I using Vue3.0 and also use Vee-validate to validate my form. But I don't know why it keep showing blank page just like in this picture
I already do what they said in the documentations, here's my code
<form class="wrap" id="signup-form col-lg-5" #submit.prevent="processForm">
<div class="row mb-5">
<router-link :to="{'name': 'Home'}">
<span class="iconify" data-icon="ion:return-up-back-outline" data-width="25" data-height="25"></span>
<button class="btn">Back</button>
</router-link>
</div>
<!-- full name -->
<div class="form-group row">
<label for="name">Full Name <span class="text-danger">*</span></label>
<ValidationProvider rules="positive|odd" v-slot="err">
<input type="text" class="form-control" v-model.trim="name">
<span>{{ err.errors[0] }}</span>
</ValidationProvider>
</div>
<!-- submit button -->
<div class="row d-flex align-items-center">
<button type="submit" class="btn btn-outline-dark col-sm-4">Submit</button>
<p style="cursor:pointer;" class="col-sm-7">
<router-link :to="{name:'Login'}">Has an account? Login</router-link>
</p>
</div>
</form>
And here's my script
<script>
import { ValidationProvider } from 'vee-validate';
import { extend } from 'vee-validate';
extend('odd', value => {
return value % 2 !== 0;
});
extend('positive', value => {
return value >= 0;
});
export default {
name: 'RegisterForm',
components: {
ValidationProvider
},
data: function(){
return{
name: '',
}
},
methods: {
processForm() {
this.$emit('form-submit',
{
'name': this.email,
'password': this.password,
})
}
}
}
</script>
What should I change from the code? By the way, Is Vee-Validator should be assigned in main.js?
Looks like you are using vee-validate v3.x, it isn't compatible with Vue 3
vee-validate v4 was released recently that supports Vue 3, but with a completely different API
https://vee-validate.logaretm.com/v4/
Related
I have a dropdown list "functions" that is filled with database entries and a dropdown list with 2 hardcoded entries. When the vue website is opened the dropdown list remains empty but as soon as I change the value of the other dropdown field the desired data from the database is available.
I'm a bit confused because I expected that adding "retrieveFunctions()" into the mounted() function would trigger the v-for, and even more confused that changing something in another select field suddenly triggers it.
The HTML code:
<template>
<div class="submit-form">
<div v-if="!submitted">
<div class="row">
<div class="col-sm-12">
<p><a style="width:500px" class="btn btn-info" data-toggle="collapse" href="#generalInformation" role="button" aria-expanded="true" >
General Information</a></p>
<div class="collaps show" id="generalInformation">
<!-- NAME -->
<div class="form-group">
<input placeholder="Name" type="text" class="form-control"
id="name" required v-model="component.name" name="name">
</div>
<!-- DOMAIN -->
<div class="input-group mb-3">
<div class="input-group-prepend">
<label style="width:100px" class="input-group-text" for="inputGroupDomain">Domain</label>
</div>
<select v-model="component.domain"
class="custom-select"
id="inputGroupDomain"
>
<option value="Power System">Power System</option>
<option value="ICT">ICT</option>
</select>
</div>
<!-- FUNCTION -->
<div class="input-group mb-3">
<div class="input-group-prepend">
<label style="width:100px" class="input-group-text" for="inputGroupFunction">Functions</label>
</div>
<select v-model="_function" class="custom-select" id="inputGroupFunction">
<option :class="{ active: index == currentIndex }"
v-for="(_function, index) in functions"
:key="index"
value= _function.name>
{{ _function.name }}
</option>
</select>
</div>
</div>
<p>
<button #click="saveComponent" class="btn btn-success">Add Component</button>
</p>
</div>
</div>
</div>
<div v-else>
<h4>Component was added succesfully!</h4>
<button class="btn btn-success" #click="newComponent">Proceed</button>
</div>
The script part:
<script>
import FunctionDataService from "../services/FunctionDataService";
export default {
name: "add-component",
data() {
return {
component: {
id: null,
name: "",
type: "",
domain: "",
},
submitted: false
};
},
methods: {
retrieveFunctions() {
FunctionDataService.getAll()
.then(response => {
this.functions = response.data;
console.log(response.data);
})
.catch(e => {
console.log(e);
});
},
refreshList() {
this.retrieveFunctions();
},
},
mounted() {
this.retrieveFunctions();
}
};
</script>
refreshList() {
this.retrieveFunctions();
},
},
mounted() {
this.retrieveFunctions();
}
};
</script>
State in the beginning: Dropdown list empty
State after selecting something in the upper dropdown list: Database entries are visible and correct
You need to initiate all responsive properties on the data return object with either a value (empty string, array, object, etc) or null. Currently it's missing the _function attribute used in the select v-model and the functions array used in the v-for. You can try to change the data to the following:
data() {
return {
_function: "",
functions: [],
component: {
id: null,
name: "",
type: "",
domain: "",
},
submitted: false
};
},
I have a component that is a form that I input a name and it updates a value on a field on the backend based on which input the name is. Right now I have two inputs (host and scout) and they work fine if I just fill one input. My problem is, when I fill both inputs, the name on the host input will always get updated twice while the name on the scout field will work just fine. Not sure if I was clear enough.
Here is the code for the component so far
<template>
<div class="add-wave">
<h3>Add Wave</h3>
<div class="row">
<form #click.prevent="addwave()" class="col s12">
<div class="row">
<div class="input-field col s12">
<input type="text" v-model="host" />
<label class="active">Host</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input type="text" v-model="scout" />
<label class="active">Scout</label>
</div>
</div>
<button type="submit" class="btn">Submit</button>
<router-link to="/member" class="btn grey">Cancel</router-link>
</form>
</div>
</div>
</template>
<script>
import { db, fv } from "../data/firebaseInit";
export default {
data() {
return {
host: null,
scout: null
};
},
methods: {
addwave() {
this.addhost();
db.collection("members")
.where("name", "==", this.scout)
.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
doc.ref.update({
scout: fv.increment(1),
total: fv.increment(1)
});
});
});
},
addhost() {
db.collection("members")
.where("name", "==", this.host)
.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
doc.ref.update({
host: fv.increment(1),
total: fv.increment(1)
});
});
});
}
}
};
</script>
I'm not sure why is it updating twice only when I fill both input fields.
I'm asking if we have similar attribute as standalone in vuejs.
I want to add items in certifications.
Here is the button add :
<l-button #click="Add()"><i class="fa fa-plus"> </i></l-button>
The add function:
Add() {
this.certifications.push( item);
this.newItemAdded = true
},
<div v-for="(item,index) in certifications">
<fg-input type="text" required
:label="$t('candidate.certification.title')"
:placeholder="$t('candidate.certification.title')"
:disabled="disableIt && !newItemAdded ">
</fg-input>
</div>
My problem is that when i add new item, the previous input also is enabled.
I want to know if there is somathing similar to standalone( like angular) in vuejs.
You must use the index and length of certifications
<div v-for="(item,index) in certifications">
<fg-input type="text" required
:label="$t('candidate.certification.title')"
:placeholder="$t('candidate.certification.title')"
:disabled="(index+1!==certifications.length)">
</fg-input>
</div>
and when you need edit button:
data() {
return {
certifications: [],
editableIndex: null
}
},
methods: {
Add() {
...
},
Edit(index) {
this.editableIndex = index
},
}
}
and in template
<template>
<div>
<div v-for="(item,index) in certifications">
<fg-input type="text" required
:label="$t('candidate.certification.title')"
:placeholder="$t('candidate.certification.title')"
:disabled="(index+1!==certifications.length&&editableIndex===null) || editableIndex===index">
</fg-input>
<l-button #click="Edit(index)"><i class="fa fa-pen"> </i></l-button>
</div>
<l-button #click="Add()"><i class="fa fa-plus"> </i></l-button>
</div>
</template>
I have an input-component which has a form which collects start and finish times, job number and a select option.
This is attached to a data property with v-model.
This is then emitted with Event.$emit('addedData', this.hours)
In the display-component the Event.$on takes this data and checks an attribute and based on the check adds it to another data property (array) with this.todays_hours.push().
The template then displays this reactively using v-for in the template.
To this point all works fine. However when I then attempt to add another line of hours the hours already displayed change reactively with the input.
As my input-component also posts to a database with axios if I reload the page all is displayed correctly.
input-component
<template>
<div>
<div class="row">
<div class="col-2">
<input hidden="" v-model="hours.day">
</div>
<div class="col-2" >
<input type="time" v-model="hours.start">
</div>
<div class="col-2" >
<input type="time" v-model="hours.finish">
</div>
<div class="col-2" >
<input type="number" v-model="hours.job_number">
</div>
<div class="col-2" >
<select v-model="hours.climbing">
<option selected="selected" value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
<div class="col-2" >
<button #click="onSave" class="btn-success btn-sm">Save</button>
</div>
</div>
<hr>
</div>
</template>
<script>
export default {
name: 'InputHoursComponent',
props: ['employeeId', 'dayCheck', 'weekEnding'],
data() {
return {
hours: {
start: "",
finish: "",
job_number: "",
climbing: 0,
day: this.dayCheck
},
climbing_select: ['No', 'Yes'],
}
},
methods: {
onSave()
{
axios.post('/payroll', {
employee_id: this.employeeId,
week_ending: this.weekEnding,
start: this.hours.start,
finish: this.hours.finish,
job_number: this.hours.job_number,
climbing: this.hours.climbing,
day: this.dayCheck
})
.then(response => {})
.catch(e => {this.errors.push(e)});
let data = this.normalizeProp(this.hours, s, true)
Event.$emit('onAddedEntry', data);
console.log("passed data:", this.hours);
}
}
}
</script>
display-component
<template>
<div>
<div v-for="item in todays_hours">
<div class="row">
<div class="col-2">
<div hidden="" ></div>
</div>
<div class="col-2" >
<div v-text="item.start"></div>
</div>
<div class="col-2" >
<div v-text="item.finish"></div>
</div>
<div class="col-2" >
<div v-text="item.job_number"></div>
</div>
<div class="col-2" >
<div v-text="(item.climbing)?'Yes':'No'"></div>
</div>
<div class="col-2" >
<button #click="onEdit" class="btn-warning btn-sm mb-1">Edit</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'DisplayHoursComponent',
props: ['dayCheck', 'hoursWorked'],
data() {
return {
hours_list: this.hoursWorked,
todays_hours: []
}
},
mounted() {
for (var i = 0; i < this.hours_list.length; i++) {
if (this.hours_list[i].day === this.dayCheck) {
this.todays_hours.push(this.hours_list[i])
}
}
Event.$on('onAddedEntry', (check) => {
if(check.day === this.dayCheck){
this.todays_hours.push(check);
}
})
},
methods: {
onEdit()
{
}
}
}
</script>
Can someone please help me?
Try pushing a copy of check instead of check itself.
Event.$on('onAddedEntry', (check) => {
if(check.day === this.dayCheck){
this.todays_hours.push({...check});
}
})
You could also make the copy when you emit the event instead.
About the issue
I am using Laravel 5.6.7 with vue.js. vee-validate is being used for validation
When the form loads, it shows validation error messages. User did not even click the submit button. Below is the screenshot.
Code
<template>
<div>
<form role="form">
<input v-validate data-vv-rules="required" type="text"
v-model="UpdateForm.First_Name">
<p v-if="errors.has('First Name')">{{ errors.first('First Name') }}</p>
<button type="button">
Update Profile
</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
UpdateForm: {
First_Name: ''
}
}
},
created() {
this.GetProfile();
},
methods: {
GetProfile() {
axios.post("some api url", {}).then(response => {
this.UpdateForm.First_Name = response.data.Data.First_Name;
});
}
}
}
</script>
Could I get rid of validation error messages on form load?
This is not the expected behavior. For initial validating you need to inform it with v-validate.initial.
Maybe you are defining this to happen when declaring v-validate or in other place.
Vue.use(VeeValidate);
new Vue({
el: '#demo'
})
.is-danger{
color: red;
}
<script src="https://unpkg.com/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/vee-validate#latest/dist/vee-validate.js"></script>
<div id="demo">
<label>This one needs touching</label>
<input type="text" name="name" v-validate="'required'">
<div v-show="errors.has('name')" class="is-danger">Errors: {{ errors.first('name') }}</div>
<br/>
<label>This one does not need touching</label>
<input name="name2" v-validate.initial="'required'" type="text">
<div v-show="errors.has('name2')" class="is-danger">{{ errors.first('name2') }}</div>
</div>
Changed
this.editForm.First_Name = Data.User.First_Name;
to
if(Data.User.First_Name != null && Data.User.First_Name != "") {
this.editForm.First_Name = Data.User.First_Name;
}
and validation is working fine now. Basically the variable is not initialized.