Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue: disabled property in useForm applied to Form Provider does not apply to all radio inputs #11842

Closed
1 task done
singhshemona opened this issue May 3, 2024 · 1 comment · Fixed by #11873
Closed
1 task done
Labels
bug Something isn't working

Comments

@singhshemona
Copy link

singhshemona commented May 3, 2024

Version Number

7.51.3

Codesandbox/Expo snack

Link to Codesandbox

Steps to reproduce

  1. Go to Codesandbox link
  2. Uncomment line 8 in App.tsx
  3. Notice how only the first radio input gets disabled

Expected behaviour

Both radio inputs should be disabled.

From my understanding, this is happening because both radio inputs are registered with the same name so it only applies the disabled validation to the first one occurring with that name. However, grouped radio inputs are supposed to share the same name and it's their id that differentiates them.

This is my workaround for now:

// Shared Form component

export const Form = <T extends FieldValues>({
    children,
    defaultValues,
    disabled,
    onSubmit,
}: FormProps<T>): JSX.Element {
    const methods = useForm<T>({
        defaultValues,
        mode: 'onChange',
        disabled,
    });

    const { handleSubmit, reset } = methods;

    useEffect(() => {
        reset(defaultValues);
    }, [JSON.stringify(defaultValues)]);

    return (
        <FormProvider {...methods}>
            <form onSubmit={onSubmit && handleSubmit(onSubmit)}>{children}</form>
        </FormProvider>
    );
};
// How Form is being used, where disabled state is set

export const Page = (): JSX.Element => {
    const canEdit = hasPermission(some_permissions_rule);

    return (
        <Form
                onSubmit={handleSubmit}
                defaultValues={irrigationControlSettings}
                disabled={!canEdit}
            >
                <SomeInputs canEdit={canEdit} />
                {canEdit && (
                    <FormActions />
                )}
          </Form>
    );
};
// SomeInputs.tsx, where I have to pass the disabled state into the radio inputs explicitly

type SomeInputsProps = {
    canEdit: boolean;
};

export const SomeInputs = ({ canEdit }: SomeInputsProps): JSX.Element => {
    const fruits = [
        {
            label:  'Orange',
            id: 'orange',
        },
        {
            label: 'Apple',
            id: 'apple',
        },
    ];

    return (
        <div>
            <RadioInput
                labelForAllInputs="Fruits"
                name="fruits"
                options={fruits}
                validationRules={!canEdit ? { disabled: true } : {}}
            />
           ...remaining form inputs
        </div>
    );
};


// RadioInput.tsx, uses a shared Input component

export const RadioInput = ({
    labelForAllInputs,
    options,
    name,
    validationRules
}): JSX.Element => {
    return (
        <div>
            <p>{labelForAllInputs}</p>}
            <div>
                {options.map((optionProps) => (
                    <Input
                        key={optionProps.id}
                        name={name}
                        type="radio"
                        validationRules={validationRules}
                        {...optionProps}
                    />
                ))}
            </div>
        </div>
    );
};

I've also tried the following:

  1. Using the disabled property from useFormState
  2. Using the Controller component

But neither worked. Might there be a better or suggested way for radio inputs to pick up on the whole form being set to disabled? I'd like to avoid having to pass down the canEdit prop all the way to the radio inputs, especially because I thought the purpose of setting the disabled state in the FormProvider was so that all the inputs could pick up on it and there would be no prop drilling needed.

What browsers are you seeing the problem on?

Chrome

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct
@erashu212
Copy link
Contributor

erashu212 commented May 9, 2024

@singhshemona BTW, there is no way to pass disabled to useForm as per the latest documentation unless otherwise. May be this can help link

bluebill1049 added a commit that referenced this issue May 18, 2024
…11873)

* feat: allow `iterateFieldsByAction` to iterate over multiple refs

* fix: `_disableForm` only disables one input when inputs share a name

* test: add unit tests for action iteration over multiple refs

* refactor: invert `abortEarly` param's logic to respect semantic meaning

* refactor: move ref iteration logic to if block

* chore: fix lint errors

* test: rename tests to reflect changes

* Update createFormControl.ts

* Update iterateFieldsByAction.ts

* Update iterateFieldsByAction.test.ts

---------

Co-authored-by: Beier (Bill) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants