Required validation message not displaying in Vue - vue.js

I have a form in my vue component.
In that form I have a filed to input document name
<!--Name-->
<div class="mb-5 relative z-30">
<p class="text-certstyle-titles font-bold text-sm mb-1">Name</p>
<validator-v2
identifier="addDocument"
name="add_name_input"
selector="id"
:rules="{ required: { message: 'Name of the document is required.'}}"
></validator-v2>
<input
id="add_name_input"
v-model="documentName"
name="name"
type="text"
class="form-input w-full relative z-10"
/>
</div>
And I have following required validation for name field inside the store method,
if (!this.documentName) {
this.showToastrErrorMessage("Please add document name")
loader.stopLoading();
return
}
But when I try to submit the form without filling name field, it's not shoeing me the error message or the toast...

Related

Laravel + vue: Error message only showing the first letter of the sentence

I'm just starting to learn laravel+vue. I was able to follow a tutorial from this yt: https://www.youtube.com/watch?v=JZDmBWRPWlw. Though it seems outdated, I was still able to follow his steps. I'm using the laravel-mix 6.0.6 and vue 2.6.12.
Using inspect element>network, I can see that I'm throwing the correct error message in array.
{"component":"Users\/Create","props":{"app":{"name":"Laravel"},"errors":{"name":"The name field is required.","email":"The email field is required."}},"url":"\/users\/create","version":"207fd484b7c2ceeff7800b8c8a11b3b6"}
But somehow it is not displaying the complete error message. Right now it just show the first letter of the sentence. LOL. Sample error message is: The email field is required and it will just display the letter "T". Below is my Create.vue. Basically it is just a user create form with simple validation.
Create.vue
<template>
<layout>
<div class="container">
<div class="col-md-6">
<div v-if="Object.keys(errors).length > 0" class="alert alert-danger mt-4">
{{ errors[Object.keys(errors)[0]][0] }}
</div>
<form action="/users" method="POST" class="my-5" #submit.prevent="createUser">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" placeholder="Name" v-model="form.name">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="text" class="form-control" id="email" placeholder="Email" v-model="form.email">
</div>
<div class="form-group">
<label for="name">Password</label>
<input type="password" class="form-control" id="password" placeholder="Password" v-model="form.password">
</div>
<button type="submit" class="btn btn-primary">Create User</button>
</form>
</div>
</div>
</layout>
</template>
<script>
import Layout from '../../Shared/Layout'
export default {
props: ['errors'],
components: {
Layout,
},
data() {
return {
form: {
name: '',
email: '',
password: '',
}
}
},
methods: {
createUser() {
this.$inertia.post('/users', this.form)
.then(() => {
// code
})
}
}
}
</script>
Edit:
I have this error on my console
[Vue warn]: Error in v-on handler: "TypeError: Cannot read property
'then' of undefined"
found in
---> at resources/js/Pages/Users/Create.vue
Your error call is probably getting only the first letter due to [0]. Try to change to:
{{ errors[Object.keys(errors)[0]] }}
Strings can also be read as arrays. If you do this:
$a = "TEST";
echo $a[0];
That would print only T.
That is probably the problem.

Populate Dynamic Input Box with existing Data VueJs

From the title itself, I want to populate a dynamically created input box that I will load via AJAX upon page load.
<div class="col-md-10" id="app">
<div class="form-row" v-for="i in travellers">
<div class="form-group col-md-6" v-for="(details, index) in bookingRequiredDetails">
<label for="required-details">{{ details }}</label>
<input
type="text"
class="form-control"
#input="prop('traveller_' + i, details, $event)"
placeholder="Required Details"
/>
</div>
</div>
</div>
data () {
return {
bookingForm: {
...
bookingRequiredDetails: ''
},
travellerDetails: {},
}
},
load: function () {
... where the data variable has value upon page load
vm.bookingForm.bookingRequiredDetails = data.bookingRequiredDetails;
if (data.travellerDetails) {
vm.travellerDetails = data.travellerDetails;
}
}
Loaded Data:
The input boxes generated will depend on the required details. So for this instance, there will be 3 generated input boxes.
bookingRequiredDetails: Array(1)
0: Array(3)
0: "Full Name"
1: "Age"
2: "Gender"
travellerDetails: Array(1)
0:
traveller_1: Object
Age: "12"
Full Name: "Jane"
Gender: "M"
1: ...
2: ...
Sample Output:
What I want is to populate the existing travellerDetails object with data loaded from the server to their respective input boxes. However, I have problems with pairing the correct data to their respective key-value pairs of the input box as shown in the screenshot.
Any idea would be greatly appreciated.
So I manage to solve it. By adding v-model.
v-model="travellerDetails['traveller_' + i][details]"
div class="col-md-10" id="app">
<div class="form-row" v-for="i in travellers">
<div class="form-group col-md-6" v-for="(details, index) in bookingRequiredDetails">
<label for="required-details">{{ details }}</label>
<input
type="text"
class="form-control"
v-model="travellerDetails['traveller_' + i][details]"
#input="prop('traveller_' + i, details, $event)"
placeholder="Required Details"
/>
</div>
</div>
</div>

VueJs v-Model Binding with Hidden Component not working

I am developing a SPA application in Vue. I have a wizard in the wizard I have a component for each step. All the components are adding at the start and their mounted and created method/event is executing when the application starts.
I am using the event bus & when I move to the next step of wizard I emit the event and catch the event on the respective step.
Note: Component is hidden at the start and when it shows it will not have the updated data or even data in input fields.
Code of the component of the 2nd step is
<template>
<section>
<div class="container">
<form class="form-horizontal">
<div class="row form-group">
<label class="col-sm-3 control-label" for="marshaCode">MARSHA Code:</label>
<div class="col-sm-4">
<input type="text" class="form-control field-ml-15" v-model="marshaCode" placeholder="Enter Marsha Code" readonly />
<input type="text" class="form-control field-ml-15":value="marshaCode" placeholder="Enter Marsha Code" readonly />
<p>{{marshaCode}}</p>
</div>
</div>
</form>
</div>
</section>
</template>
<script>
import { EventBus } from "../../shared/eventbus.js";
export default {
data() {
return {
marshaCode:"On Load Code"
}
},
mounted() {
EventBus.$on('showSurvey', () => {
this.marshaCode="On Show Code"
});
},
}
</script>
Now when this component will show the P tag will have "On Load Code" But in both the fields there will be no data.
How can I rebind, re-render or update the data?
Use vue to show/hide the component using v-if or v-show. It can't do it's job if another library is messing with the DOM.
<section v-if='showMyComponent'>
or
<div class="col-sm-4" v-if='showMyComponent'>
<input type="text" class="form-control field-ml-15" v-model="marshaCode" placeholder="Enter Marsha Code" readonly />
<input type="text" class="form-control field-ml-15":value="marshaCode" placeholder="Enter Marsha Code" readonly />
<p>{{marshaCode}}</p>
</div>
And set showMyComponent to a computed or data property. Then remove the logic to show/hide from your other library.
You can simply add this.marshaCode="On Show Code" when mounted.
mounted() {
this.marshaCode="On Show Code"
console.log(EventBus)
EventBus.$on('showSurvey', () => {
this.marshaCode="On Show Code"
});
}
An example: https://codesandbox.io/embed/vue-template-8l2lg.

v-on:model="form.email" expects a function value, got undefined

Vue.js 2 - I am trying to bind form inputs but I always get the erro message ( on all inputs ..)
v-on:model="form.email" expects a function value, got undefined
<form id="registrationForm">
<div class="form-group">
<input type="email" name="email" id="email" #model="form.email" placeholder="enter your email address">
</div>
<button #click="sendRegistration" type="submit" class="btn btn-primary btn-gradient submit">SEND</button>
</form>
and the script
data: function() {
return {
form: {
...
email: '',
...
}
}
},
methods: {
sendRegistration: function() {
console.log('sending form')
return false
}
},
You're getting some things mixed up. Attributes starting with v-on:, often abbreviated as #, are used to register event listeners on elements. #click="sendRegistration" will for example register the sendRegistration method defined on your Vue instance as a handler for that element's click event.
What you're trying to accomplish has nothing to do with event handling. The attribute you need is called v-model and binds an <input>'s value to a value saved on your Vue instance.
<input type="email" name="email" id="email" #model="form.email">
should be
<input type="email" name="email" id="email" v-model="form.email">

Vue Validator only after change / blur / submit

I'm using Vue for the first time, with Vue Validator. Here is an example of my code:
<label for="first_name">First name:
<span v-if="$validation1.first_name.required" class="invalid">Enter your first name.</span>
<input id="first_name" placeholder="e.g. Christopher" class="" v-validate:first_name="['required']" v-model="first_name" name="first_name" type="text">
</label>
The only issue at the moment is that when I land on the page with my form, the whole thing is covered in errors. Is there a way I can suppress the errors and only show them on input blur / form submit?
Argh, the Google-able word isn't about blur, or on submit – its about timing and initial:
http://vuejs.github.io/vue-validator/en/timing.html
<input id="first_name" initial="off" placeholder="e.g. Christopher" class="" v-validate:first_name="['required']" v-model="first_name" name="first_name" type="text">
you need to add .dirty or .touched to your validation
<label for="first_name">First name:
<span v-if="$validation1.first_name.required && $validation1.first_name.touched" class="invalid">Enter your first name.</span>
<input id="first_name" placeholder="e.g. Christopher" class="" v-validate:first_name="['required']" v-model="first_name" name="first_name" type="text">
</label>
I was dealing with a similar problem. I had to have an initialized variable for the input name: "" but I also wanted to have a required attribute in element.
So I add required when the event onblur occurs.
<input name="name" type="number" v-model="name" #blur="addRequired" />
const app = Vue.createApp({
data() {
return {
name: ""
}
},
methods:{
addRequired: function(event){
event.target.setAttribute("required", true);
}
}
});