How to check passwords match in vanilla Vue.js? - javascript

I'm new to Vue.js and I'd like to check if passwords are matched.
If they do not match, after the user leaves the confirmation field, the error text Passwords don't match! should appear.
I've seen a couple of solutions which involve using plugins, but I'm wondering what is the idiomatic way to do it using pure vue.js?
https://jsfiddle.net/Babrz/L2md63j7/3/
<div id="app">
<form >
<div class="form-group">
<input type="email" class="form-control" placeholder="Email">
</div>
<br>
<div class="form-group">
<input type="password" class="form-control" v-model="password" placeholder="Password">
</div>
<br>
<div class="form-group">
<input type="password" class="form-control" v-model="password2" placeholder="Confirm Passwrd">
</div>
<small v-if="showError">Passwords don't match!</small>
<br>
<div class="form-group">
<input type="text" class="form-control" placeholder="Age">
</div>
<br>
<button type="submit" class="btn login-btn">Register</button>
</form>
</div>
new Vue({
el: "#app",
data: {
email: '',
password: '',
password2: '',
age: 0,
showError: false
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
}
})

It sounds like you want to use an onblur event to run a validation on the two password values. A very basic implementation might look like this.
...
<input v-on:blur="validate" type="password" class="form-control" v-model="password2" placeholder="Confirm Passwrd">
...
...
new Vue({
el: "#app",
data: {
email: '',
password: '',
password2: '',
age: 0,
showError: false
},
methods: {
toggle: function(todo){
todo.done = !todo.done
},
validate: function() {
console.log(this.password === this.password2)
}
}
})
...
https://v2.vuejs.org/v2/guide/events.html
You can get a lot of help if you use something like validate.js to validate your passwords too.
http://validatejs.org

Related

Password validation in Vue 3 isn't working properly

Making a registration form for a website using Vue 3. I have a method, that gets values of password and password confirmation fields and compares it. If they're true - nothing happens, else - a red label appears and submit button gets disabled. I have implemented this in vue 3. but when passwords are equal, it dont works, but sometimes when they are not, it displays that they are.
<template>
<div>
<label for="password">Пароль</label>
<input type="text" v-model="password" name="password" id="password" placeholder="••••••••" required="">
</div>
<div>
<label for="confirm-password">Подтвердите Пароль</label>
<input #keydown="confirmPassword" type="confirm-password" v-model="confirm" name="confirm-password" id="confirm-password" placeholder="••••••••" required="">
<label for="confirm-password" v-if="invalidPasswords">Пароли не совпадают</label>
</div>
<button :disabled="submitDisabled" type="submit">Создать аккаунт</button>
</template>
<script>
export default {
name: "RegistrationView",
data () {
return {
...
password: '',
confirm: '',
invalidPasswords: false,
submitDisabled: false,
}
},
methods: {
confirmPassword() {
if (this.password !== this.confirm){
this.invalidPasswords = true
this.submitDisabled = true
} else {
this.invalidPasswords = false
this.submitDisabled = false
}
},
},
}
</script>
Screenshots: https://i.stack.imgur.com/3eOB1.png https://i.stack.imgur.com/ein5h.png https://i.stack.imgur.com/ein5h.png
Just change #keydown event to #input :
<input #input="confirmPassword" type="confirm-password" v-model="confirm" name="confirm-password" id="confirm-password" placeholder="••••••••" required="">
You can use #keyup or #input instead of #keydown in your confirm password:
<input #keyup="confirmPassword" type="confirm-password" v-model="confirm" name="confirm-password" id="confirm-password" placeholder="••••••••" required="">
OR
<input #input="confirmPassword" type="confirm-password" v-model="confirm" name="confirm-password" id="confirm-password" placeholder="••••••••" required="">
Both work fine.

Enable/Disable button with vueJs

new Vue({
el: '#app',
data: {
terms: false,
fullname: false,
mobile: false,
area: false,
city: false,
},
computed: {
isDisabled: function(){
return !this.terms && !this.fullname && !this.mobile && !this.area && !this.city;
}
}
})
<div id="app">
<p>
<label for='terms'>
<input id='terms' type='checkbox' v-model='terms' /> I accept terms!!!
<input id="fullname" type='text' v-modal='fullname'/> name
<input id="mobile" type='text' v-modal='mobile'/> mobile
<input id="area" type='text' v-modal='area'/> area
<input id="city" type='text' v-modal='city'/> city
</label>
</p>
<button :disabled='isDisabled'>Send Form</button>
</div>
Until user fill all the details, button should be disabled.
But Issue with this is if i click on checkbox directly button is enabling without checking for other fields
There are many problems in your code and i will list them one by one.
data property should be a function.
fullname , mobile , ... are bound to input type="text" so empty string is better for initial value.
there are typos in your v-modal
there is a mistake in your logical formula for isDisabled
so the final code should be like this:
new Vue({
el: '#app',
data() {
return {
terms: false,
fullname:'',
mobile: '',
area: '',
city: '',
};
},
computed: {
isDisabled: function(){
return !this.terms || !this.fullname || !this.mobile || !this.area || !this.city;
}
}
})
<div id="app">
<p>
<label for='terms'>
<input id='terms' type='checkbox' v-model='terms' /> I accept terms!!!
<input id="fullname" type='text' v-model='fullname'/> name
<input id="mobile" type='text' v-model='mobile'/> mobile
<input id="area" type='text' v-model='area'/> area
<input id="city" type='text' v-model='city'/> city
</label>
</p>
<button :disabled='isDisabled'>Send Form</button>
</div>
I highly recommend you to use IDE or eslint.

How can I use field validation in my Vue wizard form?

In an example of a Vue wizard form I tried to add form validation with Joi. How do I set this up logically? The goal is to controll the fields before moving to the second and last page with the next() method. Because of the simplicity of this wizard form, I don't want to change to VueFormWizard. To increase the code I erased a lot of fields etc..
<template>
<div>
<div v-if="errorMessage" class="alert alert-danger" role="alert">
{{errorMessage}}
</div>
<form>
<div v-if="step ===1 ">
<div class="form-group">
<label for="title">Title</label>
<input v-model="example.title"
type="text"
class="form-control"
id="title" />
</div>
<button #click.prevent="next()">Next step</button>
</div>
<div v-if="step === 2">
<div class="form-group">
<label for="userName">Email.</label>
<input v-model="example.userName"
type="email"
class="form-control"
id="userName" />
</div>
<button #click.prevent="prev()">Go back</button>
<button #click.prevent="createExample" type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</template>
<script>
import Joi from 'joi'
const schema = Joi.object().keys({
title: Joi.string().alphanum().min(2).max(40).required(),
userName: Joi.string().email(),
})
export default {
data: () => ({
step: 1,
errorMessage: false,
example: {
title: '',
userName: ''
}
}),
watch: {
example: {
handler () {
this.errorMessage = ''
},
deep: true
}
},
methods: {
prev () {
this.step--
},
next () {
this.step++
if (this.validUser()) {
return false
}
},
createExample () {
// Post request
},
validUser () {
const result = Joi.validate(this.huismap, schema)
return true
if (result.error.message.includes('title')) {
this.errorMessage = 'Vul een titel in van min 2 karakters'
return false
}
}
}
</script>
You can make use of browser validation if you set it up like this:
<form #submit.prevent="submitMyForm">
<input v-model="form.title" required minlength="4" maxlength="20" />
<button type="submit">Submit</button>
</form>
Now your browser will prevent you from submitting the form if title is empty, if the length is less than 4 or greater than 20.
This solution can do a lot of stuff, even regex checking:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation#Validating_against_a_regular_expression
However this is limited to a small set of checks and is not supported by older browsers. If you need very specific validation you'd have to use a custom solution, which is described here https://v2.vuejs.org/v2/cookbook/form-validation.html.

Marko JS on-submit

I can't get this to work, it will not console.log(this.stat.first_name) , I need to know how to access the input form values that are entered so I can change state and then make an axios post request in the postSubmit function. I am doing the console.log first to test it and get data movement correct.
Anything will help.
First question was deleted, this is a repost as I did not figure the problem out.
class {
onCreate() {
this.state = {
first_name: null,
last_name: null,
email: null,
address: null,
phone_number: null,
email_promotion_optin: false
};
}
postSubmit(event) {
event.preventDefault();
this.state.first_name = event.target.name.first_name;
console.log(this.state.first_name);
}
}
<form on-click('postSubmit')>
<fieldset>
<legend> Create Customer</legend>
<div>
<label>
First Name: <input type="text" name="first_name">
</label>
</div>
<div>
<label>
Last Name: <input type="text" name="last_name">
</label>
</div>
<div>
<label>
Email: <input type="text" name="email">
</label>
</div>
<div>
<label>
Address: <input type="text" name="address">
</label>
</div>
<div>
<label>
Phone Number: <input type="text" name="phone_number">
</label>
</div>
<div>
<label>
Submit <input type="submit">
</label>
</div>
</fieldset>
</form>
UPDATE!!!!!!:
I have come up with this from MarkoJS documentation, but still no luck. I may be on the right route or I may be polluting my code with a lot of unnecessary crap.
$ const axios = require('axios');
class {
onCreate() {
this.state = {
first_name: '',
last_name: '',
email: '',
address: '',
phone_number: '',
email_promotion_optin: false
};
}
onFirstNameInput () {
this.state.first_name = this.getEl('firstName').value;
}
onLastNameInput () {
this.state.last_name = this.getEl('lastName').value;
}
onEmailInput () {
this.state.email = this.getEl('email').value;
}
onAddressInput () {
this.state.address = this.getEl('address').value;
}
onPhoneNumberInput () {
this.state.phone_number = this.getEl('phoneNumber').value;
}
postSubmit() {
axios.post('/api/v1/customers', this.state)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
}
<form>
<fieldset>
<legend> Create Customer</legend>
<div>
<label>
First Name: <input type="text" key="firstName" on-input('onFirstNameInput')>
</label>
</div>
<div>
<label>
Last Name: <input type="text" key="last_name" on-input('oneLastNameInput')>
</label>
</div>
<div>
<label>
Email: <input type="text" key="email" on-input('onEmailInput')>
</label>
</div>
<div>
<label>
Address: <input type="text" key="address" on-input('onAddressInput')>
</label>
</div>
<div>
<label>
Phone Number: <input type="text" key="phone_number" on-input('onPhoneNumberInput')>
</label>
</div>
</fieldset>
<div>
<button on-click('postSubmit')>Submit</button>
</div>
</form>
I looked into the issue. The reason that the code is not working as expected is that the properties on the this.state object are not defined as enumerable. MarkoJS uses Object.defineProperty to create getters and setters for the state properties, but it is not explicitly setting the enumerable property to true so it is defaulting to false. I think we should fix this and opened up a GitHub issue to discuss: https://github.com/marko-js/marko/issues/964
In the meantime, I recommend the following workaround to explicitly copy over the properties that should be submitted with the HTTP post:
postSubmit() {
var request = {
first_name: this.state.first_name,
last_name: this.state.last_name,
email: this.state.email,
address: this.state.address,
phone_number: this.state.phone_number,
email_promotion_optin: this.state.email_promotion_optin
}
axios.post('/api/v1/customers', request)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}

Vue/Jquery override two-way data bidning

I have an input in a Vue.js component that I need to override using jquery. I need to fill an input with an email address using jquery. When I press fill in email jQuery will populate the email input. But when I use V-model this it is not updated. Is there a workaround for this?
Here is a working jsfiddle example
https://jsfiddle.net/s3b7f1ah/
Here is the HTML
<button id="push-email">Fill in email</button>
<br><br>
<div id="root">
<label for="name">Name</label>
<input type="text" name="name" id="name" v-model="name">
<label for="name">Email</label>
<input type="text" name="email" id="email" v-model="email">
<br><br>
<button #click="proceed">next</button>
<br><br>
{{ name }} <br>
{{ email }}
</div>
Here is the jQuery
//jQuery
$(function() {
$('#push-email').click(function() {
$('#email').val("john#example.com");
});
});
And here is the vue component
//Vue
var app = new Vue({
el: '#root',
data: {
name: '',
email: '',
},
methods: {
proceed: function () {
}
},
});
https://jsfiddle.net/s3b7f1ah/
The best way if you really are stuck would be to add an event listener in your vue model:
var app = new Vue({
el: '#root',
data: {
name: '',
email: '',
},
methods: {
proceed: function () {
},
foo : function(event){
this.email = event.target.value;
}
},
});
<input #change="foo" type="text" name="email" id="email" v-model="email">
This way, you don't have to modify the jQuery logic.
Updated jsfiddle: https://jsfiddle.net/s3b7f1ah/1/
Change you jquery code to set the model value instead and it will get reflected in the input field.
//jQuery
$(function() {
$('#push-email').click(function() {
app.email = 'john#example.com';
});
});
You could write a directive to handle the jQuery change (as long as jQuery issues one). If jQuery just sets the value without triggering a change event, you'll never see it. Borrowing code from Axnyff:
//Vue
var app = new Vue({
el: '#root',
data: {
name: '',
email: '',
},
methods: {
proceed: function() {
},
foo: function(event) {
this.email = event.target.value;
}
},
directives: {
onJqueryChange: {
bind(el, binding) {
$(el).change(binding.value);
}
}
}
});
//Jquery
$(function() {
$('#push-email').click(function() {
$('#email').val("john#example.com").change();
});
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="push-email">Fill in email</button>
<br>
<br>
<div id="root">
<label for="name">Name</label>
<input type="text" name="name" id="name" v-model="name">
<label for="name">Email</label>
<input v-on-jquery-change="foo" type="text" name="email" id="email" v-model="email">
<br>
<br>
<button #click="proceed">next</button>
<br>
<br> {{ name }}
<br> {{ email }}
</div>

Categories

Resources