I want to access the error message returned from my api if error exists for its corresponding input field. With what I have tried, all errors returned from the api shows below all input fields as in the image below.
Below are the parent and child vue components.
InputField.vue
<template>
<div class="form-group basic">
<div class="input-wrapper">
<label class="label" :for="name">{{label}}</label>
<input :type="type"
class="form-control"
:class="errorClassObject()"
:id="name" :placeholder="placeholder"
:v-model="value" #input="updateField">
<i class="clear-input">
<ion-icon name="close-circle" role="img" class="md hydrated" aria-label="close circle"></ion-icon>
</i>
</div>
<div v-text="errorMessage(name)" class="input-info text-danger">Error here</div>
</div>
</template>
<script>
export default {
name: "InputField",
props: [
'name', 'value', 'type', 'label', 'placeholder', 'errors'
],
data: function() {
return {
}
},
computed: {
hasError: function(){
return this.errors
//return this.errors.name throws an error name is undefined
}
},
methods: {
updateField (){
this.$emit('input', event.target.value)
},
errorMessage(name){
if(this.hasError){
return this.errors;
//return this.errors.name throws undefined name
}
},
errorClassObject (){
return{
'error-field': this.hasError
}
}
}
}
</script>
<style scoped>
</style>
ChangePassword.vue
<template>
<form #submit.prevent="onSubmit">
<form-input
required
name="current_password"
type="password"
label="Current Password"
:errors="errors"
placeholder="Enter current password"
v-model="passwordForm.current_password"
/>
<form-input .../>
<form-input.../>
<div class="form-button-group transparent">
<button type="submit" class="btn btn-primary btn-block btn-lg">Update Password</button>
</div>
</form>
</template>
Presently, if there are any errors from the request, the response is returned in the format below
You could get access to it using the square brackets like :
errorMessage(name){
if(this.hasError){
return this.errors[name];
}
},
Related
I'm trying to save data with VueJS to a Go backend API.
When I click submit, the data is saved twice. I've tried to prevent this but something is missing.
I've tested the endpoint with Postman and it's saving normally.
Here is the component:
<template>
<div class="row">
<form #submit.prevent="PostDominio">
<hr />
<label id="lbldom">Dominio </label>
<input v-model="form.Titulo" type="text" />
<button
id="sendom"
class="btn btn-outline-primary btn-sm shadow-sm p-1 mb-1"
#click="PostDominio"
>
Gravar
</button>
<hr />
</form>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
form: {
Titulo: '',
},
}
},
methods: {
PostDominio() {
axios
.post('http://localhost:3000/dominios', this.form)
.bind(this)
.catch((error) => {
console.log(error)
})
},
},
}
</script>
I added e.preventDefault to the PostDominio(e) function and it solved my issue!
I generate so many input boxes on loop of article array.
article is array of objects. Input boxes values are set with "value" key in each object.
<div
v-for="(option, i) in this.article"
:key="i"
class="form-row"
>
<div class="col">
<input
v-model="option.value"
:label="'label '+i"
:name="'inputValue'+i"
type="text"
required
/>
</div>
</div>
<button #click="submit"></button>
<script>
export default {
name: 'Article',
data(){
return(
article:[
{id: 'art1', value: 'artValue1'},
{id: 'art2', value: 'artValue2'},
{id: 'art3', value: 'artValue3'}
// There are about 50 objects
]
)
},
methods:{
submit(){
// How get values of inputs?
}
}
}
</script>
How can I make the value of input change and update the object in vue?
I created a sample Single File Component based on your code. Look at my modifications. The 'magic' of Vue reactivity is that the 'article' data is updated in real time as you change the input values.
<template>
<div class="input-bound-object-array">
<div class="row">
<div class="col-md-6">
<form #submit.prevent="submitForm">
<div class="form-group" v-for="(option, i) in article" :key="i">
<label>{{ option.id }}</label>
<input type="text" class="form-control" v-model="option.value"
required />
</div>
<button type="submit" class="btn btn-secondary">Submit</button>
</form>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
article: [
{ id: 'art1', value: 'artValue1' },
{ id: 'art2', value: 'artValue2' },
{ id: 'art3', value: 'artValue3' }
// There are about 50 objects
]
}
},
methods: {
submitForm() {
// 'this.article' is updated as the input values are changed, so at this point
// you have the data changes, so you can process it as needed, i.e. POST to REST endpoint
console.log(this.article);
}
}
}
</script>
You forgot to return the object from data function and you can pass option to submit handler and print the input values.
// How get values of inputs? -> Do you mean all of the inputs or input where ever the button clicked or anything else. Below code is to handle individual input and submit handlers
<template>
<div
v-for="(option, i) in article"
:key="i"
class="form-row"
>
<div class="col">
<input
v-model="option.value"
:label="'label ' + i"
:name="'inputValue' + i"
type="text"
required
/>
</div>
<!-- <button #click="submit(option)">Submit</button> to handle individual inputs -->
</div>
<!-- <button #click="submitAll()">Submit All</button> to handle all inputs -->
</template>
<script>
export default {
name: 'Article',
data() {
return { // you missed this
article:[
{id: 'art1', value: 'artValue1'},
{id: 'art2', value: 'artValue2'},
{id: 'art3', value: 'artValue3'}
]
}
},
methods: {
submit(option) { // current option
console.log(option.id, option.value)
},
submitAll() {
console.log(this.article) // which will have update input values as
you're using `v-model`, check `values`
}
}
}
</script>
Demo Link here
this is the template I want to make a password input and checkbox while box is checked I want to type inside input to turn into the text instead of password
<!--template-->
<template>
<div>
<div id="login">
<h1 style="font-size:30px; color:black;">Login</h1>
<input type="text" placeholder="Username...">
<input :type="inputtype" placeholder="Password...">
<input type="checkbox" name="" id="" :checked="totext">
<button class="button is-link">Submit</button>
Register
Forgot the password..?!
</div>
</div>
</template>
17:5 error Unexpected labeled statement no-labels
17:16 error Expected an assignment or function call and instead saw an expression
<script>
export default {
data () {
inputtype: 'password'
},
methods: {
totext () {
this.inputtype = this.inputtype === 'password' ? 'text' : 'password'
}
}
}
</script>
Please try this code instead:
:type="totext ? 'password': 'text' "
<template>
<div>
<div id="login">
<h1 style="font-size:30px; color:black;">Login</h1>
<input type="text" placeholder="Username...">
<input :type="totext ? 'password': 'text' " placeholder="Password...">
<input type="checkbox" name="" id="" :checked="totext">
<button class="button is-link">Submit</button>
Register
Forgot the password..?!
</div>
</div>
</template>
And this script:
<script>
export default {
data () {
return {
totext : false
}
}
}
</script>
Or this one (the better one)
<template>
<div>
<div id="login">
<h1 style="font-size:30px; color:black;">Login</h1>
<input type="text" placeholder="Username...">
<input :type="isText" placeholder="Password...">
<input type="checkbox" name="" id="" :checked="totext">
<button class="button is-link">Submit</button>
Register
Forgot the password..?!
</div>
</div>
</template>
And
<script>
export default {
data () {
return {
totext : false
}
},
computed: {
isText(){
return totext ? 'password': 'text'
}
}
}
</script>
Please try this code :
data: () => ({
inputtype: 'password'
)}
You've merged the two sets of braces.
This:
data () {
inputtype: 'password'
},
should be this:
data () {
return {
inputtype: 'password'
}
},
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.
I am trying to implement search component for my application, parent component have the search text box and button. When the user provide some value i want to send the data to api and show the result in child component. I am bit confused where to call the api and also how to populate the data in child component. Also, initially my child component should not render in the parent component, when the search get some result then it can render. Please help me how to implement a search functionality in vue js 2.
Parent Component
<template>
<div><h3> Search </h3></div>
<div class="row">
<form role="search">
<div class="form-group col-lg-6 col-md-6">
<input type="text" v-model="searchKey" class="form-control">
</div>
<div class="col-lg-6 col-md-6">
<button type="button" id="btn2" class="btn btn-danger btn-md" v-on:click="getInputValue">Search</button>
</div>
</form>
</div>
<result :searchdataShow='searchData'></result>
</template>
<script>
import resultView from './result'
export default {
components: {
'result': resultView
},
data () {
return {
searchKey: null,
searchData: null
}
},
methods: {
getInputValue: function(e) {
console.log(this.searchKey)
if(this.searchKey && this.searchKey != null) {
this.$http.get('url').then((response) => {
console.log(response.data)
this.searchData = response.data
})
}
}
}
</script>
Search Result component(child component)
<template>
<div>
<div class="row"><h3> Search Results</h3></div>
</div>
</template>
<script>
export default {
props: ['searchdataShow']
}
</script>
Create a boolean variable that keeps track of your ajax request, i usually call it loading, or fetchedData, depending on the context. Before the ajax call, set it to true, after the call, set it to false.
Once you have this variable working, you can then conditionally render the result component with v-if. I like to show a loading icon with the corresponding v-else.
Also your template doesn't seem to have a root element, which is required.
<template>
<div><h3> Search </h3></div>
<div class="row">
<form role="search">
<div class="form-group col-lg-6 col-md-6">
<input type="text" v-model="searchKey" class="form-control">
</div>
<div class="col-lg-6 col-md-6">
<button type="button" id="btn2" class="btn btn-danger btn-md" v-on:click="getInputValue">Search</button>
</div>
</form>
</div>
<result v-if="!loading" :searchdataShow='searchData'></result>
<div v-else>loading!!</div>
</template>
<script>
import resultView from './result'
export default {
components: {
'result': resultView
},
data () {
return {
loading: false,
searchKey: null,
searchData: null
}
},
methods: {
getInputValue: function(e) {
console.log(this.searchKey)
this.loading = true;
if(this.searchKey && this.searchKey != null) {
this.$http.get('url').then((response) => {
console.log(response.data)
this.loading = false;
this.searchData = response.data
})
}
}
}
</script>