I have a submit button that is initially disabled (through v-bind:disabled
) and will only be enabled until all form inputs are non-empty and errors are resolved. For each of my input, I have a spinner that will become a check or an x after verifying the validity of the input. This takes a few seconds and I was hoping that the same delay be applied to the enabling of the submit button. At the moment, this is what the form looks like:
This is the form (in pug):
.form-group
label Email Address
.input-group
input.form-control(type="email" name="emailAddress" value=profile.email
v-model="email"
v-validate
data-vv-delay="1000"
data-vv-rules="required|email"
data-vv-as="email"
:class="{ 'input': true, 'is-danger': errors.has('emailAddress') }"
placeholder="eg. andres@gmail.com")
.input-group-append
span.input-group-text
i.fal.fa-pulse.fa-spinner(v-if="email && emailBusy")
i.fal.fa-check.text-green(v-if="email && !emailBusy && !isEmailTaken && !errors.has('emailAddress')")
i.fal.fa-times.text-red(v-if="email && !emailBusy && (isEmailTaken || errors.has('emailAddress'))")
span.text-danger.text-error(v-show="errors.has('emailAddress')") {{ errors.first('emailAddress') }}
span.text-danger.text-error(v-if="email && email.length > 0 && isEmailTaken") Email address has already been taken
.form-group
label Username
.input-group
input.form-control(type="name" name="username"
v-model="username"
v-validate
data-vv-delay="1000"
data-vv-rules="required|verify_username"
:class="{ 'input': true, 'is-danger': errors.has('username') }"
placeholder="eg. andres45")
.input-group-append
span.input-group-text
i.fal.fa-pulse.fa-spinner(v-if="username && usernameBusy")
i.fal.fa-check.text-green(v-if="username && !usernameBusy && !isUsernameTaken && !errors.has('username')")
i.fal.fa-times.text-red(v-if="username && !usernameBusy && (isUsernameTaken || errors.has('username'))")
span.text-danger.text-error(v-show="errors.has('username')") {{ errors.first('username') }}
span.text-danger.text-error(v-if="username && username.length > 0 && isUsernameTaken") Username has already been taken
.form-group
button.btn.btn-blue(:disabled="errors.any() || isEmailTaken || isUsernameTaken || !username || !email" type="submit")
i.fal.fa-sign-in.mr-2
span Complete Sign Up
The vue instance:
var register = new Vue({
el: '#register',
data: {
email: email,
username: null,
isUsernameTaken: false,
usernameTimer: null,
usernameBusy: false,
isEmailTaken: false,
emailTimer: null,
emailBusy: false
},
methods: {
validateEmail: function(email) {
var self = this;
var url = '/api/users?email=' + email;
self.$http.get(url)
.then(function(res){
self.isEmailTaken = true;
self.emailBusy = false;
}, function(err){
self.isEmailTaken = false;
self.emailBusy = false;
});
},
validateUsername: function(username) {
var self = this;
var url = '/api/users/' + username;
self.$http.get(url)
.then(function(res){
self.isUsernameTaken = true;
self.usernameBusy = false;
}, function(err){
self.isUsernameTaken = false;
self.usernameBusy = false;
});
}
},
watch: {
username: function(val) {
var self = this;
clearTimeout(self.usernameTimer);
self.usernameBusy = true;
self.usernameTimer = setTimeout(function() {
self.validateUsername(val);
}, 1600);
},
email: function(val) {
var self = this;
clearTimeout(self.emailTimer);
self.emailBusy = true;
self.emailTimer = setTimeout(function() {
self.validateEmail(val);
}, 1600);
}
}
});