1

Currently I am using semantic ui css multiple dropdown validation. How do I validate the dropdown so that user has to choose at least ONE option before submitting ?

Right now the current output is that if I submit the form WITHOUT choosing any option, the error message appears.

However, if I choose an option and the submit, the error message still appears.

enter image description here

Following is my code.

import React, { useState } from 'react'
import { Button, Checkbox, Form, Dropdown } from 'semantic-ui-react'
//validation dependencies
import { useForm, Controller } from "react-hook-form";
import { yupResolver } from '@hookform/resolvers/yup';
import * as Yup from 'yup';


function TestForm() {

    const validationSchema = Yup.object().shape({
        firstName: Yup.string()
            .required('firstName is required')
            .min(6, 'firstName must be at least 6 characters')
        ,
        options: Yup
            .object()
            .shape({
                key: Yup.number().required("key is required (from label)"),
                value: Yup.string().required("Value is required")
            })
            .nullable() // for handling null value when clearing options via clicking "x"
            .required("options is required (from outter null check)")
    });
    const formOptions = { mode: 'all', reValidateMode: 'onChange', resolver: yupResolver(validationSchema) };
    const { register, handleSubmit, reset, formState: { errors }, watch, setValue, control } = useForm(formOptions);
    const [stateOptions, setStateOptions] = useState([
        {
            key: 1,
            text: 'aaaa',
            value: 'a'
        },
        {
            key: 2,
            text: 'bbbb',
            value: 'b'
        },
        {
            key: 3,
            text: 'cccc',
            value: 'c'
        },
    ]);
    console.log(watch())//For Debugging

    const onSubmitHandler = (data) => {
        console.log({ data });
        setValue('firstName', 'dash', { shouldDirty: true, shouldValidate: true })
    }

    return (
        <div>
            <Form reply onSubmit={handleSubmit(onSubmitHandler)}>
                <Form.Field>
                    <label>First Name</label>
                    <input placeholder='First Name' name="firstName" {...register('firstName')} />
                    <div className="invalid-feedback">{errors.firstName?.message}</div>
                </Form.Field>
                <Form.Field>
                    <Controller
                        name="options"
                        control={control}
                        render={({ field }) => (
                            <Dropdown
                                {...field}
                                placeholder='State'
                                fluid
                                multiple
                                search
                                selection
                                options={stateOptions}
                            />
                        )}
                    />
                    <div className="invalid-feedback">{errors.options?.message || errors.options?.value.message}</div>
                </Form.Field>
                <Form.Field>
                    <Button type='submit'>Submit</Button>
                </Form.Field>
            </Form>
        </div>
    )
}

export default TestForm

1 Answer 1

2

Since Dropdown component in semantic-ui-react doesn't support ref attribute, so you need to controll the value of DropDown by yourself, here is an example you can try on it:

 const options = [
  {
    key: 1,
    text: 'aaaa',
    value: 'a',
  },
  {
    key: 2,
    text: 'bbbb',
    value: 'b',
  },
  {
    key: 3,
    text: 'cccc',
    value: 'c',
  },
]

function TestForm() {
  const validationSchema = Yup.object().shape({
    firstName: Yup.string()
      .required('firstName is required')
      .min(6, 'firstName must be at least 6 characters'),
    options: Yup.array()
    .of(Yup.object()
      .shape({
        key: Yup.number().required('key is required (from label)'),
        value: Yup.string().required('Value is required'),
      }))
      .test(
        "required",
        "options is required",
        (value) => Array.isArray(value) && value.length > 0
      ),
  });
  const formOptions = {
    mode: 'all',
    reValidateMode: 'onChange',
    resolver: yupResolver(validationSchema),
  };
  const {
    register,
    handleSubmit,
    formState: { errors },
    setValue,
    control,
  } = useForm(formOptions);

  const onSubmitHandler = (data) => {
    console.log(data);
  };

  return (
    <div>
      <Form reply onSubmit={handleSubmit(onSubmitHandler)}>
        <Form.Field>
          <label>First Name</label>
          <input
            placeholder="First Name"
            name="firstName"
            {...register('firstName')}
          />
          <div className="invalid-feedback">{errors.firstName?.message}</div>
        </Form.Field>
        <Form.Field>
          <Controller
            name="options"
            control={control}
            render={({ field }) => {
              let { value, ...other } = field;
              return (
                  <Dropdown
                    {...other}
                    placeholder="State"
                    fluid
                    multiple
                    search
                    selection
                    options={options}
                    value={Array.isArray(value) ? value.map(v => v.value) : []}
                    onChange={(e,{value})=> {
                      const values = value.map(v => options.find(item => item.value == v));
                      setValue('options', values)
                    }}
                  />
              );
            }}
          />
          <div className="invalid-feedback">
            {errors.options?.message || errors.options?.value.message}
          </div>
        </Form.Field>
        <Form.Field>
          <Button type="submit">Submit</Button>
        </Form.Field>
      </Form>
    </div>
  );
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much @Saeed , it solved the problem. Really appreciate it !
Glad I could help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.