Setting multiple selected values using React-select - javascript

I am having a dropdown where a user can add multiple dropdowns and select a value in it. While making a GET request, i wanted to keep the selected value in the dropdown, but not sure how to do it. I am able to make the selected value in a single dropdown, but finding it difficult to keep the selected value in multiple dropdowns.
I will be getting the value in an array like this
values = ["English","Ukraine","Japnese","Korean"];
Then in Select Dropdown for setting the single value i have written it like this:
options = [
{value: "english", label: "English"},
{value: "ukraine", label: "Ukraine"},
{value: "japnese", label: "Japnese"},
{value: "korean", label: "Korean"},
{value: "french", label: "French"}
];
<Select
className="profile-module-select-container"
classNamePrefix="profile-module-select"
options={options}
onChange={selected => {
this.handleDropdownSelect(selected, formKey);
}}
onMenuOpen={(e, i, o) => {
this.setState({
selectMenuOpen: true
});
}}
onMenuClose={() => {
this.setState({
selectMenuOpen: false
});
}}
name={name}
value={options.filter((items) => { return items.value === values })}
/>

values is an array and you would have to loop it over as well and filter it against Options . Considering the current implementation, it would be a nested loop, yes.

Related

how to select All checkbox based group in reactjs

I did initial state for select single checkbox .Here is my intial state
this.state = {
fruites: [
{ id: 1 , value: "banana", isChecked: false },
{ id: 2, value: "apple", isChecked: false },
{ id: 3,value: "mango", isChecked: false },
{ id: 4, value: "grap", isChecked: false }
]
};
}
Method: I just this for selected all checkbox
handleAllChecked = id => event => {
let fruites = this.state.fruites;
fruites.forEach(fruite => {
data.filter(item =>
fruite.isChecked = event.target.checked;
});
});
this.setState({ fruites: fruites });
};
I just this method for individual checkbox .
handleCheckChieldElement = event => {
let fruites = this.state.fruites;
fruites.forEach(fruite => {
if (fruite.value === event.target.value)
fruite.isChecked = event.target.checked;
});
this.setState({ fruites: fruites });
};
Render:Here is my UI, I want to select All checkbox based on group . For example , I have got two group of value - such as Group , Topgroup. The problem is that , When I click on the group , it will select All checkbox including Topgroup and also I click banana , it will select all banana , I don't want to get all banana when click on one item. I don't to want to get topgroup checkbox when I select on the group.
{[{ id: 1, name: "group" }, { id: 2, name: "topGropup" }].map(item => (
<div>
<input
type="checkbox"
onChange={this.handleAllChecked(item.id)}
value="checkedall"
/>{" "}
{item.name}
<ul>
{this.state.fruites.map((fruite, index) => {
return (
<CheckBox
key={index}
handleCheckChieldElement={this.handleCheckChieldElement}
{...fruite}
/>
);
})}
</ul>
</div>
))}
</div>
How can I resolve this problem . Here is my codesanbox : https://codesandbox.io/s/react-multi-select-checkbox-or6ko
Here, I edited your codesandbox: https://codesandbox.io/s/react-multi-select-checkbox-bbuky
Basically you have 8 checkboxes, even though its 4 items displayed, duplicated for each group.
I added the 4 missing items in your state, but you'd actually want some kind of factory function that lets you create your state given the groups you have.
I had to edit some of your values since you were relying on stuff that now is not unique anymore, like value and use the group's id for example to create a unique identifier groupId-itemId.
Memory pointer to the same list
The groups in the app have the same pointer to memory list of fruits.
because of that the updates will affect on both groups.
See how I fixed it:
https://codesandbox.io/s/react-multi-select-checkbox-r29d1
I found some things in the app that can be improve so I improve them for example:
label to input checkbox to be able to click also on the text
I am here if you have any problem, I suggest you to learn Hooks.

react-select 2 setting value/label

I am using react-select 2 and trying to set value on form that needs to perform update of some data fetched from server.
I have tried solution:
handleSelectChange(selectedOption){
this.setState({ selectedOption });
}
const options = [
{ value: 'Value 1', label: 'Value 1' },
{ value: 'Value 2', label: 'Value 2' },
]
<Select
options={options}
onChange={(selectedOption)=>this.handleSelectChange(selectedOption)}
autoFocus={true}
value={options.find(option => option.value === data.valueTyppe)}
/>
By using this it is not possible to change (visualy) label in select input - value changes on select but label stays as one defined by data.ValueType.
I think your problem comes from not allowing full control of the Select input.The value of the Select input should be the component state value property, same as the onChange calback is.
return(
<Select
options={options}
onChange={this.handleSelectChange}
autoFocus={true}
value={this.state.selectedOption}
/>
try this working examle
I have used this solution and it works for me.
First Value/Label pair is set as on defined in options that have value === data.FacilityType (saved string in database).
Then it enables change of option where value/label pair is also updated in Select.
<Select
options={options}
onChange={(selectedOption)=>this.handleSelectChange(selectedOption)}
autoFocus={true}
defaultValue={options.find(option => option.value === data.facilityType)}
/>

Update multiple semantic ui react dropdown keys to state

I'm using Semantic UI React to render some selection options in a dropdown .
I have a child component that is mapping over an array of object and returning some keys. So I supplied the following to the options prop for the semantic ui dropdown
<Dropdown
id="slotId"
value={slotId}
initialized={initialized}
onChange={onSlotIdChange}
selection
fluid
placeholder="Please select a slot id"
clearable
options={slots.map(slotId => {
return {
text: slotId.slotId,
value: slotId.slotId,
key: slotId.slotId,
description: `Initialized: ${slotId.initialized}`,
initialized: slotId.initialized
};
})}
/>
I'm lifting up state to the parent where I have the changeHandler defined
onSlotIdChange = async (e, { value, initialized }) => {
this.setState(
{ slotId: value, initialized: initialized, isLoading: false },
() => {
console.log(
"chosen slotId updated to state, callback -->",
this.state.slotId
);
console.log("initialized", this.state.initialized);
}
);
if (!value) {
this.handleClear();
return;
}
};
I have a codesanbox here with the issue.
Basically when I make the selection of the slotId it updates the slotId value to state, but I also want to update the initialized value to state as well. So For example, in the codesanbox, If you choose slotId: 1 from the dropdown I also want a state variable initialized to update with the value of Y.
I'm struggling with getting the initialized key from the child to update with the selected Id in the parent. It's only being set to an empty "" instead of the initialized value of Y or N.
I think the way semantic handles event changes only the value key is recognized
The reason was because on your Dropdown component's options, you value only includes the slotId:
options={slots.map(slot => {
return {
key: slot.slotId,
text: slot.slotId,
value: slot.slotId, // <--- this value here
description: `Initialized: ${slot.initialized}`,
initialized: slot.initialized
};
})}
To receive more information, you can either update the value returned:
<Dropdown
id="slotId"
value={slotId}
initialized={initialized}
onChange={onSlotIdChange}
selection
fluid
placeholder="Please select a slot id"
clearable
options={slots.map(slot => {
return {
key: slot.slotId,
text: slot.slotId,
value: { slotId: slot.slotId, initialized: slot.initialized },
description: `Initialized: ${slot.initialized}`,
initialized: slot.initialized
};
})}
/>
or pass in the third argument on onChange callback:
<Dropdown
id="slotId"
value={slotId}
initialized={initialized}
onChange={(e, d) => onSlotIdChange(e, d, slots.find(s => s.slotId === d.value).initialized)}
selection
fluid
placeholder="Please select a slot id"
clearable
options={slots.map(slot => {
return {
key: slot.slotId,
text: slot.slotId,
value: slot.slotId,
description: `Initialized: ${slot.initialized}`,
initialized: slot.initialized
};
})}
/>
or update the data returned to include with the found initialized value similar to the second approach above. Whichever that suits you best!

Is there any way I can use isMulti without it deleting choices I've already picked? In otherwords, having duplicate/repeated selected options?

Basically, I want to use the react-select library and use the isMulti prop, but the problem with that after selecting an option, the value would be deleted. As you can see below with the provided images, as soon as I click "US: 1" that option would go away. But for the app I'm trying to build, it's certainly possible for a customer to want 2 of the same sizes. Therefore they would pick 2 "US: 1" and it automatically sets the quantity to 2. The problem is that as soon as they pick "US: 1" that option goes away.
This is all I currently have now.
const options = [
{value: 1, label: "US: 1"},
{value: 1.25, label: "US: 1.25"},
{value: 1.5, label: "US: 1.5"},
{value: 1.75, label: "US: 1.75"},
{value: 2, label: "US: 2"},
{value: 2.25, label: "US: 2.25"},
]
class Details extends Component {
state={
selectedOption: []
}
handleChange = (selectedOption) => {
this.setState({ selectedOption: selectedOption });
}
render() {
<Select isMulti={true} isSearchable={true} onClick={value.changeSize(id, selectedOption)} value={selectedOption} onChange={this.handleChange} options={options}></Select>
}
}
Here's an example of what I'm talking about. "US: 1" goes away when it's clicked when I want that option to stay. I'm thinking it alters my "options" array and displaying the new one that doesn't have the clicked option. If I can somehow keep feeding it these original values after every single on onChange that would be awesome. I'm not sure how to dig into the library on how to do it or if it's even possible.
https://www.npmjs.com/package/react-select
Here how I would do it:
class Details extends Component {
state = {
selectedOption: []
};
handleChange = selectedOption => {
const newSelectedOption = selectedOption.map(opt => ({
label: opt.label,
innerValue: opt.value,
// I set a random value because it is needed to be able to delete the value without deleting all of them
value: Math.random()
}));
this.setState({ selectedOption: newSelectedOption });
};
render() {
return (
<Select
isMulti={true}
isSearchable={true}
value={this.state.selectedOption}
onChange={this.handleChange}
options={options}
/>
);
}
}
The idea is not to use value as it's original goal. When a label props is passed to value inside Select it still displays it correctly. So you will base yourself on innerValue and trick react-select.
Here a live example
I guess all you need is to add hideSelectedOptions={false} to <Select />.
Like:
<Select
isMulti={true}
hideSelectedOptions={false}
options={options}
...
/>

Changing state for multiple elements in page

In my react-app i have a list that is rendered dynamically from an array, each item has a checkbox and an input, the input by default is disabled, when i click on the checkbox this input should be enabled if it meets a specific condition, i have managed to do some of the work, but I'm facing some issues like when i click on one of the checkboxes all inputs get enabled, and this input has a value i want to be able to edit it but i can't here is the code:
Initial state
cards: [],
disabledInput: false
Mapping the list:
return this.state.cards.map(card => (
<Checkbox key={card.id} onClick={this.setState({ disabledInput: true })} />
<Input value={this.state.card.name} disabled={this.state.disabledInput} onChange={e => this.setState({ text: e.target.value })} />
));
You need to keep the initial disable states of each checkbox true as an array and map that individually into each checkbox.
cards = [{
name: 'card 1',
disabledInput: true
}, {
name: 'card 2',
disabledInput: true
}]
changeDisableState = (i) => {
let cards = this.state.cards;
cards[i].disabledInput = !cards[i].disabledInput;
this.setState({cards});
}
return this.state.cards.map((card, i) => (
<Checkbox key={card.id} onClick={() => this.changeDisableState(i)} />
<Input value={card.name} disabled={card.disabledInput}/>
));
Edited: Instead of a separate array you can keep a disable field inside the card state itself.
Each checkbox should have a boolean to manage its own state (checked or not). I created a Codesandbox that should solve your problem
You need to maintain a disabledInput flag for each card, at the minute you only have one across all cards.
Your card state should look something like -
cards = [{
name: 'card 1',
disabledInput: false
}, {
name: 'card 2',
disabledInput: true
}]

Categories

Resources