Broken form validations in SolidJS?
Describe the bug
Hey! I am literally following the guide for validations and I am unable to accomplish a simple validation.
Your minimal, reproducible example
https://stackblitz.com/edit/solidjs-templates-bv3rc2x1?file=src%2FApp.tsx
Steps to reproduce
- Follow the instructions in the guide
- Observe field validation doesn't fire
- Observe submit button doesn't get conditionally disabled
Expected behavior
Probably resolving the issue with validator not running would resolve the button state?
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
N/A
TanStack Form adapter
solid-form
TanStack Form version
1.0.5
TypeScript version
5.1.3
Additional context
No response
onInput is the listener you are looking for here.
So the problem here is how SolidJS treats onChange.
onInput triggers immediately when the input value changes, whether by user typing, pasting, or any other form of content modification. This event fires with each keystroke or value change.
onChange triggers when the input loses focus after being modified (on blur), or when the user explicitly commits a change (like pressing Enter in some inputs).
As for the docs, there are 5 instances where I see this error is made, I will verify them and make a commit based on whether their usage is OK. Thank you for bringing this up!
@theVedanta found one more issue (potentially? I've updated the example). Notice both canSubmit and isValid are true by default. Even if I set defaultState to false, that doesn't change. I modified the validator to always fail, yet the form remains submittable until the first keystroke.
For DX, I wouldn't expect to have to set defaultState at all. The validators should be executed with default values and that's what should determine the initial state. Forcing the default state through defaultState might trip some people up, but would be still an acceptable workaround as long as it works.
I think this is a good insight!
However, the defaultState is not something I would expect to have toggled to false for canSubmit and isValid. From what I get, it SHOULD be set based on the initial values. In the stackblitz example, the onChange checks for the validation not some validator.
If you had a validator check it, for example onMount on the form-level, you would get the desired output.
You can check out this example: https://stackblitz.com/edit/solidjs-templates-g56ng1la?file=src%2FApp.tsx
This has both canSubmit and isValid as false without the defaultState being set because it validates on-mounting not on-changing.
@theVedanta Thanks! This should work as a workaround for me. For clarity, these two are definitely bugs within the package.
- As described above, when setting
defaultState, the form should be disabled. If this isn't something you'd expect me doing, it shouldn't be autocompleted by IDE and throw when I try to do so. Otherwise, it should work as one would expect. - Even if I don't do anything else but keep the "always throw"
onChangevalidator, the form should be disabled. Right now, I can press the submit button, but doing so runs the validators and instead of submitting, it disables the form. This is inconsistent with the initial state, so I should either be able to submit the invalid form or it should be disabled from the start.
My take is that 1 should work as expected, otherwise there isn't much point offering that feature. 2 should be always disabled, otherwise the form would allow invalid submissions by default which defeats the purpose.
- I think this might be right, it should either reflect the settings provided or just not have the options to set the values that it will auto-change anyways. However, I will let a maintainer comment on this for more clarity.
- I don't think this is the right approach. The onChange validator should only check onChange. There's a reason the
onMountvalidator exists. If we want to have the form check for validations when it it loaded on the screen we might wanna use that and not just depend on the onChange to make it an invalid form.
@theVedanta 2. Why doesn't the form submit then when I click the submit button from initial state?