Vue js input array for cloneable sections - vue.js

I have input sections like so:
<div class="cloneable" data-id="0">
<div class="col-md-9">
<div class="form-group">
<label>Skills and Qualifications Titles</label>
<input placeholder="ex : PHP, WordPress" name="skill.name" type="text" class="form-control" vmodel="skill.name">
<span class="help-block text-danger" v-text="errors.get('skill.name')"></span>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label>Skill Level %</label>
<input placeholder="ex : 90" name="skill.percentage" type="text" class="form-control" v-model="skill.percentage">
<span class="help-block text-danger" v-text="errors.get('skill.percentage')"></span>
</div>
</div>
</div>
Each section can be cloned to make a duplicate, so I am trying to array my data so I can access it backend like
skill[0]['name']
skill[1]['name']
skill[2]['name']
... etc
I am initiating the data like so:
skill: [
{
'name': '',
'percentage': ''
}
],
I have tried using the models like skill.index.name, but that doesn't work, how can I achieve what I am trying to do above?

If I understand, you have an array of skills like:
skill: [
{'name': 'a_name', 'percentage': '20'}
{'name': 'b_name', 'percentage': '30'}
],
and you want to access a particular member of that array in your template. The normal way the arrays end up in templates is using a v-for: like:
<li v-for="a_skill in skill">
{{ a_skill.name }}
</li>
…which would like all the skills in the array.
If you want to access a particular member of that array you will need to add the index like this:
<input v-model="skill[0].name"> // not skill.0.name
(don't forget the hyphen in v-model it's missing in your example)
You can even do that if you have some data you want to use as the index. For example:
data () {
return {
skill: [
{"name": "Foo"},
{"name": "Bar"}
],
i: 1
}},
Then you could use this in your template:
<input v-model="skill[i].name">

Related

When i edit a dict in an array which has been cloned from another dict, all the duplicated dictionary values also changes

when I edit a dict in a array which has been cloned from another dict,the value of the other cloned dictionaries also changes. Is there a way where i can change only the specified dictionary value??
<template v-for="stage in clonedstages">
<p v-text="stage.name" #click="stagedisplay=true" > </p>
<stage header="Stage Edit" :visible.sync="stagedisplay" :modal="true">
<div>
<div class="form-group">
<label for="stagename">Stage name </label>
<input type="text" class="form-control" id="stagename" v-model="[index]clonedstages.name">
</div>
</div>
<button class="btn btn-secondary" #click="stagedisplay=false">Done</button>
</stage>
</template>
<div class="col-sm">
<button class="btn-sm btn-primary" #click="Gd">GD</button>
`
interview: {
stage_type : 1,
description : "something",
name : "Interview"
},
clonedstages: [],
this is the dict,
Interview(){
vue_create.clonedstages.push(vue_create.interview);
},
this is the method.
I am new to this.

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].

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>

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>