Reputation: 2654
I am using Vue CLI and Bootstrap and am having trouble with the form validation currently when the page loads all the input fields load as invalid. I can see why this is happening because the input fields are getting a class of is-invalid
. I have fixed this by passing the state prop a value of null when it is false. It does not seem like the default behavior should be to run the validation when the page loads but maybe it is. I believe I have everything set up correctly as far as structure and proper classes I followed the bootstrap-vue docs.
My Code
<b-form
@submit.prevent="addReview"
name="review-form"
class="needs-validation"
novalidate
>
<div class="name">
<label class="sr-only" for="form-input-name">Name</label>
<b-input
id="form-input-name"
class="form-inputs mb-2 mr-sm-2 mb-sm-0"
v-model="name"
placeholder="Name"
required
:state="isEmpty(this.name) ? true : null" <---- My problem is here
></b-input>
...
</b-form>
My problem is I need 3 results from this ternary which obviously isn't possible. I need null on load to remove the error messages then false to display error on validation and true to display valid input. I have been struggling with this for days so any help with any aspect of this setup would be greatly appreciated if you want more code let me know. The submit button adds a class of was-validated
which does display any error messages that are associated with empty inputs but doesn't validate the inputs.
Question
How do I validate inputs while still keeping form error messages hidden on load.
Upvotes: 4
Views: 10291
Reputation: 56
You aren't bound to just using a ternary statement in the :state
prop - you can hook :state
up to a computed property directly, which will achieve three things (this is similar to what is shown in the documentation):
I'm working loosely off of your example, but something like the following should solve your issue:
<template>
<div id="app">
<img width="25%" src="./assets/logo.png" style="margin-bottom: 15px;">
<b-form>
<div class="name">
<label class="sr-only" for="form-input- name">Name</label>
<b-input v-model="name" id="form-input-name" :state="isNameStateValid"></b-input>
</div>
</b-form>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
name: ""
};
},
methods: {
isValid() {
return this.name.length > 3 ? true : false; //your validation criteria goes here
}
},
computed: {
isNameStateValid() {
if (this.name) {
return this.isValid(this.name);
}
return null;
}
}
};
</script>
In the above, you would have a method that would check for your specific validation criteria (isValid, isEmpty, etc.).
Our new computed property, isNameStateEmpty, will use that method's return value, returning false for a validation failure (triggering BootstrapVue's failed validation state), true for a validation pass, or null in the event that this.name
does not have a current value (examples being a fresh page load, or a user clearing the input field, making it blank).
See a working Codesandbox of this behavior here.
Because the input's v-model (v-bind:value and @change) is set to our "name" data property, every character change within the input field will reactively update our data property (this.name
).
Because our isNameStateValid
computed property has a dependency of this.name
, it will reevaluate on every change of the this.name
data property - ensuring real-time validation using BootstrapVue's validation state.
Hopefully that helps.
Upvotes: 3