Joseph
Joseph

Reputation: 7755

Dynamic Value Dropdown in React

I have variabled called types that I want to display in the select dropdown. I have a difficulty displaying it. Its values are dynamic based on the types. Pls check my codesandbox here

CLICK HERE

Code

 {types.map((value, index) => (
        <Dropdown value={value} index={index} />
 ))}


const Dropdown = ({ value, index }) => {
  const select = (e) => {
    console.log(e);
  };
  return (
    <Select onChange={(e) => select(e)}>
      {/* {value.map((value, index) => (
        {value.name}
        <option value="1">{value.option[index+1]}</option>
      ))} */}
    </Select>
  );
};

Upvotes: 1

Views: 348

Answers (3)

Nedko Dimitrov
Nedko Dimitrov

Reputation: 5081

In the <Dropdown /> component the value is not an array but an object. If you want to loop over it, do the following:

    const Dropdown = ({ value, index }) => {
  const select = (e, value) => {
    console.log("event", e);
    console.log("object", value);
  };
  return (
    <Select onChange={(e) => select(e, value)}>
      {Object.keys(value)
        .filter((key) => value[key] && key.startsWith("option"))
        .map((key, index) => (
          <option value={key}>{value[key]}</option>
        ))}
    </Select>
  );
};

https://codesandbox.io/s/dynamic-select-dropdown-styled-components-forked-78qm6?file=/Dropdown.js

Upvotes: 1

codebarz
codebarz

Reputation: 327

Using your data structure, your Dropdown component works if you do it this way but would only pick the first option.

const Dropdown = ({ value, index }) => {
  return (
    <Select>
        <option value="1">{value[`option${index+1}`]}</option>
    </Select>
  );
};

But this is what I advise, If this is within your control, I would advise you restructure your types data structure a little bit to something like below

const types = [
    {
      id: "1",
      name: "color",
      options: [
        {value: "red", label: "red"}, 
        {value: "blue", label: "blue"}
      ],
      price: 12
    },
    {
      id: "2",
      name: "weight",
      options: [
        {value: "", label: "Placeholder"},
        {value: "20", label: "20 Kilos"}, 
        {value: "30", label: "30 Kilos"}, 
        {value: "40", label: "40 Kilos"}, 
        {value: "50", label: "50 Kilos"}
      ],
      price: 13
    }
];

Then your dropdown component can also be refactored to this

const Dropdown = ({ options, index }) => {
  return (
    <Select>
      {options.map((option) => <option value={option.value}>{option.label}</option>)}
    </Select>
  );
};

This would enable you to easily use your Dropdown component with the type array as follows

  return (
    <MainContainer>
      {types.map((value, index) => (
        <Dropdown options={value.options} index={index} />
      ))}
    </MainContainer>
  );

Upvotes: 1

AliReza Beigy
AliReza Beigy

Reputation: 629

I suggest to fix the type structure, anyway you can fix it in js side by following code

let options = Object.fromEntries(Object.entries(value).filter(entry => Object.keys(value).filter(k => k.startsWith("option")).includes(entry[0])));

sample options value:

{option1: "20 Kilo", option2: "30 Kilo", option3: "40 Kilo", option4: "50 Kilo"}

Upvotes: 0

Related Questions