koumoul-dev / vuetify-jsonschema-form

Create beautiful and low-effort forms that output valid data. Published on npm as @koumoul/vjsf.
https://koumoul-dev.github.io/vuetify-jsonschema-form/latest/
MIT License
553 stars 156 forks source link

Form is not rendering initial error validations #160

Closed sobrinho closed 4 years ago

sobrinho commented 4 years ago

Hey,

The form is not rendering the initial validations but it is being validated (the state model is false but the validation message only appears after calling form.validate()).

Example: https://codepen.io/gcsobrinho/pen/RwavMdx

You can see the valid=false but the error message only renders when you click Validate.

albanm commented 4 years ago

If I understand correctly your issue, it is intended. See this v-form example.

Validation errors are displayed either when calling .validate() or when a component gets focus then loses it (blur event). This way the user is not overloaded by errors, but only once he progresses in the form and makes mistakes or when he actually tries to validate it. If you wish to display all errors right away run validate().

sobrinho commented 4 years ago

I'm not sure if that's an issue with VJSF or Vuetify but this UX can be improved.

The problem is that the user does not know what field has an issue when the form is initially rendered, he needs to focus/blur every field to figure this out.

And even worse, if you rely on form v-model to render a "check the form errors" message, he won't see them.

sobrinho commented 4 years ago

I've updated the pen to better demonstrate the issue: https://codepen.io/gcsobrinho/pen/RwavMdx

The form is rendered with the data but only two of the three fields has an error and by using the v-model to render the check form errors, makes the user confused.

sobrinho commented 4 years ago

And to demonstrate why I can't call validate when the Vue component is mounted: https://codepen.io/gcsobrinho/pen/LYNqmOQ

In the initial state, the form doesn't contain errors yet, the user hasn't interacted with it yet.

The perfect UX would be something like that:

  1. The initial rendering does not validate not yet interacted fields
  2. The initial rendering would validate already filled fields
albanm commented 4 years ago

If the data was already interacted with globally in a previous session then re-displayed with potentially different validation rules, your application should know about it. Then calling .validate() and showing all errors from the start might be desirable.

Otherwise it is pristine and errors should not be shown before interactions or manual validation.

I am sorry but I remain unconvinced, differentiating filled and non-filled properties doesn't strike me as the right thing to always do. A property might be filled without true interactions by the user, a property might be non-filled and still have been interacted with in previous sessions (filled then emptied).

albanm commented 4 years ago

I I understand correctly the thing that bothers you is this special case:

Is that it ?

sobrinho commented 4 years ago

Kind of; what triggered all of that is that a default value recently changed in the schema and now the UX is like that:

  1. We have a message saying that something is wrong in the form, please check
  2. But there is no error rendered in the form
  3. The submit button which would trigger the validation is disabled because the v-model state is saying that the form is invalid

Later I figured I could focus/blur the fields to find the wrong data but a normal user wouldn't.


Our first try was to allow to submit the form to trigger the validation but the UX is still bad:

  1. We have a message saying that something is wrong in the form, please check
  2. But there is no error rendered in the form
  3. Submit the form (validates)
  4. The check the form message is still there and it didn't save
  5. I have to check across different tabs again (yes, we are using tabs, to make it even worse to find out the field)

Our second try was to trigger the validations in the initial rendering but then we are back to the situation of flooding validations from fields that weren't filled by the user yet, which is also not good.

Eventually, we figured the defective default value and fixed it but later a validation changed and we got the exact unintuitive UX again.


With your suggestion, I am now checking if the data is persisted before performing the initial validation but this doesn't sound intuitive to me and can be brittle in other use cases.

And to make it consistent across the application, we have to use a customized component to keep the correct validation behavior.


I'm wondering, why would we want a behavior other than that?

albanm commented 4 years ago

Ok, I am starting to come around and I will try some changes.

Still a little bit concerned that what you perceive as the obvious adaptive behavior might be considered as unpredictable black magic by others and cause regressions. Maybe I will create an option and not activate it by default to be safe.

sobrinho commented 4 years ago

Yeah, it sounds the appropriate behavior but others might expect differently.

Maybe we can have an option like validation: initial/always/lazy/etc, I'm not sure about the values but something in that line would be awesome!

albanm commented 4 years ago

Just pushed this commit https://github.com/koumoul-dev/vuetify-jsonschema-form/commit/47745dc2291b279709e894d5d378c631f3d17a83

I think it might do the trick. Could you maybe clone the repo, check the behavior directly from source code and give me feedback ? Otherwise I will perform some more tests myself later on. You can see CONTRIBUTE.md for how to run the examples.