How to create data binding with array input ( multiple input) on vue - vue.js

I have form input using vue js and this input have button to add more column input this button. like this picture image. So on this single input I use v-model and its work , but on my new form this v-model and data binding didn't work. You can see my form like this :
on this new from , this v-model didn't work
<script type="x-template" id="form-input">
<div class="field">
<div class="field-body">
<div class="field">
<label class="label">Nama Barang: </label>
<p class="control is-expanded">
<input
type="text"
id="nama_barang"
class="input"
// v-model="userData.nama_barang" ---> if i add this v-model like this this form not showing , if i remove this its work , but i need v-model to store data
placeholder="nama barang">
</p>
</div>
<div class="field">
<label class="label">Satuan: </label>
<p class="control is-expanded">
<input
type="text"
id="satuan"
class="input"
// v-model="userData.satuan" ---> if i add this v-model like this this form not showing , if i remove this its work , but i need v-model to store data
placeholder="Satuan">
</p>
</div>
<div class="field">
<label class="label">Quantity:</label>
<p class="control is-expanded">
<input
type="number"
id="qtt"
class="input"
//v-model="userData.qtt" ---> if i add this v-model like this this form not showing , if i remove this its work , but i need v-model to store data
placeholder="Qtt" >
</p>
</div>
<div class="field">
<label class="label">Harga:</label>
<p class="control is-expanded">
<input class="input"
type="number"
id="harga"
//v-model="userData.harga" ---> if i add this v-model like this this form not showing , if i remove this its work , but i need v-model to store data
placeholder="Harga">
</p>
</div>
<div class="field">
<label class="label">Harga Total:</label>
<p class="control is-expanded">
{{(userData.qtt * userData.harga) | currency}} // its didnt work because this v-model didnt work
</p>
</div>
</div>
</div>
and its my export default
export default {
data(){
return{
fields: [],
count: 0,
userData:[{
rek_id:'',
tgl_pengajuan:'',
suplier_id:'',
status:'Aktif',
}],
rek:{},
suplier:{},
fields: [],
count: 0,
}
},
components:{
},
methods:{
submit() {
this.errors = {};
axios.post('/pengadaan/store_induk_pencairan', this.userData).then(response => {
window.location = response.data.redirect;
}).catch(error => {
if (error.response.status === 422) {
this.errors = error.response.data.errors || {};
}
});
},
addFormElement: function(type) {
this.fields.push({
'type': type,
id: this.count++
});
},
},
so how this v-model on new form can work like one single form ? this v-model only work on only first form

userData is a array, but in the v-model, you are calling like a js object

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.

Dynamic input value related to another values

I would like to make the value ****here****of the input id="inputWorkload" dynamic and related to the value of inputDuration (newTask.duration * 2 )
How to do it with Vue js?
<div class="col-sm-2">
<div class="form-group">
<label for="inputDuration">Duration (H)</label>
<input class="form-control" id="inputDuration" min="4" step="4" type="number" v-model="newTask.duration">
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label for="inputWorkload">Workload</label>
<input disabled class="form-control" id="inputWorkload" value="****here****">
</div>
</div>
Add an on change event to the duration:
<input class="form-control" id="inputDuration" min="4" step="4" type="number" v-model="newTask.duration" onchange="myFunction()">
Then write some JavaScript which gets the value of the duration on change and updates the workload value based on that.
<script>
function myFunction() {
var inputDurationValue = document.getElementById("inputDuration").value;
document.getElementById("inputWorkload") = inputDurationValue;
}
</script>
With a watcher. Something like this.
data: {
//define your #inputWorkload variable , let's say "workload"
},
watch: {
newTask: {
handler(val){
this.workload = val.duration * 2;
},
deep: true
},
}
// in your template
<input disabled class="form-control" id="inputWorkload" :value="workload">

create vue.js v-model from dynamci value

I am generating a some checkbox dynamically. Now I need to create v-model dynamic.
<div class="form-group input-group">
<label class="form-group-title">DIETARY PREFERENCES</label>
<p>Please mark appropriate boxes if it applies to you and/or your family</p>
<div class="check-group" v-for="v in alldietry" :key="v">
<input type="checkbox" v-model="userinfo.{{#Here will be the value}}" value="" id="Vegetarian">
<label for="Vegetarian">{{v.title}}</label>
</div>
</div>
into the v-model I have try v-model="userinfo.{{xyz}}" its shows error.
You can't use {{ }} interpolation inside attributes.
The v-model value is a javascript expression, so instead of
v-model="userinfo.{{xyz}}"
you can just do
v-model="userinfo[xyz]"
as you would normally do in javascript when accessing a dynamic property of an object.
To bind dynamic object to model, you need to access to key shared by the model value and the set of data used to display your list.
let vm = new Vue({
el: '#app',
data: {
userinfo: {
0: '',
1: ''
}
},
computed: {
alldietry() {
return [
{
id: 0,
title: 'Title'
},
{
id: 1,
title: 'Title'
}
]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="form-group input-group">
<label class="form-group-title">DIETARY PREFERENCES</label>
<p>Please mark appropriate boxes if it applies to you and/or your family</p>
<div class="check-group" v-for="(v, index) in alldietry" :key="index">
<input type="checkbox" v-model="userinfo[v.id]" value="" :id="v.id">
<label :for="v.id">{{v.title}}</label>
</div>
{{ userinfo }}
</div>

Vue 2 - use same form for adding new and editing

I have following template:
<template>
<div>
<form #submit="save">
<div class="field">
<label class="label">Name</label>
<div class="control">
<input class="input" type="text" placeholder="Name" :value="book.title">
</div>
</div>
<div class="field">
<label class="label">Name</label>
<div class="control">
<input class="input" type="text" placeholder="Name" :value="book.author">
</div>
</div>
</form>
</div>
</template>
<script>
export default {
data() {
return {
book : {}
}
},
methods: {
save() {
}
},
created() {
if(this.$store.state.book != 'undefined'){
this.book = this.$store.state.book;
}
},
computed: {}
}
</script>
<style></style>
So far everything works fine if the book is pass with the this.$store.state.book, but if this is not passed the form is failing, with the error message:
** Error in render function: "TypeError: Cannot read property 'title' of undefined"**
I thought that passing the empty object would dynamically bind the book object and auto create the params.
Is it possible to use the same form for both adding new and editing?
I tried your code, and all you have to do is remove the 'quotes' from 'undefined'. Obviously, it's a string as is, and not a js thing.

vue js get multiple values from inputs

So I have 2 blocks of HTML, each containing 2 input fields and when submitting the form, I want to get all values from the inputs, and then create an object from the values...
As of know I've done it with plain vanilla JS and it works as it should, however if feels like to touching the DOM a bit to much, and also are very much depending on a specific DOM struckture, and therefore I was thinking there must be a better way, the VUE way so to speak, however im a bit stuck on how to do this the VUE way, which is why posting the question here in hope of getting some useful tips :)
HTML:
<form novalidate autocomplete="off">
<div class="input-block-container">
<div class="input-block">
<input type="text" placeholder="Insert name" name="name[]" />
<input-effects></input-effects>
</div>
<div class="input-block">
<input type="email" placeholder="Insert email address" name="email[]" />
<input-effects></input-effects>
</div>
</div>
<div class="input-block-container">
<div class="input-block">
<input type="text" placeholder="Insert name" name="name[]" />
<input-effects></input-effects>
</div>
<div class="input-block">
<input type="email" placeholder="Insert email address" name="email[]" />
<input-effects></input-effects>
</div>
</div>
<button class="button button--primary" #click.prevent="sendInvites"><span>Send</span></button>
</form>
JS:
methods: {
createDataObject() {
let emailValues = document.querySelectorAll('input[type="email"]');
emailValues.forEach((email) => {
let name = email.parentNode.parentNode.querySelector('input[type="text"]').value;
if(email.value !== "" && name !== "") {
this.dataObj.push({
email: email.value,
name
});
}
});
return JSON.stringify(this.dataObj);
},
sendInvites() {
const objectToSend = this.createDataObject();
console.log(objectToSend);
//TODO: Methods to send data to server
}
}
You can provide data properties for each of your inputs if you have static content.
data: function() {
return {
name1: '',
email1: '',
name2: '',
email2: ''
}
}
Then use them in your template:
<input type="text" placeholder="Insert name" v-model="name1" />
Access in method by this.name1
Try this
<div id="app">
<h1> Finds </h1>
<div v-for="find in finds">
<input name="name[]" v-model="find.name">
<input name="email[]" v-model="find.email">
</div>
<button #click="addFind">
New Find
</button>
<pre>{{ $data | json }}</pre>
</div>
Vue Component
new Vue({
el: '#app',
data: {
finds: []
},
methods: {
addFind: function () {
this.finds.push({ name: '', email: '' });
}
enter code here
}
});