Search code examples
reactjssemantic-uiformik

Semantic UI dropdown not setting value after selecting option


I am using React semantic ui. I am rendering a dropdown in Fieldset. I have written code such that, once a option is selected, the options is updated such that the selected option is removed from the list. But when I select an option from the dropdown, the selected value is not displayed, rather it shows empty.

Here is my code: This is my dropdown code:

<Dropdown
name={`rows.${index}.mainField`}
className={"dropdown fieldDropdown"}
widths={2}
placeholder="Field"
fluid
selection  
options={mainFieldOptions}
value={row.mainField}
onChange={(e, { value }) => {
     setFieldValue(`rows.${index}.mainField`, value)
     updateDropDownOptions(value)                               
     }
  }                                                            
/>

My options:

let mainField = [
    { key: "org", text: "org", value: "org" },
    { key: "role", text: "role", value: "role" },
    { key: "emailId", text: "emailId", value: "emailId" },
]

Also, I have:

const [mainFieldOptions, setMainFieldOptions] = useState(mainField)

And,

  const updateDropDownOptions = (value:any) => {
        let updatedOptions: { key: string; text: string; value: string }[] = []
        mainFieldOptions.forEach(option => {
            if(option.key != value){
                updatedOptions.push({ key:option.key , text:option.key, value:option.key  })
            }
        })
        setMainFieldOptions(updatedOptions)
        console.log("mainfield", mainField)
    }

In onChange, if I dont call updateDropDownOptions() method, the dropdown value is set. But when I call the method, its giving blank value. Please help.


Solution

  • There are few changes required in your code,

    1. You are pushing the entire initialValues when you are adding a row which is an [{}] but you need to push only {} so change your code to initialValues[0] in your push method.
    2. Its not needed to maintain a additional state for the options. You can filter the options based on the selected option in other rows which is available in the values.rows .

    Util for filtering the options

    const getMainFieldOptions = (rows, index) => {
      const selectedOptions = rows.filter((row, rowIndex) => rowIndex !== index);
    
      const filteredOptions = mainField.filter(mainFieldOption => !selectedOptions.find(selectedOption => mainFieldOption.value === selectedOption.mainField));
      return filteredOptions;
    }
    

    Call this util when rendering each row

    values.rows.length > 0 &&
                    values.rows.map((row, index) => {
                      const  mainFieldOptions = getMainFieldOptions(values.rows, index);
    

    Working Sandbox