-
-
Notifications
You must be signed in to change notification settings - Fork 7k
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
Make v-form validation great again #1581
Conversation
028a280
to
6b379da
Compare
- data.inputs is now an array instead of an int - Dynamically added inputs contribute to form validity - Removed inputs no longer contribute to form validity
- Now emits on every change, allowing optional fields - Removed redundant function calls
7acec58
to
c713172
Compare
- Validate runs through all inputs again instead of stopping at the first error
Create a test corresponding to the changes and I'll finish my review and merge, thank you. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
src/components/VForm/VForm.js
Outdated
}, false) | ||
|
||
return !errors | ||
return !this.inputs.filter(input => input.validate(true)).length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could/should be !this.inputs.every(input => input.validate(true))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had that in 9a5063b, but it stops at the first invalid field. I can change it to ...length !== 0
to make it more clear what is happening.
Edit: or
const errors = this.inputs.filter ... .length
return !errors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could also possibly use this.inputs.some(input => !input.validate(true))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.some
has the same problem as .every
.
The every method executes the provided callback function once for each element present in the array until it finds one where callback returns a falsy value. If such an element is found, the every method immediately returns false.
some() executes the callback function once for each element present in the array until it finds one where callback returns a truthy value (a value that becomes true when converted to a Boolean). If such an element is found, some() immediately returns true.
input.validate()
must be called on every element so that validation errors are forced to display.
src/components/VForm/VForm.js
Outdated
} | ||
|
||
this.inputs.push(child) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove space
this.$vuetify.load(() => { | ||
this.getInputs().forEach((child) => { | ||
this.inputs += 1 | ||
this.$vuetify.load(() => this.watchInputs()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be this.$vuetify.load(this.watchInputs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That will pass the global Window
object to watchInputs
, instead of undefined
.
Is .load()
even needed? Nothing seems to change if I remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's for SSR protection lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also valid point, no need to change this.
Brilliant! Now I begin to think that external validators are second class. I believe this enhancement should work on Looking forward for a quick merge! |
src/components/VForm/VForm.js
Outdated
@@ -78,11 +75,13 @@ export default { | |||
}) | |||
}, | |||
validate () { | |||
return !this.inputs.filter(input => input.validate(true)).length | |||
return !this.inputs.filter(input => input.validate(true)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reasoning for this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, thanks for pointing that out. That wasn't meant to be pushed.
- Make validate() method more readable
1cf254f
to
671f33a
Compare
Form validation (
<v-form v-model="valid">
) is kinda useless right now:valid
only changes when every single form field has been updated, whether they require validation or not. This makes optional fields impossible without having to callform.validate()
v-if
or similar), it doesn't ever count towards validation, even ifform.validate()
is calledform.reset()
orform.validate()
is calledThis PR fixes all these issues, making validation of forms like this or this possible.
valid
will change after every update.form.validate()
can still be called to check overall form validity and force validation errors to display on untouched invalid fieldslazy-validation
is added that only takes into account touched fields when determining overall validity (this is the same as it is currently) - soform.reset()
will result invalid
beingtrue
valid
should now betrue