React-Select if value exists show value if not show placeholder text - javascript

I'm using this component here: https://react-select.com/home
What I'm trying to accomplish is on page load if my array contains a value in my Assigned element then I want to display that by default in my react-select box if not then I want my placeholder Assign to to show.
Here is how my select looks:
<Select
value={this.state.Product[0].Assigned ? this.state.Product[0].Assigned : selectedAssigned}
onChange={this.handleChangeAssigned}
options={this.state.AssignedList}
placeholder={<div>Assign to:</div>}
/>
In my Product[0].Assigned there is currently a value, however the dropdown still has the placeholder Assign To. I tried changing value to value={this.state.Product[0].Assigned} but still no luck.
Here is my change handle:
handleChangeAssigned = selectedAssigned => {
this.setState(
{ selectedAssigned },
() => console.log(`Option selected:`, this.state.selectedAssigned)
);
};

It seems like you are storing the same data in multiple places. You are checking if you have an assignment by looking at this.state.Product[0].Assigned. But when you select an assignment you are not updating that property. Instead you are updating a completely separate property this.state.selectedAssigned. this.state.Product[0].Assigned never changes so if you see a placeholder at first then you will always see a placeholder.
The value that you set on the Select needs to be the same as the value that you update.
import React from "react";
import Select from "react-select";
interface Option {
label: string;
value: string;
}
interface State {
Product: any[];
AssignedList: Option[];
selectedAssigned: Option | null;
}
export default class MyComponent extends React.Component<{}, State> {
state: State = {
Product: [],
AssignedList: [
{ label: "a", value: "a" },
{ label: "b", value: "b" },
{ label: "c", value: "c" }
],
selectedAssigned: null
};
handleChangeAssigned = (selectedAssigned: Option | null) => {
this.setState({ selectedAssigned }, () =>
console.log(`Option selected:`, this.state.selectedAssigned)
);
};
render() {
return (
<Select
value={this.state.selectedAssigned}
onChange={this.handleChangeAssigned}
options={this.state.AssignedList}
placeholder={<div>Assign to:</div>}
/>
);
}
}
Code Sandbox Link

Related

reset value when using react-select

I am using react-select for my select dropdown. The issue I am having is that there is no empty option to reset the dropdown value if the user changes their mind.
Currently I am taking the options and manually adding an empty string, but I feel there must be something already in the library to handle this? I cannot find anything in the docs.
My code looks like the below, and there is a code sandbox here.
import React from "react";
import Select from "react-select";
const App = () => {
const options = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
];
return <Dropdown options={options} />;
}
const Dropdown = ({ options }) => {
const optionsWithEmptyOption = [{ value: "", label: "" }, ...options];
return <Select options={optionsWithEmptyOption} />;
};
Plase check this out
https://codesandbox.io/s/zow1c?module=/example.js
import React, { Component } from 'react';
import CreatableSelect from 'react-select/creatable';
import { colourOptions } from './docs/data';
export default class CreatableSingle extends Component<*, State> {
handleChange = (newValue: any, actionMeta: any) => {
console.group('Value Changed');
console.log(newValue);
console.log(`action: ${actionMeta.action}`);
console.groupEnd();
};
handleInputChange = (inputValue: any, actionMeta: any) => {
console.group('Input Changed');
console.log(inputValue);
console.log(`action: ${actionMeta.action}`);
console.groupEnd();
};
render() {
return (
<CreatableSelect
isClearable
onChange={this.handleChange}
onInputChange={this.handleInputChange}
options={colourOptions}
/>
);
}
}
Empty Unicode
I add line to options, and write between the apostrophes empty unicode like this: ⠀⠀⠀⠀⠀⠀⠀⠀ .. you can mark it but dont see it.
const options = [
{ value: "", label: "⠀" },
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
];
And I change this:
return <Select options={options} />;
what about const optionsWithEmptyOption = [{ value: null, label: "Select..." }, ...options];
I'm not really good with explanations, but #NicoHaase is right, so here it goes...
as far as I know, you must give a value to value null (if nothing) or string ... same for the label, #1 because of the user UX and second so react-select knows what to display. But if you really need to leave it in black, and you can try to modify in the styles, in order to have the same height as the other options.

Changes to properties in mounted not triggering computed in VueJS

I have a VueJS component which contains a button whose class and text are computed properties and changes every time the button is clicked. They are changing fine as long as I click on the button once it is loaded. I wanted to store the state in localStorage and if I reload the page set the text and class based on the value stored. The value of ordered is changing but the button text and class are not reflecting that in UI. Does anyone have any suggestion as to what I may be doing wrong? Following is the source
<template>
<div class="main-view">
<button type="button" :class="order_button_style" #click="on_order_button_click()">
{{ order_button_text }}
</button>
</div>
</template>
<script>
export default {
name: "FoodComponent",
props: {
item: Object
},
methods: {
on_order_button_click() {
this.item.ordered = !this.item.ordered;
localStorage.setItem(this.item.id, this.item.ordered);
}
},
mounted() {
var storedState = localStorage.getItem(this.item.id);
if (storedState) {
this.item.ordered = storedState;
}
},
computed: {
order_button_text() {
return this.item.ordered === true ? "Ordered" : "Order";
},
order_button_style() {
return this.item.ordered === true
? "button ordered-button"
: "button unordered-button";
}
}
};
</script>
What you will get from the local storage is a string. In mounted, ordered property will be a string instead of a boolean so you order_button_text computed property condition will never be true. To fix this you can just convert storedState property to a boolean :
mounted() {
const storedState = localStorage.getItem(this.item.id) === 'true';
if (storedState) {
this.item.ordered = storedState;
}
},

Setting a default value with react-select not working

I have a simple React component which gets an initial state:
this.state = {
currentObject: {
isYounger: false
}
}
I then render a react-select with the default value of this.state.currentObject.isYounger:
<Select
name={"age"}
value={this.state.currentObject.isYounger}
onChange={newValue => this.addIsYoungerValue(newValue)}
options={isYoungerOptions}
/>
For some reason, the value is not set. Why is this?
Codesandbox
Version:
"react-select": "^2.4.2",
Here the issue is not with state selection, the actual issue is that the label is not getting displayed.
So, as per your addIsYoungerValue function you are setting the value of this.state.currentObject.isYounger to whole object. i.e. { value: true, label: "Younger" }. So, the issue can be solved by changing the value of initial state by below.
this.state = {
array: [],
currentObject: {
isYounger: { value: true, label: "Younger" }
}
};
And hurrey, the default value label will be shown..
Your defaultValue or value must be objects. In your case like this:
defaultValue={isYoungerOptions[0]}
or
this.state = {
array: [],
currentObject: {
isYounger: { value: "true", label: "Younger" }
}
};
Here an live example.
There is an alternate way to use value as your defaultValue. In my case I have used "id" and "industry" instead of "label" and "value"
this.state = {
interested_industries: [{id:"ANY", industry:"ANY"}]
}
And in Select component:-
<Select
name="interested_industries"
options={industries}
value={interested_industries}
getOptionLabel={ x => x.id}
getOptionValue={ x => x.industry}
onChange={this.handleSelect}
isMulti
/>

How to build React checkbox tree

I'm trying to work with a checkbox tree component like this: https://www.npmjs.com/package/react-checkbox-tree, except I'm storing the items that I have selected in Redux. Moreover, the only items that I'm actually storing are the leaf nodes in the tree. So for example, I'd have the full options data which would be used to render the tree:
const fam = {
cuz2: {
name: 'cuz2',
children: {
cuzKid2: {
name: 'cuzKid2',
children: {
}
}
}
},
grandpa: {
name: 'grandpa',
children: {
dad: {
name: 'dad',
children: {
me: {
name: 'me',
children: {}
},
sis: {
name: 'sis',
children: {}
}
}
},
aunt: {
name: 'aunt',
children: {
cuz: {
name: 'cuz',
children: {
name: 'cuzkid',
children: {}
}
}
}
}
}
}
and a separate object that stores the items selected. The following would be the only items that would appear if every checkbox was checked:
const selected = {
cuz2: true,
me: true,
sis: true,
cuz: true
}
I seem to be struggling with this method for having the UI determine which boxes to have fully, partially, or un-checked based on the selected object. I was wondering if anyone can recommend another strategy of accomplishing this.
So I have used react-checkbox-tree but I have customised a bit the icons in order to use another icons library.
Check my example on sandbox:
The library provides a basic example of how to render a tree with selected and/or expanded nodes.
All you need to do is:
set up the nodes with a unique 'value'
Choose which items should be selected (it may comes from Redux)
pass nodes & checked list to the CheckBox constructor
also be sure that when user select/unselect, you update the UI properly using the state
Your code should look similar to this:
import React from 'react';
import CheckboxTree from 'react-checkbox-tree';
const nodes = [{
value: '/cuz2',
label: 'cuz2',
children: [],
},
// other nodes
];
class BasicExample extends React.Component {
state = {
checked: [
'/cuz2'
],
expanded: [
'/cuz2',
],
};
constructor(props) {
super(props);
this.onCheck = this.onCheck.bind(this);
this.onExpand = this.onExpand.bind(this);
}
onCheck(checked) {
this.setState({
checked
});
}
onExpand(expanded) {
this.setState({
expanded
});
}
render() {
const {
checked,
expanded
} = this.state;
return (<
CheckboxTree checked={
checked
}
expanded={
expanded
}
nodes={
nodes
}
onCheck={
this.onCheck
}
onExpand={
this.onExpand
}
/>
);
}
}
export default BasicExample;

send the value as string when selecting the option

I am using react-select for autocomplete and option related field. When i select the option it passes whole that option object as {value: 'abc', label: 'ABC'} but i wanted only to pass the value as a string not the object. Thus, i used getOptionValue but it is not working as expected.
This is what I have done
<Field
name='status'
component={SearchableText}
placeholder="Search..."
options={status}
styles={styles}
getOptionLabel={option => option.label}
getOptionValue={option => option.value}
/>
I have used both getOptionLabel and getOptionValue but is still passing the selected option in object form instead of just the value as string.
Expected one
status: 'active'
Current behavior
status: { value: 'active', label: 'Active'}
I couldn't find getOptionValue in the docs for react-select, but you could always create an adapter around react-select. i.e. create your own Select component that uses react-select's Select component internally. After doing this it becomes possible to create your own getOptionValue. You can use this to make sure the value is a string.
import React from "react";
import Select from "react-select";
class MySelect extends React.Component {
getSelectValue() {
return this.props.options.find(
option => this.props.getOptionValue(option) === this.props.input.value
);
}
render() {
console.log("value", this.props.input.value);
return (
<Select
value={this.getSelectValue()}
onChange={option => {
this.props.input.onChange(this.props.getOptionValue(option));
}}
options={this.props.options}
/>
);
}
}
MySelect.defaultProps = {
getOptionValue: v => v
};
const MyForm = reduxForm({ form: "MyForm" })(
class extends React.PureComponent {
render() {
return (
<Field
name="myCoolSelect"
component={MySelect}
options={[
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
]}
getOptionValue={option => option.value}
/>
);
}
}
);
The above is a basic example of how to get this working. You may want to pass other input or meta props to take advantage of other redux-form features. e.g. onBlur, onFocus, etc. You can see it in action here: https://codesandbox.io/s/6wykjnv32n

Categories

Resources