How reset a Select value based on switch off value

124 Views Asked by At

hope that are you doing well! I have a little question breaking my head and I don't know how solve it yet. I'm working with React, TypeScript, Ant Design and Refine Framework and have a page component edit.tsx where I have to edit a record, so, deppending of value comming from DB of field catHasParent that could be true or false, The switch catHasParent wil be Yes or Not, and a Form.Item > category_id Select have to be enabled or disabled, and when catHasParent will be equal to false, category_id must be resetted to null and this value must be saved on DB. If I select catHasParent to True and select a Parent Category and later without saving turn off catHasParent, then catecory_id remains with previous value (a wrong category_id selected by mistake), and there is my problem, I can't find how reset it. Here is my code, Cheers!

import React, { useState, useEffect } from "react";
import { IResourceComponentsProps } from "@refinedev/core";
import { Edit, useForm } from "@refinedev/antd";
import { Form, Row, Col, Input, Select, Switch } from "antd";

import { usePopulateSelect } from "../../components/populateSelect";
// Some declarations here
export const CategoryEdit: React.FC<IResourceComponentsProps> = () => {
...
   const { form, queryResult, formProps, saveButtonProps } = useForm();
   ...
   const [disabled, setDisabled] = useState(catHasParent);
   const [catHasParent, setCatHasParent] = useState(false);
   ...
   const optionsCategories = usePopulateSelect({ resource: "categories", data: categoryData });
   ...
   let catHasParentValue = queryResult?.data?.data.catHasParent;
   ...
   const toggle = () => {
    setDisabled(!disabled);
    setCatHasParent(!catHasParent);
 
    // if (disabled) {
    //    Some code could be here but doesn't work
    // }
  };
  return (
    <Edit saveButtonProps={saveButtonProps} title="Edit Category">
      <Form {...formProps} layout="vertical">

        // Row and Col with Category Name and other stuffs

        <Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
          <Col className="gutter-row" flex={2}>
            <Form.Item 
              label="Has a Parent Category?" 
              name={["catHasParent"]}
              initialValue={catHasParentValue} // With this here I found that represent DB value 
              >
              <Switch 
                defaultChecked={catHasParentValue} // With this here I found that represent DB value 
                checkedChildren="Yes" 
                unCheckedChildren="Not" 
                onClick={toggle} 
              />
            </Form.Item>
          </Col>
          <Col className="gutter-row" flex={20}>
            <Form.Item
              label="Category"
              name={["category_id"]}
            >
              <Select 
                value={category_id}
                options={optionsCategories} 
                disabled={catHasParent} 
              />
            </Form.Item>
          </Col>
        </Row>

        // Others Rows and Cols with Information

    </Form>
  </Edit>
  );
};

I tested retrieve record from DB and work fine, the component retrieve all the data. The Select Category retrieve all category records well. The Switch enable and disable the Select Category_ID well. I Research about onFinish useForm state and nothing.

1

There are 1 best solutions below

0
Alican Erdurmaz On

I've prepared an example demonstrating how to dynamically disable, change, and reset a form value. I hope I've understood your question correctly.

https://codesandbox.io/p/sandbox/affectionate-sammet-plf6rq?embed=1&file=%2Fsrc%2Fpages%2Fposts%2Fedit.tsx%3A16%2C5

import React, { useEffect } from "react";
import { IResourceComponentsProps } from "@refinedev/core";
import { Edit, useForm, useSelect } from "@refinedev/antd";

import { Form, Input, Select, Switch } from "antd";

import { IPost, ICategory } from "../../interfaces";

type IPostExtended = IPost & { hasParent: boolean };

export const PostEdit: React.FC<IResourceComponentsProps> = () => {
    const { formProps, saveButtonProps, queryResult, formLoading, form } =
        useForm<IPostExtended>({
            warnWhenUnsavedChanges: true,
        });
    const postData = queryResult?.data?.data;
    const hasParentFormValue = Form.useWatch("hasParent", form);

    const { selectProps: categorySelectProps } = useSelect<ICategory>({
        resource: "categories",
        defaultValue: postData?.category.id,
        pagination: { mode: "off" },
    });

    // for initial value
    useEffect(() => {
        if (postData?.hasParent) {
            formProps.form?.setFieldValue("category", postData?.category);
        } else {
            formProps.form?.setFieldValue(["category", "id"], null);
        }
    }, [postData]);

    // for form value change
    useEffect(() => {
        if (hasParentFormValue) {
            formProps.form?.setFieldValue("category", postData?.category);
        } else {
            formProps.form?.setFieldValue(["category", "id"], null);
        }
    }, [hasParentFormValue]);

    return (
        <Edit saveButtonProps={saveButtonProps} isLoading={formLoading}>
            <Form {...formProps} layout="vertical">
                <Form.Item label="Title" name="title">
                    <Input />
                </Form.Item>
                <Form.Item label="Category" name={["category", "id"]}>
                    <Select
                        {...categorySelectProps}
                        disabled={!hasParentFormValue}
                    />
                </Form.Item>
                <Form.Item
                    valuePropName="checked"
                    label="Has Parent"
                    name="hasParent"
                >
                    <Switch checkedChildren="Yes" unCheckedChildren="No" />
                </Form.Item>
            </Form>
        </Edit>
    );
};