[BUG] - Validation Inconsistency
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
Operating System Version
Mac
Browser
Chrome
Can you share the exact code of those components shown in the screenshot? A sandbox would be better.
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
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,
//...
};
//....
},
[
//...
],
);
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.
@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.
would you assign to me? I'll try to fix it.
@jijiseong assigned. thanks.
@wingkwong What should i do to achieve the reverse of this issue, i.e disable the build in html validation from select.
For example:
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?
@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,
//...
};
//....
},
[
//...
],
);
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
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.
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.