I got an object called data
and already show values as option
in select
now I want to show selected
option via selected
object, but no success:
let data = [
{id: 1, name: 'xxx'},
{id: 2, name: 'yyy'},
{id: 3, name: 'zzz'},
{id: 4, name: 'sss'},
{id: 5, name: 'vvv'},
];
let selected = [
{id: 1, name: 'xxx'},
{id: 3, name: 'zzz'},
{id: 5, name: 'vvv'},
]
<select multiple={true}>
data.map(function(Creator, index){
return (
<option key={Index}>{Creator.name}</option>
)
});
</select>
I did:
{data.map(function(Cr, In){
{selected.map(function (Creator, Index) {
return (
<option selected={Creator.name === Cr.name ? true : false} key={In}>{Cr.name}</option>
)
})}
})}
But return no option
and I guess this is not best practice, how can I fix this and what is best practice?
CodePudding user response:
Use a function to iterate over the options, and use find
to check whether the the id
and name
of the option matches the same properties of an object in the selected array, and use that variable to determine whether the option should be selected or not.
In this working example I've passed the options/selected data into the Example component, and set state with the options data for convenience.
const { useState } = React;
function Example({ data, selected }) {
const [ options, setOptions ] = useState(data);
function getSelected() {
// Iterate over the options, and get the id, and name
return options.map(option => {
const { id, name } = option;
// `found` is a boolean depending on whether the option
// in the current iteration is in the selected array
const found = selected.find(obj => {
return obj.id === id && obj.name === name;
});
// And then we can return an option where selected
// is the result of that boolean, either true or false
return <option value={option} selected={found}>{name}</option>;
});
}
return (
<div>
<select multiple>
{getSelected()}
</select>
</div>
);
};
const data = [
{id: 1, name: 'xxx'},
{id: 2, name: 'yyy'},
{id: 3, name: 'zzz'},
{id: 4, name: 'sss'},
{id: 5, name: 'vvv'},
];
const selected = [
{id: 1, name: 'xxx'},
{id: 3, name: 'zzz'},
{id: 5, name: 'vvv'},
];
ReactDOM.render(
<Example data={data} selected={selected} />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Do not iterate selected object, just read them by Index like this selected[index]
data.map(function(Creator, index){
return (
<option selected={Creator.id === selected[index].id ? true : false}>{Creator.name}</option>
)
});
CodePudding user response:
You can do something like this which will result in the solution but it will result in extra steps. To avoid running over the extra steps of checking you can make use of a dictionary.
const addList = data.map(function (Creator, index) {
let check = false;
for (let i = 0; i < selected.length; i ) {
if (selected[i].id == Creator.id) {
check = true;
break;
}
}
return (
<option key={Creator.id} selected={check}>
{Creator.name}
</option>
);
});
Below is the one using dictionary
let newobj = {};
for(let i=0;i<selected.length;i ){
newobj[selected[i].id]="selected";
}
const addList = data.map(function (Creator, index) {
return (
<option key={Creator.id} selected={newobj[Creator.id]==="selected"}>
{Creator.name}
</option>
);
});
CodePudding user response:
In the data object, you can have a isSelected
key of type boolean
which will determine if the option is selected or not
let data = [
{id: 1, name: 'xxx',isSelected: false},
{id: 2, name: 'yyy',isSelected: false},
{id: 3, name: 'zzz',isSelected: false},
{id: 4, name: 'sss',isSelected: false},
{id: 5, name: 'vvv',isSelected: false},
];
<select multiple={true}>
data.map(function(Creator){
return (
<option selected={creator.isSelected} key={Creator.id}>{Creator.name}</option>
)
});
</select>