Vue email validation is not returning true - javascript

I am really new to Vue and for this project I am using email validation followed by reg on VUE Script Data. When I print out the console.log(this.reg.test(this.email)) , while the user is filling the email input field, it validates correctly as true or false. NEXT button stays disable for both true and false case. Can we make the button enable, once the console.log(this.reg.test(this.email)) is true.
View
<div id="app">
<h2>Todos:</h2>
<input type="email" v-model="email" placeholder="enter email email address"/>
<button v-bind:disabled="isDisableComputed">NEXT</button>
</div>
Script
new Vue({
el: "#app",
data: {
email: '',
reg: /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,24}))$/
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
},
computed: {
isDisableComputed() {
if(this.reg.test(this.email) == 'true'){
console.log(this.reg.test(this.email));
return false;
}
else{
console.log(this.reg.test(this.email));
return true;
}
},
}
})
Below is my code uploaded on JSFIDDLE
https://jsfiddle.net/ujjumaki/9es2dLfz/6/

Look into MDN: RegExp, RegExp.test return boolean, not one string. So this.reg.test(this.email) == 'true' will be always false.
let regex = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,24}))$/
console.log("regex.test('test#test.com') ==> ", regex.test('test#test.com'))
console.log("regex.test('test#test.com')=='true' ==> ", regex.test('test#test.com') == 'true')
console.log("regex.test('test#test.com') ==> ", regex.test('test#test#.com'))
console.log("regex.test('test#test#.com')=='true' ==> ", regex.test('test#test#.com') == 'true')
So uses return !this.reg.test(this.email) instead like the computed property=isDisableComputed in below snippet.
new Vue({
el: "#app",
data () {
return {
email: '',
reg: /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,24}))$/
}
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
},
computed: {
isDisableComputed() {
return !this.reg.test(this.email)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Todos:</h2>
<input type="email" v-model="email" placeholder="enter email email address"/>
<button :disabled="isDisableComputed">NEXT ({{isDisableComputed}})</button>
</div>

Related

Vue form validation

I have some problems with mine Vue app.
I'm trying to validate login form that is connected with my Laravel App.
This is how template looks
<template>
<div>
<div class="main" v-if="canLogin">
<img class="logo" src="../assets/logo.png">
<form id="app"
#submit="checkForm"
method="post">
<p v-if="validation.length">
<b>Please correct the following error(s):</b>
<ul>
<li v-for="validation in validation">{{ error }}</li>
</ul>
</p>
<input class="form-input" type="email" v-model="form.email" id="email" align="center" placeholder="eMail" required>
<input class="form-input" type="password" v-model="form.password" id="password" align="center" placeholder="Password" required>
<button #click.prevent="login" class="submit">Sign In</button>
</form>
</div>
<div class="main" v-if="!canLogin">
<span> YOU ARE BLOCKED FOR 15 MINUTES</span>
</div>
</div>
</template>
As you see I want to foreach errors, but it's always giving error that
'validation' is defined but never used
And this is how mine script looks.
<script>
import User from "../apis/User";
export default {
data() {
return {
form: {
email: "",
password: ""
},
validation: [],
errors: '',
message: '',
canLogin: true,
};
},
mounted() {
User.canLogin().then(response => {
this.canLogin = response.data.canLogin;
});
},
methods: {
checkForm: function (e) {
this.errors = [];
if (!this.form.password) {
this.errors.push("Name required.");
}
if (!this.form.email) {
this.errors.push('Email required.');
} else if (!this.validEmail(this.email)) {
this.errors.push('Valid email required.');
}
if (!this.errors.length) {
return true;
}
e.preventDefault();
},
validEmail: function (email) {
var re = /^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
},
login() {
User.login(this.form)
.then(response => {
this.$store.commit("LOGIN", true);
localStorage.setItem("token", response.data.token);
this.$router.push({ name: "Dashboard" });
this.$snotify.success(response.data.message, {
timeout: 2000,
showProgressBar: true,
closeOnClick: true,
pauseOnHover: true
});
})
.catch(error => {
if (error.response.status === 400) {
this.errors = error.response.data.message;
this.$snotify.error(error.response.data.message, {
timeout: 2000,
showProgressBar: true,
closeOnClick: true,
pauseOnHover: true
});
}
if(error.response.status === 429){
this.canLogin = false;
}
});
}
}
};
</script>
I'm catching few thhings, like, canLogin, this is checking if IP is not blocked.
There is one more error like:
Elements in iteration expect to have 'v-bind:key' directives
I'm just a started with vue so don't judge me if it's simple fix.
BTW: without validation works fine, I believe it's not only problem with those errors and probbly I'm not catching some things as needed.
What am I doing wrong here?
Change
<ul>
<li v-for="validation in validation">{{ error }}</li>
</ul>
To:
<ul>
<li v-for="(error,index) in errors" v-bind:key="index">{{ error }}</li>
</ul>
In vue, you must provide a key for every v-for looping.
And change your data to:
data() {
return {
form: {
email: "",
password: ""
},
validation: [],
errors: [],
message: '',
canLogin: true,
};
},
I made your errors variable an arrayList.

Apply mask to input

I need a mask for input that needs to have the format of dddd-ddd (Portuguse zip code), I don't feel like importing a library just for this input.
This is what I have right now:
new Vue({
el: '#app',
data: {
zip_code: '2770-315'
},
computed: {
mask_zip_code: {
get: function() {
return this.zip_code;
},
set: function(input) {
input = input.replace(/[^0-9-]/g, "");
if(input.length >= 4) {
input = input.substr(0, 4)+'-'+input.substr(5); // in case people type "-"
}
this.zip_code = input;
}
}
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<input v-model="mask_zip_code" maxlength="8">
</div>
Has you can see the behavior is a little wierd and it allows to type letters as well.
I've updated your snippet to work as you intended it. The computed value works but it will not be reflected in the input, instead a method is more appropriate here
new Vue({
el: '#app',
data: {
zip_code: '2770-315'
},
methods: {
mask_zip: function(event) {
if (event.key && event.key.match(/[a-zA-Z]/)) {
event.preventDefault()
} else {
if(this.zip_code.length >= 4) {
this.zip_code = this.zip_code.substr(0, 4)+'-'+this.zip_code.substr(5); // in case people type "-"
}
}
return this.zip_code;
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<input v-model="mask_zip_code" maxlength="8" #keypress="inputValidation">
{{mask_zip_code}}
</div>
Try using the pattern attribute with a regex:
<script src="https://unpkg.com/vue"></script>
<form>
<input v-model="mask_zip_code" pattern="[0-9]{4}-[0-9]{3}">
<button>Submit</button>
</form>
This should prevent users from submitting the form with anything other than a valid Portuguese zip code.

Custom component , error compiling template

What am I doing wrong here with my custom component?
What I want is to have:
label
input
Why is idfor undefined? Why do I get this error on labeltext
invalid expression: Unexpected identifier in "Name of superhero"
labeltext is supposed to be a string and I should be able to pass in any string I like?
This is what I have so far. jsfiddle
Vue.component("base-input", {
props: {
value: {
type: String,
required: true
},
idfor: {
type: String,
required: true
},
labeltext: {
type: String,
required: true
}
},
template:
`
<div>
<label for="idfor">{{labeltext}}</label>
<input type="text" id="idfor" v-bind:value="value" v-on:input="$emit('input', $event.target.value)">
</div>
`
});
Vue.config.devtools = true;
new Vue({
el: "#app",
data() {
return {
user: {
name: "Hulk",
age: 42
}
};
}
});
HTML
<div id="app">
<base-input v-bind:idfor="name" v-bind:value="user.name" v-bind:labeltext="Name of superhero"/>
</div>
there's one problem, you just have to make sure you are including '' for literals
<div id="app">
<base-input v-bind:idfor="'name'" v-bind:value="user.name" v-bind:labeltext="'Name of superhero'"/>
This is because v-bind:labeltext= evaluates the value as an expression. And if you need to pass an string then you need to wrap it in quotes like
v-bind:labeltext="'Name of superhero'"
Updated fiddle

Prompt before leaving page with vee-validate

Trying to set up a basic "Are you sure you want to leave this page" type prompt on a page containing a simple html form.
Form:
<!DOCTYPE html>
<html>
<head></head>
<body>
<div id="app">
<form id="webform" action='#' method='POST' #submit.prevent="doSubmit()">
<input v-validate="'required'" :class="{'input': true, 'is-danger': errors.has('cust_name_first') }" name="cust_name_first" type="text">
<span v-show="errors.has('cust_name_first')" class="help is-danger">{{ errors.first('cust_name_first') }}</span>
</form>
</div>
<!-- div id app -->
</body>
</html>
And the javascript:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vee-validate/2.0.9/vee-validate.min.js"></script>
<script>
formsubmitval = 1;
Vue.use(VeeValidate);
new Vue({
el: "#app",
template: '#app',
data() {
return {
cust_name_first: null,
cust_id: null,
sales_name_first: null,
};
},
methods: {
doSubmit() {
this.$validator.validateAll().then(function(result){
if (!result){
//this means a validation failed, so exit without doing anything
return;
}
//here you would put your form submit stuff
formsubmitval=0;
document.getElementById('webform').submit();
});
}
}
});
if (formsubmitval==1)
{
window.onbeforeunload = function(e) {
e = e || window.event;
e.preventDefault = true;
e.cancelBubble = true;
e.returnValue = 'test';
}
}
</script>
The problem is that I'm not being prompted to leave the page, and any user entered data is lost. What am I doing wrong with the script above?
I was making this more difficult than it needed to be. Just needed to add onbeforeunload event, and then set it to null when sumbmitting. Works a treat.
Updated javascript:
<script>
window.onbeforeunload = function() {
return true;
};
Vue.use(VeeValidate);
new Vue({
el: "#app",
template: '#app',
data() {
return {
cust_name_first: null,
cust_id: null,
sales_name_first: null,
};
},
methods: {
doSubmit() {
this.$validator.validateAll().then(function(result){
if (!result){
//this means a validation failed, so exit without doing anything
return;
}
//here you would put your form submit stuff
window.onbeforeunload = null;
document.getElementById('webform').submit();
});
}
}
});
</script>

Passing Parent Function to Child Component in VueJS

I'm having my practice in VueJS 1.0 and I am learning about Components.
in this example, there is an input element and has to supply coupon or some kind of a code from an API. and I have to validate. I have my <coupon > component and has props of when-applied. The when-applied must call the parent function setCoupon but it won't.
I only got this error this.whenApplied is not a function.
<div id="demo" class="list-group">
<script id="coupon-template" type="x-template">
<input type="text" v-model="coupon" v-on:blur="whenCouponHasBeenEntered">
<div v-text="text"></div>
</script>
<coupon when-applied="setCoupon"></coupon>
</div>
Here is my app.js file
Vue.component('coupon', {
template: '#coupon-template',
props: ['whenApplied'],
data: function() {
return {
coupon: '',
invalid: false,
text: ''
}
},
methods: {
whenCouponHasBeenEntered: function() {
this.validate();
},
validate: function() {
if( this.coupon == 'FOOBAR') {
this.whenApplied(this.coupon);
return this.text = '20% OFF!!';
}
return this.text = 'that coupon doesn`t exists';
}
}
});
new Vue({
el: '#demo',
methods: {
setCoupon: function(coupon) {
alert('set coupon'+ coupon);
}
}
});
Someone pls help. Suggestions pretty much appreciated.
You should bind the property:
<coupon v-bind:when-applied="setCoupon"></coupon>
or you could use the shorthand syntax for v-bind:
<coupon :when-applied="setCoupon"></coupon>
Read more about the props here.

Categories