I'm trying to add some validations with Vuelidate to a login form. When I leave the username field blank, I'm expecting to see a warning displayed saying "Name is required", but nothing is showing up.
It's not progressing to the next step (which is what I want), so I'm assuming that the validation is working, I'm just not getting the message displayed on the screen. I ran it in debug mode and I'm not getting any errors, is there something I've done wrong?
<template>
<div>
<h3>Sign in</h3>
<div class="row" v-if="errorMessage">
<div class="alert alert-danger"><p>{{ errorMessage }}</p></div>
</div>
<div class="row" v-if="successMessage">
<div class="alert alert-success"><p>{{ successMessage }}</p></div>
</div>
<form #submit.prevent="OnLogin">
<div class="form-group">
<label for="userSigninLogin">Email</label>
<input name="username" type="text"
class="form-control"
:class="{ 'is-invalid': submitted && $v.apiRequest.username.$error }"
placeholder="Enter your email" v-model="apiRequest.username">
</div>
<div class="form-group">
<label for="userSigninPassword">Password</label>
<input name="password" type="password"
class="form-control" id="userSigninPassword"
placeholder="Enter your password" v-model="apiRequest.password">
</div>
<button type="submit" class="btn btn-primary">Sign in</button>
<div v-if="submitted" && !$v.apiRequest.username.required
class="alert alert-danger"><p>Name is required</p></div>
<div class="row" v-if="submitted" && !$v.apiRequest.username.required>
<div class="alert alert-danger"><p>Name is required</p></div>
</div>
</form>
</div>
</template>
<script>
import { required, minLength } from 'vuelidate/lib/validators';
export default {
data() {
return {
apiRequest: new this.$request({
username: '',
password: '',
}),
errorMessage: '',
successMessage: '',
submitted: false,
};
},
validations: {
apiRequest: {
username: {
required,
minLength: minLength(2),
},
},
},
methods: {
OnLogin() {
this.submitted = true;
this.apiRequest.addStore(this.$store);
this.apiRequest.post('login')
.then((response) => {
this.successMessage = response;
this.errorMessage = '';
})
.catch((errors) => {
this.errorMessage = errors;
this.successMessage = '';
});
},
},
};
</script>
Follow the steps it helps you to resolve your issue. You forgot to add validation on button click and also there is template error in displaying error message.
Step 1: HTML template
<div id="app">
<h3>Sign in</h3>
<div class="row" v-if="errorMessage">
<div class="alert alert-danger">
<p>{{ errorMessage }}</p>
</div>
</div>
<div class="row" v-if="successMessage">
<div class="alert alert-success">
<p>{{ successMessage }}</p>
</div>
</div>
<form #submit.prevent="OnLogin">
<div class="form-group">
<label for="userSigninLogin">Email</label>
<input name="username"
type="text" class="form-control" :class="{ 'is-invalid': submitted && $v.apiRequest.username.$error }"
placeholder="Enter your email" v-model="apiRequest.username" />
<div v-if="submitted && $v.apiRequest.username.$error" class="alert alert-danger">
<span v-if="!$v.apiRequest.username.required">Username is Required</span>
<span v-if="!$v.apiRequest.username.minLength">Enter Minimum 6 character</span>
<span v-if="$v.apiRequest.username.minLength && !$v.apiRequest.username.email">Enter Valid Email address</span>
</div>
</div>
<div class="form-group">
<label for="userSigninPassword">Password</label>
<input name="password" type="password" class="form-control"
id="userSigninPassword" placeholder="Enter your password" v-model="apiRequest.password" />
<div class="row" v-if="submitted && !$v.apiRequest.password.required">
<span class="alert alert-danger">Password is required</span>
</div>
</div>
<button type="submit" class="btn btn-primary">Sign in</button>
</form>
</div>
Step 2: Initalize your modal data
data() {
return {
apiRequest: {
username: "",
password: "",
},
errorMessage: "",
successMessage: "",
submitted: false,
};
},
Step 3: Add validations rule
validations: {
apiRequest: {
username: {
required,
minLength: minLength(6),
email,
},
password: { required },
},
},
Step 4: Add form submit method
methods: {
OnLogin() {
this.submitted = true;
this.$v.$touch();
if (this.$v.$invalid) {
return; // stop here if form is invalid
}
this.apiRequest
.post("login")
.then((response) => {
this.successMessage = response;
this.errorMessage = "";
})
.catch((errors) => {
this.errorMessage = errors;
this.successMessage = "";
});
},
},
DEMO
Related
I am very noob in vuejs. I am trying to create vuejs form with validation. But in browser its showing nothing. In console there showing Process is not define.
This is the console error image :
<script>
import { required, email, minLength } from 'vuelidate/lib/validators'
export function validName(name) {
let validNamePattern = new RegExp("^[a-zA-Z]+(?:[-'\\s][a-zA-Z]+)*$");
if (validNamePattern.test(name)){
return true;
}
return false;
}
export default {
setup () {
return { v$: useVuelidate() }
},
data() {
return {
form: {
firstName: '',
lastName: '',
email: '',
password: '',
confirmPassword: '',
}
}
},
validations() {
return {
form: {
firstName: {
required, name_validation: {
$validator: validName,
$message: 'Invalid Name. Valid name only contain letters, dashes (-) and spaces'
}
},
lastName: {
required, name_validation: {
$validator: validName,
$message: 'Invalid Name. Valid name only contain letters, dashes (-) and spaces'
}
},
email: { required, email },
password: { required, min: minLength(6) },
confirmPassword: { required }
},
}
},
}
</script>
<template>
<form #submit.prevent="onSubmit">
<!-- First and Last Name Row -->
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for=""> First Name:</label><input class="form-control" placeholder="Enter first name" type="text" v-model="v$.form.firstName.$model">
<div class="pre-icon os-icon os-icon-user-male-circle"></div>
<!-- Error Message -->
<div class="input-errors" v-for="(error, index) of v$.form.firstName.$errors" :key="index">
<div class="error-msg">{{ error.$message }}</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="">Last Name:</label><input class="form-control" placeholder="Enter last name" type="text" v-model="v$.form.lastName.$model">
<!-- Error Message -->
<div class="input-errors" v-for="(error, index) of v$.form.lastName.$errors" :key="index">
<div class="error-msg">{{ error.$message }}</div>
</div>
</div>
</div>
</div>
<!-- Email Row -->
<div class="form-group">
<label for=""> Email address</label><input class="form-control" placeholder="Enter email" type="email" v-model="v$.form.email.$model">
<div class="pre-icon os-icon os-icon-email-2-at2"></div>
<!-- Error Message -->
<div class="input-errors" v-for="(error, index) of v$.form.email.$errors" :key="index">
<div class="error-msg">{{ error.$message }}</div>
</div>
</div>
<!-- Password and Confirm Password Row -->
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for=""> Password</label><input class="form-control" placeholder="Password" type="password" v-model="v$.form.password.$model">
<div class="pre-icon os-icon os-icon-fingerprint"></div>
<!-- Error Message -->
<div class="input-errors" v-for="(error, index) of v$.form.password.$errors" :key="index">
<div class="error-msg">{{ error.$message }}</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="">Confirm Password</label><input #input="checkPassword()" class="form-control" placeholder="Confirm Password" type="password" v-model="v$.form.confirmPassword.$model">
<!-- Error Message -->
<div class="input-errors" v-for="(error, index) of v$.form.confirmPassword.$errors" :key="index">
<div class="error-msg">{{ error.$message }}</div>
</div>
</div>
</div>
</div>
<!-- Submit Button -->
<div class="buttons-w">
<button class="btn btn-primary" :disabled="v$.form.$invalid" style="margin-left:120px">Signup</button>
</div>
</form>
</template>
I am trying to make form and validation also. But when I am running code it's showing nothing and in console telling process is not Define.
I saw that you are using useVuelidate(), but you didn't import it:
import { required, email, minLength } from 'vuelidate/lib/validators'
export function validName(name) {
...
setup () {
return { v$: useVuelidate() }
},
...
You need to add this import as well:
import useVuelidate from '#vuelidate/core'
The way you imported vuelidate is different from what Vuelidate documentation says. try to substitute the line below:
import { required, email, minLength } from 'vuelidate/lib/validators'
With this one:
import { required, email, minLength } from '#vuelidate/validators'
import useVuelidate from '#vuelidate/core'
This will probably removes the error. I recommend to read documentation with more details.
I am trying to do customer login with Vue .
I have tried to do something and received respone 200 and 302 still but not working. I also tried this way : http://web.archive.org/web/20150417052042/http://inside.sauce.ly:80/how-to-build-an-ajax-login-form-...
but same .
let productForm = new Vue({
el:".vue-login-form",
data(){
return{
form: {
email: null,
password: null,
},
customerData: null,
}
},
methods:{
login(){
axios.post('/account/login', this.form )
.then((response) => {
console.log(response);
this.customerData = response.data;
})
.catch(function (error){
});
},
},
})
<form action="">
<div class="form-top">
<h2>Welcome Back!</h2>
<p>Please login to your account.</p>
</div>
<div class="login-fields">
<div class="input">
<input type="email" v-model="form.email" placeholder="Email address">
</div>
<div class="input mb-0">
<input type="password" v-model="form.password" placeholder="Password">
</div>
<div class="forgot-pass">Forgot Password?</div>
<div class="submit-button">
<button type="button" #Click="login()">Log In</button>
</div>
</div>
</form>
I developed one page which is responsible for displaying cart items and the response is coming from backend upto this it's working fine .Now inside same page one more registration page is there and that also integrated with backend API, after successfully registered it should be redirected to /orderSuccess page but it's not redirecting ,Here what is the issue please help me How to fix this issue.
After registered it changes my url path /cart to /ordersuccess also but page is not displaying..please help me to fix this issue
Cart.vue
<template>
<div class="main">
<div class="first-section">
<div class="content">
<h5>My Cart({{books.length}})</h5>
</div>
<div v-for="book in books" :key="book.id" class="container">
<div class="mid-section">
<img v-bind:src="book.file" alt="not found">
<p class="title-section">{{book.name}}</p>
</div>
<div class="author-section">
<p class="author-name">by {{book.author}}</p>
</div>
<div class="price-section">
<h6>Rs.{{book.price}}</h6>
</div>
<div class="icons">
<i class="fas fa-minus-circle"></i>
<input class="rectangle" value=1>
<i class="fas fa-plus-circle"></i>
</div>
</div>
<div class="btn-grps">
<button class="btn" v-on:click="flip()" v-if="hide==true" type="submit">Place Order</button>
</div>
</div>
<div class="second -section">
<div class="details-box">
<input type="text" v-if="hide==true" class="initial-btn" placeholder="Customer Details" />
</div>
<div v-if="hide==false" class="fill-details">
<form #submit.prevent="" class="address">
<h4 class="heading">Customer Details</h4>
<div class="name">
<input type="name" required pattern="[A-Za-z]{3,10}" v-model="name">
<label class="label">Name</label>
</div>
<div class="name">
<input type="text" required v-model="phoneNumber">
<label class="label">Phone Number</label>
</div>
<div class="pin">
<input type="text" required v-model="pincode">
<label class="label">PinCode</label>
</div>
<div class="pin">
<input type="text" required v-model="locality">
<label class="label">Locality</label>
</div>
<div class="address-block">
<input class="address" type="text" required v-model="address">
<label id="Add" class="label">Address</label>
</div>
<div class="city-landMark">
<input type="text" required v-model="city">
<label class="label">City/Town</label>
</div>
<div class="city-landMark">
<input type="text" required v-model="landmark">
<label class="label">LandMark</label>
</div>
<div class="Radio-Buttons">
<p>Type</p>
<div class="radio-btns flex-container">
<div>
<input type="radio" id="Home" value="Home" name="type" v-model="type">
<div class="first-radio"> <label class="home" for="Home">Home</label></div>
</div>
<div>
<input class="work-round" type="radio" id="Work" value="Work" name="type" v-model="type">
<div class="second-radio"> <label for="Work" class="work-label">Work</label></div>
</div>
<div>
<input class="other-round" type="radio" id="Other" value="Other" name="type" v-model="type">
<div class="third-radio"><label for="Other">Other</label></div>
</div>
</div>
<div class="btn-continue">
<button type="submit" #click="handlesubmit();" class="continue">continue</button>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import service from '../service/User'
export default {
beforeMount() {
// if (localStorage.getItem("reloaded")) {
// localStorage.removeItem("reloaded");
// } else {
// localStorage.setItem("reloaded", "1");
// location.reload();
// }
service.userDisplayCart().then(response => {
this.books = response.data;
})
},
data() {
return {
flag: true,
hide: true,
booksCount: 0,
name: '',
phoneNumber: '',
pincode: '',
locality: '',
city: '',
address: '',
landmark: '',
type: '',
books: []
}
},
methods: {
flip() {
this.hide = !this.hide;
},
Togglebtn() {
this.flag = !this.flag;
},
handlesubmit() {
let userData = {
name: this.name,
phoneNumber: this.phoneNumber,
pincode: this.pincode,
locality: this.locality,
city: this.city,
address: this.address,
landmark: this.landmark,
type: this.type,
}
service.customerRegister(userData).then(response => {
alert("user registered successfully");
this.$router.push('/ordersuccess');
return response;
})
}
}
}
</script>
<style lang="scss" scoped>
#import "#/styles/Cart.scss";
</style>
router.js
{
path:'/dashboard',
component:Dashboard,
children:[{
path:'/displaybooks',
component:DisplayBooks
},
{
path:'/sortLowtoHigh',
component:sortBooksLowtoHigh
},
{
path:'/sortHightoLow',
component:sortBooksHightoLow
},
{
path:'/cart',
component:Cart
},
{
path:'/ordersuccess',
component:OrderPlace
},
]
}
You can use the history mode on your router settings. This should fix the issue
const routes = {
path: 'Dashboard',
....
}
new VueRouter({routes, mode: 'history'});
this.$router.push({ path: '/ordersuccess' })
https://router.vuejs.org/guide/essentials/navigation.html
I created a Vue component that has several forms that can be submitted by the user. On submit, the form will send some data to my backend. The problem is that my backend needs to know which form was submitted, and this input doesn't depend on the user, so I added a hidden input so that when the user send the data, my backend can also know which type of form was submitted. I tried the following:
<template>
<div>
<div v-if="order=='total'">
<form #submit="formSubmit">
<input type="hidden" v-model="order_type" value="form1">
<input type="text" class="form-control" v-model="amount">
<br>
<input type="text" class="form-control" v-model="price">
<br>
<button class="btn btn-primary">BUY</button>
</form>
</div>
<div v-else-if="order=='partial'">
<input type="hidden" v-model="order_type" value="form2">
<input type="text" class="form-control" v-model="amount">
<br>
<input type="text" class="form-control" v-model="price">
<br>
<button class="btn btn-primary">BUY</button>
</form>
</div>
<br>
</div>
</template>
<script>
import axios from 'axios'
export default {
props:{
order:{
type:String,
default:'total'
},
},
mounted() {
console.log('Component mounted.')
},
data() {
return {
name: '',
description: '',
output: ''
};
},
methods: {
formSubmit(e) {
e.preventDefault();
let currentObj = this;
axios.post('MYURL', {
order_type: this.order_type,
price: this.price,
amount: this.amount
})
.then(function (response) {
currentObj.output = response.data;
})
.catch(function (error) {
currentObj.output = error;
});
}
}
}
</script>
The problem with this code is that order_type doesn't get sent with the form. I have read somewhere that Vue doesn't allow hidden values, so is there any other way to do this?
You can pass a param to the method:
#submit.prevent="formSubmit("form1")"
And in the method:
formSubmit(value) {
let currentObj = this;
axios
.post("MYURL", {
price: this.price,
amount: this.amount,
order_type: value
})
.then(function(response) {
currentObj.output = response.data;
})
.catch(function(error) {
currentObj.output = error;
});
},
Your template becomes:
<template>
<div>
<div v-if="order=='total'">
<form #submit.prevent="formSubmit("form1")">
<input type="text" class="form-control" v-model="amount">
<br>
<input type="text" class="form-control" v-model="price">
<br>
<button class="btn btn-primary" type="submit">BUY</button>
</form>
</div>
<div v-else-if="order=='partial'">
<form #submit.prevent="formSubmit("form2")">
<input type="text" class="form-control" v-model="amount">
<br>
<input type="text" class="form-control" v-model="price">
<br>
<button class="btn btn-primary" type="submit">BUY</button>
</form>
</div>
<br>
</div>
</template>
SOLUTION 2
To avoid duplication you could also set a computed property:
orderType(){
if (this.order === "total") {
return "form1"
} else if (this.order === "partial") {
return "form2"
} else {
return null
}
With that in place you can simplify the template by removing the conditional and not needing to pass anything to the method:
<template>
<div>
<form #submit.prevent="formSubmit()">
<input type="text" class="form-control" v-model="amount" />
<br />
<input type="text" class="form-control" v-model="price" />
<br />
<button class="btn btn-primary" type="submit">BUY</button>
</form>
</div>
</template>
And in the method the value of order_type is calculated in the computed property:
formSubmit() {
let currentObj = this;
axios
.post("MYURL", {
price: this.price,
amount: this.amount,
order_type: this.orderType
})
.then(function(response) {
currentObj.output = response.data;
})
.catch(function(error) {
currentObj.output = error;
});
},
I can insert data into database but i cannot see my data i.e data fields are empty in database form is sending empty data to database can anybody solve this i am also getting this error-> [Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'preventDefault' of undefined".
but still, the form is sending data to database (empty data)
here's my code
<template>
<b-container>
<div class="update-info">
<div class="feature-text myinv-title">
<h5 class="title title-sm">Update your information</h5>
</div>
<form id="app" #submit.prevent="saveUser" method="post" novalidate="true">
<p v-if="errors.length">
<b>Please fill in all the fields</b>
<ul>
<li v-for="error in errors" class="alert alert-danger">{{ error }}</li>
</ul>
</p>
<div class="form-row">
<div class="form-group col-md-3">
<label for="trx">TRX Address No.</label>
<input
id="trx"
class="form-control trx-address-nooverflow"
type="text"
name="TRX Address"
readonly
>
</div>
<div class="form-group col-md-3">
<label for="name">Name</label>
<input
id="name"
class="form-control"
v-model="name"
type="text"
name="name"
>
</div>
<div class="form-group col-md-3">
<label for="name">Country</label>
<country-select
id="Country"
class="form-control"
v-model="country"
:country="country"
topCountry="US" />
</div>
<div class="form-group col-md-3">
<label for="email">Email ID</label>
<input
id="email"
class="form-control"
v-model="email"
type="email"
name="email"
>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-3">
<label for="email">Mobile No</label>
<input
id="mobile"
class="form-control"
v-model="mobile_no"
type="text"
name="mobile"
>
</div>
<div class="form-group col-md-3">
<div class="top-30">
<input type="submit" class="btn btn-btn btn-grad btn-submit" />
</div>
</div>
<div class="clearfix"></div>
</div>
</form>
</div>
</b-container>
</template>
this is my script
<script>
import axios from 'axios'
export default{
data(){
return{
errorMessage: "",
successMessage: "",
errors: [],
trx_no: "",
name: "",
country: "",
email: "",
mobile_no: "",
myAddress: "",
newUser: {trx_no: "", name: "", country: "", email: "", mobile_no: ""}
}
},
mounted: function(){
this.getAllUsers();
},
methods: {
getAllUsers: function(){
axios.get('http://localhost:8888/vue-and-php/public/api/update-info-form.php?action=read', { crossdomain: true })
.then((response) => {
if(response.data.error){
this.errorMessage = response.data.message;
}else{
this.newUser = response.data.newUser;
}
});
},
saveUser(event){
this.checkForm()
if(!this.errors.length) {
var formData = this.toFormData(this.newUser);
axios.post('http://localhost:8888/vue-and-php/public/api/update-info-form.php?action=update', formData, { crossdomain: true })
.then((response) => {
this.newUser = {trx_no: "", name: "", country: "", email: "", mobile_no: ""};
if(response.data.error){
this.errorMessage = response.data.message;
}else{
this.getAllUsers();
}
});
}
},
toFormData: function(obj){
var form_data = new FormData();
for(var key in obj){
form_data.append(key, obj[key]);
}
return form_data;
},
clearMessage: function(){
this.errorMessage = "";
this.successMessage = "";
},
//validation
checkForm: function (e) {
this.errors = [];
if (!this.name) {
this.errors.push("Name Required.");
}
if (!this.country) {
this.errors.push("Country Required.");
}
if (!this.email) {
this.errors.push('Email Required.');
} else if (!this.validEmail(this.email)) {
this.errors.push('Valid Email Address Required.');
}
if (!this.mobile_no) {
this.errors.push("Phone Number 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);
}
}
}
</script>