nextui icon indicating copy to clipboard operation
nextui copied to clipboard

[BUG] - Validation Inconsistency

Open Rain-YuXia opened this issue 1 year ago • 1 comments

NextUI Version

2.4.8

Describe the bug

Input and Select validation behaviour is different.

Your Example Website or App

No response

Steps to Reproduce the Bug or Issue

When I set isRequired on both Input & Select, the select dropdown uses HTML built-in validation. However, the input box doesn't.

From the screenshots below, you can see the validation error pops up for Select, but not for Input

Expected behavior

They should behave in the same way.

Screenshots or Videos

Screenshot 2024-10-18 at 2 43 12 PM Screenshot 2024-10-18 at 2 44 26 PM

Operating System Version

Mac

Browser

Chrome

Rain-YuXia avatar Oct 18 '24 01:10 Rain-YuXia

Can you share the exact code of those components shown in the screenshot? A sandbox would be better.

wingkwong avatar Oct 21 '24 11:10 wingkwong

Sorry I couldn't figure out how to work with a Sandbox lol... My code is more or less like below:

<form onSubmit={submit}>
    <Select
        label="Type of Property"
        labelPlacement="outside-left"
        isRequired
        aria-label="Type of Property"
        variant="bordered"
        placeholder="Select the Property Type"
        isInvalid={!!errors.property_type_id}
        errorMessage={errors.property_type_id}
        selectedKeys={[data.property_type_id]}
        onChange={(e) => {updateListingHandler('property_type_id', e.target.value)}}
    >
        {
            category.property_types.map((item) => (
                <SelectItem key={item.id}>
                    {item.name}
                </SelectItem>
            ))
        }
    </Select>

    <Input
          label="$ Per Annum"
          labelPlacement="outside-left"
          isRequired
          size="md"
          variant="bordered"
          startContent={
              <div className="pointer-events-none flex items-center">
                  <span className="text-default-400 text-small">$</span>
              </div>
          }
          value={formatNumber(data.value_per_annum)}
          onValueChange={(v) => updateListingHandler('value_per_annum', v)}
      />
</form>

Then when the form is submitting with empty data in Type of Property, it doesn't trigger onSubmit event and pop-up the built-in validation error.

However, if the $ per Annum is empty, no built-in validation triggered and the code can go to submit function.

Hope I made myself clear lol

Rain-YuXia avatar Oct 21 '24 21:10 Rain-YuXia

Try this. The pop-up still doesn`t appear. but focus and highlight work.

    <Input isRquired validationBehavior="native" />

@wingkwong input uses domRef instead of the original ref. So the pop-up doesn't appear. Is this intentional?

// use-input.ts line 363

 const getInputProps: PropGetter = useCallback(
    (props = {}) => {
      return {
        ref: domRef,
        //...
      };
      //....
    },

    [
      //...
    ],
  );

jijiseong avatar Oct 22 '24 17:10 jijiseong

Try this. The pop-up still doesn`t appear. but focus and highlight work.

    <Input isRquired validationBehavior="native" />

@wingkwong input uses domRef instead of the original ref. So the pop-up doesn't appear. Is this intentional?

// use-input.ts line 363

 const getInputProps: PropGetter = useCallback(
    (props = {}) => {
      return {
        ref: domRef,
        //...
      };
      //....
    },

    [
      //...
    ],
  );

Thanks for the reply.

But I prefer to disable the native validation behaviour for Select, since I have my own validation logics.

As I found out, Input and DatePicker both have disabled the native behaviour. However, Select hasn't. I think it's a inconsistency.

And setting validationBehavior="aria" on Select doesn't disable the built-in validation.

Rain-YuXia avatar Oct 22 '24 23:10 Rain-YuXia

@jijiseong the original ref is passed to useDomRef. In select, there is a hidden native select / input where input component doesn't have it. Maybe the validation part is different here. Need to dig a bit to see if it is related.

wingkwong avatar Oct 23 '24 03:10 wingkwong

would you assign to me? I'll try to fix it.

jijiseong avatar Oct 24 '24 18:10 jijiseong

@jijiseong assigned. thanks.

wingkwong avatar Oct 24 '24 18:10 wingkwong

@wingkwong What should i do to achieve the reverse of this issue, i.e disable the build in html validation from select. For example: image

For the above screenshot i used isRequired in Input but not on Select (but used isInvalid) on flipside of this appraoach is loose the asterisk in the select's label. Is there a better approach for this?

DonBrowny avatar Oct 28 '24 01:10 DonBrowny

@wingkwong Please cancel the assignment. TT I had tried to fix this issue, but I don't know what is the best way. One thing that's certain is that it works properly when passing the original ref direlctly to the input prop.

 const getInputProps: PropGetter = useCallback(
    (props = {}) => {
      return {
        ref: originalProps.ref,
        //...
      };
      //....
    },

    [
      //...
    ],
  );

jijiseong avatar Oct 28 '24 04:10 jijiseong

React Aria prevents browser error UI from appearing, but HiddenSelect causes the Select to display it.

https://github.com/adobe/react-spectrum/blob/93c26d8bd2dfe48a815f08c58925a977b94d6fdd/packages/%40react-aria/form/src/useFormValidation.ts#L70-L71 https://stackblitz.com/edit/vitejs-vite-shqsjy?file=src%2FApp.tsx

chirokas avatar Oct 28 '24 14:10 chirokas

I found that in order to enable the Input to have the default HTML required validation I just need to add required attribute to the Input (on top of the isRequired to get the visual indication).

When using select with isRequired, the generated HTML includes a hidden input with a required attribute, this is set to the value and submitted with the form:

<input tabindex="-1" required type="text" value="" style="font-size: 16px;">

I would expect the Input component to also add the required attribute when it is set with isRequired to enable native form support.

hagai-slash-in avatar Oct 29 '24 20:10 hagai-slash-in

Select is implemented by customizing react-aria, so we haven't been able to incorporate validationBehavior yet. Therefore, we need to enable validationBehavior support for Select.

ryo-manba avatar Nov 06 '24 13:11 ryo-manba