How to add a validation from the select renderer using the rsuite in react

557 views Asked by At
  const [application, setApplication] = useState([])
  const [app, setApp] = useState([
    {
      id: null,
      code: null,
      name: null
    }
  ]);

useEffect(() => {
 let ignore = false;
   (async function load() {
    let response = await getAllData();
    if (!ignore) setApplication(response['data'])

 })()
 return () => ignore = true;
},[]);
     {
    
            label: (
              <div className="flex items-center">
                <label className="flex-1">Application</label>
                <div className="text-right">
                  <ButtonGroup>
                    <IconButton icon={<Icon icon="plus" />} onClick={() => appendApp()} />
                    <IconButton onClick={() => removeApp()} size="md" icon={<Icon icon="minus" />} style={{ display: app.length > 1 ? 'inline-block' : 'none' }} />
                  </ButtonGroup>
                </div>
              </div>
            ),
            name: 'applications',
            renderer: (data) => {
              const { control, register, errors } = useFormContext();
    
              return (
                <div className="flex flex-col w-full">
                  {
                    app.map((item, index) => (
                      <div key={index} className="flex flex-col pb-2 -items-center">
                        <div className="flex pb-2 w-full">
                          <SelectPicker
                            placeholder="Select Application"
                            data={application['data']}
                            labelKey="name"
                            valueKey="code"
                            style={{ width: '100%' }}
                            disabledItemValues={Array.isArray(control.getValues()['applications']) ? control.getValues()['applications'].map(x => x.id) : []}
                            onChange={(value) => control.setValue('applications', _setApp(value, index, 'code'))}
                            value={control.getValues()['applications']?.code}
                          />
                        </div>
                      </div>
                    ))
                  }
                </div>
              )
            }

 const appendApp = () => {
    let i = 0;
    for (i = 0; i < noOfApp; i++) {
      setApp(arr => [...arr, {
        id: null,
        code: null,
        name: null,
        role: null
      }]);

      return app;
    }
  }

  const removeAppRole = () => {
    setApp([...app.slice(0, -1)]);
  }

  const _setApp = (value, idx, status) => {
    app[idx][status] = value;
    setApp(app);
    return app;
  }

How do I add a validation on the select? for example when the select field is empty it should validation that it is required to select. also for example when there's a existing data which is like this:

data = [{
 id: 1,
 name: 'IOS',
 code: 'ios'
}]

and how do I display this data on the select field? cause I have a create and edit. when I try to edit it doesn't display the value.

1

There are 1 answers

2
Jamt0 On

I do not use the register, I prefer to use Controller, for these cases it is more practical, in the v7 of react-hook-form, see this example:

My select component:

import { ErrorMessage } from "@hookform/error-message";
import { IonItem, IonLabel, IonSelect, IonSelectOption } from "@ionic/react";
import { FunctionComponent } from "react";
import { Controller } from "react-hook-form";
import React from "react";

const Select: FunctionComponent<Props> = ({
  options,
  control,
  errors,
  defaultValue,
  name,
  label,
  rules
}) => {
  return (
    <>
      <IonItem className="mb-4">
        <IonLabel position="floating" color="primary">
          {label}
        </IonLabel>
        <Controller
          render={({ field: { onChange, onBlur, value } }) => (
            <IonSelect
              value={value}
              onIonChange={onChange}
              onIonBlur={onBlur}
              interface="action-sheet"
              className="mt-2"
            >
              {options ? options.map((opcion) => {
                return (
                  <IonSelectOption value={opcion.value} key={opcion.value}>
                    {opcion.label}
                  </IonSelectOption>
                );
              }):""}
            </IonSelect>
          )}
          control={control}
          name={name}
          defaultValue={defaultValue}
          rules={rules}
        />
      </IonItem>
      <ErrorMessage
        errors={errors}
        name={name}
        as={<div className="text-red-600 px-6" />}
      />
    </>
  );
};

export default Select;

Use the component in other component:

import Select from "components/Select/Select";
import { useForm } from "react-hook-form";
import Scaffold from "components/Scaffold/Scaffold";
import React from "react";

let defaultValues = {
  subjectId: "1"
};

const options = [
    {
      label: "Option1",
      value: "1",
    },
    {
      label: "Option2",
      value: "2",
    },
  ];

const ContactUs: React.FC = () => {

  const {
    control,
    handleSubmit,
    formState: { isSubmitting, isValid, errors },
  } = useForm({
    defaultValues: defaultValues,
    mode: "onChange",
  });


  const handlerSendButton = async (select) => {
    console.log(select);
  };

  const rulesSubject = {
    required: "this field is required",
  };

  return (
    <Scaffold>
      <Scaffold.Content>
        <h6 className="text-2xl font-bold text-center">
          Contact us
        </h6>
        <Select
          control={control}
          errors={errors}
          defaultValue={defaultValues.subjectId}
          options={options}
          name="subjectId"
          label={"Subject"}
          rules={rulesSubject}
        />
      </Scaffold.Content>
      <Scaffold.Footer>
        <Button
          onClick={handleSubmit(handlerSendButton)}
          disabled={!isValid || isSubmitting}
        >
          Save
        </Button>
      </Scaffold.Footer>
    </Scaffold>
  );
};

In this case i use Ionic for the UI but you can use MaterialUI, ReactSuite o other framework, its the same.

I hope it helps you, good luck.

EDIT

A repository : Ionic React Select Form Hook A codeSandBox: Ionic React Select Form Hook