Populate Dynamic Input Box with existing Data VueJs - vue.js

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>

Related

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

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

post indexed array Vue.js Axiom

I can post an array of objects in Vue, but I'm having trouble posting a simple indexed array. I'm giving streamlined code because I think the answer lies in plain sight for the experienced.
Here's what I've got so far...
<section v-for="(item, index) in items">
<div>
<button #click.prevent="deleteItem(index)">delete</button>
<input type="text" v-model="item[index]" placeholder="enter your item here">
</div>
</section>
<div>
<button #click.prevent="addItem">add item</button>
</div>
The Vue instance data object so far:
data () {
return {
items: ['']
}
},
What works:
The user can add/delete rows on the form.
Vue DevTools shows me an indexed array with empty fields for each row.
Error messages in the JS console:
I would like to see this in the post...
{ "items": ["item1 input value", "item2 input value"] }
Instead I'm only able to get this because Vue won't react to the input changes...
{ "items": ["", ""] }
For comparison, posting an array of objects works like this:
<section v-for="(item, index) in items">
<div>
<button #click.prevent="deleteItem(index)">delete</button>
<input type="text" v-model="item.color" placeholder="enter color here">
<input type="text" v-model="item.price" placeholder="enter price here">
<input type="text" v-model="item.comment" placeholder="enter comment here">
</div>
</section>
<div>
<button #click.prevent="addItem">add item</button>
</div>
The Vue instance data object:
data () {
return {
items: [{ color: '', price: '', comment: '' }]
}
},
I just received the answer in another forum.
It was so silly... item[index] just needs to be items[index].

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 js v-for v-bind not unique

I'm trying to create a form where I have a select list (fetched from API) and user can add items into a seperate array from this list. New array is also rendered via v-for and uses v-model to edit some additional data.
For example I have a list of goods/services defined beforehand which will be rendered into select option block. Now user can select one of these products and add them to a invoice. After adding (pushed to a new array), user must be able to make some additional changes.
<select class="form-control" v-model="selectedServiceId">
<option v-for="service in services" :value="service._id">{{service.name}}</option>
</select>
<button type="button" class="btn btn-primary" v-on:click="addService">Add</button>
add service method:
addService() {
for (var i = 0; i < this.services.length; i++) {
if (this.services[i]._id == this.selectedServiceId) {
this.services_goods.push(this.services[i])
break;
}
}
}
And now I want to render the list I've pushed into:
<ul>
<li v-for="(item, key) in services_goods">
<span>{{item.name}}</span>
<label for="itemPrice">Price €
<input id="itemPrice" v-model="item.price">
</label>
<label for="itemQty">Quantity
<input type="number" min="1" id="itemQty" v-model="item.quantity">
</label>
<div>
<button type="button" v-on:click="removeService(item._id)">X</button>
</div>
</li>
</ul>
everything is fine up until I add the same item twice and try to modify the price for one of them - it changes price for both.
The reason it changes the price for both is that they are the same object. When you insert an object into an array, the value in the array is a reference to the object. You have two references to the same object.
Each object you insert into the array should be newly created, with contents copied from the selected item.
new Vue({
el: '#app',
data: {
selectedServiceId: null,
services: [{
_id: 1,
price: 1,
quantity: 1,
name: 'First'
},
{
_id: 2,
price: 2,
quantity: 2,
name: 'Second'
}
],
services_goods: []
},
methods: {
addService() {
const foundGood = this.services.find((s) => s._id == this.selectedServiceId);
// Object.assign copies an object's contents
this.services_goods.push(Object.assign({}, foundGood));
}
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<div id="app">
<select class="form-control" v-model="selectedServiceId">
<option v-for="service in services" :value="service._id">{{service.name}}</option>
</select>
<button type="button" class="btn btn-primary" v-on:click="addService">Add</button>
<ul>
<li v-for="(item, key) in services_goods">
<span>{{item.name}}</span>
<label for="itemPrice">Price €
<input id="itemPrice" v-model="item.price">
</label>
<label for="itemQty">Quantity
<input type="number" min="1" id="itemQty" v-model="item.quantity">
</label>
<div>
<button type="button" v-on:click="removeService(item._id)">X</button>
</div>
</li>
</ul>
</div>

vuejs set a radio button checked if statement is true

I am trying to make a radio button checked using vuejs v-for only if my if-statement is true. Is there a way to use vuejs' v-if/v-else for this type of problem?
in php and html I can achieve this by doing the following:
<input type="radio" <? if(portal.id == currentPortalId) ? 'checked="checked"' : ''?>>
Below is what I have so far using vuejs:
<div v-for="portal in portals">
<input type="radio" id="{{portal.id}}" name="portalSelect"
v-bind:value="{id: portal.id, name: portal.name}"
v-model="newPortalSelect"
v-on:change="showSellers"
v-if="{{portal.id == currentPortalId}}"
checked="checked">
<label for="{{portal.id}}">{{portal.name}}</label>
</div>
I know the v-if statement here is for checking whether to show or hide the input.
Any help would be very much appreciated.
You could bind the checked attribute like this:
<div v-for="portal in portals">
<input type="radio"
id="{{portal.id}}"
name="portalSelect"
v-bind:value="{id: portal.id, name: portal.name}"
v-model="newPortalSelect"
v-on:change="showSellers"
:checked="portal.id == currentPortalId">
<label for="{{portal.id}}">{{portal.name}}</label>
</div>
Simple example: https://jsfiddle.net/b4k6tpj9/
Maybe someone finds this approach helpful:
In template I assign each radio button a value:
<input type="radio" value="1" v-model.number="someProperty">
<input type="radio" value="2" v-model.number="someProperty">
Then in the component I set the value, i.e:
data: function () {
return {
someProperty: 2
}
}
And in this case vue will select the second radio button.
You can follow below option if you can adjust with your logic:
<div class="combination-quantity">
<input type="radio" value="Lost"
v-model="missing_status">
<label for="lost">Lost</label>
<br>
<input type="radio" value="Return Supplier" v-model="missing_status">
<label for="return_supplier">Return Supplier</label>
</div>
Value for missing_status could be "Lost" or "Return Supplier" and based on the value radio option will be get selected automatically.
Below is an example of keeping track of the selected radiobutton, by
applying a value binding to the object (:value="portal") and
applying a v-model binding to the currently selected object (v-model="currentPortal").
The radiobutton will be checked automatically by Vue, when the two match (no :checked binding necessary!).
Vue 3 with composition API
Vue.createApp({
setup() {
const portals = [{
id: 1,
name: "Portal 1"
}, {
id: 2,
name: "Portal 2"
}];
const currentPortal = portals[1];
return {
portals,
currentPortal
}
}
}).mount("#app");
<script src="https://unpkg.com/vue#next"></script>
<div id="app">
<template v-for="portal in portals">
<input
type="radio"
:id="portal.id"
name="portalSelect"
:value="portal"
v-model="currentPortal">
<label :for="portal.id">{{portal.name}}</label>
</template>
</div>
I would like to point out a few options when dealing with radios and vue.js. In general if you need to dynamically bind an attribute value you can use the shorthand binding syntax to bind to and calculate that value. You can bind to data, a computed value or a method and a combination of all three.
new Vue({
el: '#demo',
data() {
return {
checkedData: false,
checkedGroupVModel: "radioVModel3", //some defaul
toggleChecked: false,
recalculateComputed: null
};
},
computed: {
amIChecked() {
let isEven = false;
if (this.recalculateComputed) {
let timeMills = new Date().getMilliseconds();
isEven = timeMills % 2 === 0;
}
return isEven;
}
},
methods: {
onToggle() {
this.toggleChecked = !this.toggleChecked;
return this.toggleChecked;
},
mutateComputedDependentData() {
this.recalculateComputed = {};
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="demo">
<div>
<div>
<span>Simple Radio Group - Only one checked at a time. Bound to data.checkedData</span><br>
<label>Radio 1 - inverse of checkedData = {{!checkedData}}
<input type="radio" name="group1" value="radio1" :checked="!checkedData">
</label><br>
<label>Radio 2 - checkedData = {{checkedData}}
<input type="radio" name="group1" value="radio2" :checked="checkedData">
</label><br>
<span>Understanding checked attribute: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-checked</span>
</div>
<br>
<div>
<span>Simple Radio - Checked bouned to semi-random computed object</span><br>
<label>Radio 1: {{amIChecked}}
<input type="radio" :checked="amIChecked">
</label>
<label>Recalculate Computed Value
<button type="button" #click="mutateComputedDependentData">Click Me Several Times</button>
</label>
</div>
<br>
<div>
<span>Simple Radio Group - v-model bound value = {{checkedGroupVModel}}</span><br>
<label>Simple Radio 1:
<input type="radio" name="vModelGroup" value="radioVModel1" v-model="checkedGroupVModel">
</label><br>
<label>Simple Radio 2:
<input type="radio" name="vModelGroup" value="radioVModel2" v-model="checkedGroupVModel">
</label><br>
<label>Simple Radio 3:
<input type="radio" name="vModelGroup" value="radioVModel3" v-model="checkedGroupVModel">
</label>
</div>
<br>
<div>
<span>Simpe Radio - click handler to toggle data bound to :checked to toggle selection</span><br>
<label>Toggle Radio = {{toggleChecked}}
<input type="radio" :checked="toggleChecked" #click='onToggle()'>
</label>
</div>
</div>
</div>