Reputation: 85
How to disable "Next" button when fields aren't correctly filled out? I would like block this step. I using passwordRules[] and emailRules[].
:disabled="" working for buttons in specific steps, but I don't know how to use it for inputs rules.
Could someone please help me solve this problem?
Demo code: https://codepen.io/noobmaster2137/pen/JjbZLKz
HTML:
<div id="app">
<v-app id="inspire">
<v-card
class="mx-auto"
width="100%"
max-width="400"
>
<v-card-title class="title font-weight-regular justify-space-between">
<span>{{ currentTitle }}</span>
<v-avatar
color="primary lighten-2"
class="subheading white--text"
size="24"
v-text="step"
></v-avatar>
</v-card-title>
<v-window v-model="step">
<v-window-item :value="1">
<v-card-text>
<v-text-field
v-model="email"
:rules="emailRules"
:counter="50"
label="Email"
minlength="5"
maxlength="50"
required
></v-text-field>
</v-card-text>
</v-window-item>
<v-window-item :value="2">
<v-card-text>
<v-text-field
v-model="password"
:rules="passwordRules"
label="Password"
type="password"
></v-text-field>
<v-text-field
v-model="confirmPassword"
:rules="passwordRules"
label="Confirm Password"
type="password"
></v-text-field>
</v-card-text>
</v-window-item>
<v-window-item :value="3">
<div class="pa-4 text-center">
<v-img
class="mb-4"
contain
height="128"
src="https://cdn.vuetifyjs.com/images/logos/v.svg"
></v-img>
<h3 class="title font-weight-light mb-2">
Welcome to Vuetify
</h3>
<span class="caption grey--text">Thanks for signing up!</span>
</div>
</v-window-item>
</v-window>
<v-divider></v-divider>
<v-card-actions>
<v-btn
:disabled="step === 1"
text
@click="step--"
>
Back
</v-btn>
<v-spacer></v-spacer>
<v-btn
:disabled="step === 3"
color="primary"
depressed
@click="step++"
>
Next
</v-btn>
</v-card-actions>
</v-card>
</v-app>
</div>
JS:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
step: 1,
email: '',
emailRules: [
v => !!v || 'Email is required',
v => v.length >= 5 || 'The e-mail address must contain at least 5 characters',
v => v.length <= 50 || 'The e-mail address cannot be longer than 50 characters',
v => /.+@.+/.test(v) || 'Please enter a valid email address',
],
password: '',
confirmPassword: '',
passwordRules: [
v => !!v || 'Password is required',
v => v.length >= 8 || 'Password must contain at least 8 characters',
v => v.length <= 50 || 'Password address cannot be longer than 50 characters',
],
}),
computed: {
currentTitle () {
switch (this.step) {
case 1: return 'Sign-up'
case 2: return 'Create a password'
default: return 'Account created'
}
},
},
})
Upvotes: 1
Views: 792
Reputation: 821
Please check if this helps
HTML:
<div id="app">
<v-app id="inspire">
<v-card class="mx-auto" width="100%" max-width="400">
<v-card-title class="title font-weight-regular justify-space-between">
<span>{{ currentTitle }}</span>
<v-avatar color="primary lighten-2" class="subheading white--text" size="24"
v-text="step"
></v-avatar>
</v-card-title>
<v-window v-model="step">
<v-window-item :value="1">
<v-form v-model="isFormValid">
<v-card-text>
<v-text-field v-model="email" :rules="emailRules" :counter="50"
label="Email" minlength="5" maxlength="50" required
></v-text-field>
</v-card-text>
</v-form>
</v-window-item>
<v-window-item :value="2">
<v-form v-model="isFormValid">
<v-card-text>
<v-text-field v-model="password" :rules="passwordRules" label="Password"
type="password"
></v-text-field>
<v-text-field v-model="confirmPassword" :rules="passwordRules"
label="Confirm Password" type="password"
></v-text-field>
</v-card-text>
</v-form>
</v-window-item>
<v-window-item :value="3">
<div class="pa-4 text-center">
<v-img class="mb-4" contain height="128"
src="https://cdn.vuetifyjs.com/images/logos/v.svg"
></v-img>
<h3 class="title font-weight-light mb-2">Welcome to Vuetify</h3>
<span class="caption grey--text">Thanks for signing up!</span>
</div>
</v-window-item>
</v-window>
<v-divider></v-divider>
<v-card-actions>
<v-btn :disabled="!isFormValid ||step === 1" text @click="step--">
Back
</v-btn>
<v-spacer></v-spacer>
<v-btn :disabled=" !isFormValid || step === 3" color="primary" depressed @click="step++">
Next
</v-btn>
</v-card-actions>
</v-card>
</v-app>
</div>
JS:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
step: 1,isFormValid: false,
email: '',
emailRules: [
v => !!v || 'Email is required',
v => v.length >= 5 || 'The e-mail address must contain at least 5 characters',
v => v.length <= 50 || 'The e-mail address cannot be longer than 50 characters',
v => /.+@.+/.test(v) || 'Please enter a valid email address',
],
password: '',
confirmPassword: '',
passwordRules: [
v => !!v || 'Password is required',
v => v.length >= 8 || 'Password must contain at least 8 characters',
v => v.length <= 50 || 'Password address cannot be longer than 50 characters',
],
}),
computed: {
currentTitle () {
switch (this.step) {
case 1: return 'Sign-up'
case 2: return 'Create a password'
default: return 'Account created'
}
},
},
})
Upvotes: 1
Reputation: 144
You could use a computed property called "canAdvance" like this
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
step: 1,
email: '',
emailRules: [
v => !!v || 'Email is required',
v => v.length >= 5 || 'The e-mail address must contain at least 5 characters',
v => v.length <= 50 || 'The e-mail address cannot be longer than 50 characters',
v => /.+@.+/.test(v) || 'Please enter a valid email address',
],
password: '',
confirmPassword: '',
passwordRules: [
v => !!v || 'Password is required',
v => v.length >= 8 || 'Password must contain at least 8 characters',
v => v.length <= 50 || 'Password address cannot be longer than 50 characters',
],
}),
computed: {
currentTitle () {
switch (this.step) {
case 1: return 'Sign-up'
case 2: return 'Create a password'
default: return 'Account created'
}
},
canAdvance() {
return this.emailRules.every(rule => rule(this.email) === true) &&
this.passwordRules.every(rule => rule(this.password) === true);
}
},
})
and then use the property to enable or disable the button.
I would return true or false on each rule instead of the error message, something like this
data: {emailRules: [{validator: (v) => {return !!v}, errorMessage: 'Email is required'}]}
so you can separate the validation from the error message and adapt your code to show the corresponding message foreach rule
Upvotes: 0