Home > Software engineering >  Reactjs show selected option by object
Reactjs show selected option by object

Time:11-01

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>
  • Related