How to handle v-model in dynamic input fields - javascript

I have a form where the user has the option to click an "Add" button and input content into new fields. I've currently dynamically generated the v-model for the fields, but I realized I need to register/return each of them in the setup function to use them.
How do I generate and register/return v-models for the different input fields if I don't know how many fields the user will decide to add?
<div
v-for="(content, i) in contentFields"
:key="i"
>
<div>Content {{ i }}</div>
<q-input
:v-model="`contentName_` + i"
outlined
type="text"
dense
/>
</div></div>

Take a look at following snippet with simple dynamic v-models pls:
new Vue({
el: "#demo",
data() {
return {
contentFields: [{name: '', desc: ''}]
}
},
methods: {
addInput() {
let newI = this.contentFields.length
this.contentFields.push({name: '', desc: ''})
},
setD() {
console.log(this.contentFields)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<button #click="addInput">add</button>
<div v-for="(content, i) in contentFields" :key="i">
<div>Content {{ i }}</div>
<input
v-model="content.name"
outlined
type="text"
dense
#change="setD"
/>
<input
v-model="content.desc"
outlined
type="text"
dense
#change="setD"
/>
</div>
</div>

Related

Vue JS taking input dynamically inside v-for

Hi I am trying to taking input in this fashion:
itemPrices: [{regionId: "A", price: "200"},{regionId: "B", price: "100"}]
As the user presses add button new input fields get added.
For this I have taken an empty array=> itemPrices: [], inside vue app data.
Now Inside table element I have this code:
<vs-tr v-for="n in num" v-bind:key="n">
<vs-td
><vs-input
v-model="itemPrices[n].regionId"
placeholder="Region Name"
/></vs-td>
<vs-td>
<vs-input
placeholder="price"
v-model="itemPrices[n].price"
/>
</vs-td>
</vs-tr>
Here 'num' is just an integer which decides how many rows should be there. But this is not working... What is a possible solution for this task?
If I understood you correctly, you set num as itemPrices array length:
new Vue({
el: '#demo',
data() {
return {
itemPrices: []
}
},
computed: {
num() {
return this.itemPrices.length
}
},
methods: {
addItem() {
this.itemPrices = [...this.itemPrices, {regionId: "", price: ""}]
}
}
})
<link href="https://unpkg.com/vuesax#4.0.1-alpha.16/dist/vuesax.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuesax#4.0.1-alpha.16/dist/vuesax.min.js"></script>
<div id="demo">
<vs-button #click="addItem">add</vs-button>
<vs-tr v-for="(n, i) in num" :key="n">
<vs-td>
<vs-input
v-model="itemPrices[i].regionId"
placeholder="Region Name"
/>
</vs-td>
<vs-td>
<vs-input
placeholder="price"
v-model="itemPrices[i].price"
/>
</vs-td>
</vs-tr>
</div>
If you are sure “num” is a filled array I think you can use the following code:
<vs-tr v-for="n in num" v-bind:key="n">
<vs-td
><vs-input
v-model="n.regionId"
placeholder="Region Name"
/></vs-td>
<vs-td>
<vs-input
placeholder="price"
v-model="n.price"
/>
</vs-td>
</vs-tr>
Since n is a representation of each instance inside your array.
Although, you should provide you JS code as well. This way people here get a better understanding of what is going on. For example, I can’t see what “num” looks like.

Vuejs get form data from array

I have a form which is showing multiple input based on database data and I need to get each input value when I submit my form.
Code
<form ref="form" :model="form">
<div class="row">
<div
class="col-md-6"
v-for="(field, index) in fields"
:key="index"
>
<input
class="form-control"
v-model="form.field"
:placeholder="field.title"
/>
</div>
</div>
<vs-button
class="mt-3"
#click="onSubmit"
native-type="submit"
gradient
>
Generate
</vs-button>
</form>
data() {
return {
fields: [],
form: {
field: [],
},
};
},
Issue
My issue is that currently when I fill 1 input others get the same value, I need to fill each input individually.
Screenshots
Any idea?
You're using your v-model pointing to form.field, try to use v-model="form.field[index]"

How to extract the value of textbox (V-Model)?

https://codepen.io/Maximusssssu/pen/KKzLzxg
<td><input class="input" v-model="user.name" /></td>
If you click the link above, is it possible to extract a specific text value (such as a,b,c) in the textbox using .getElementById or other method? This is a very weird input textbox.
You have access to the inputs value as the input and user.name have a two-way binding through v-model:
new Vue({
el: "#app",
data: {
user: {
name: ""
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input v-model="user.name" /> {{ user.name }}
</div>

VueJS: How to use a binding value within a for loop of an array?

I have an array of strings:
myList: ['First item', 'Second item']
I want to add a third, and more. I have a method that pushes an empty string onto the array:
this.myList.push('')
(Using .push on a Vue object is okay)
It now looks like this:
['First item', 'Second item', '']
Which I can now edit. However, it’s not bound to the array. When another item is added, the value is lost and it returns to an empty string.
var app = new Vue({
el: '#app',
data: function() {
return {
myList: ['First item', 'Second item']
}
},
methods: {
remove(index) {
Vue.delete(this.myList, index)
},
add() {
this.myList.push('')
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<div id="app">
<p v-for="(listItem, index) in myList" class="my-2 field" :key="index">
<input
type="text"
:value="listItem"
:key="index"
/>
<button #click.prevent="remove(index)">✕</button>
</p>
<p>
<button #click.prevent="add()">Add</button>
</p>
</div>
Tried the following:
As above:
<input
type="text"
:value="listItem"
:key="index"
/>
Without key, same:
<input
type="text"
:value="listItem"
/>
With (incorrect) binding, doesn’t echo value:
<input
type="text"
:value="myList[index]"
/>
Using v-bind:
<input
type="text"
v-bind:value="listItem"
/>
And also with a key:
<input
type="text"
v-bind:value="listItem"
v-bind:key="index"
/>
I’m positive that I’m going about this the wrong way. Hopefully you can see the behaviour that I’m trying to achive.
Update Have just tried using a v-model, but I get this error:
You are binding v-model directly to a v-for iteration alias. This will not be able to modify the v-for source array because writing to the alias is like modifying a function local variable. Consider using an array of objects and use v-model on an object property instead.
Is it perhaps easier to have an array of objects with one value?
you should use v-model to have a 2-way binding on your input and you have to use myList[index] cause v-bind directive requires an attribute value and not a v-for alias (as listItem). Try this:
var app = new Vue({
el: '#app',
data: function() {
return {
myList: ['First item', 'Second item']
}
},
methods: {
remove(index) {
Vue.delete(this.myList, index)
},
add(listItem) {
this.myList.push('')
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<div id="app">
<p v-for="(listItem, index) in myList" class="my-2 field" :key="index">
{{myList[index]}}
<input
type="text"
v-model="myList[index]"
/>
<button #click.prevent="remove(index)">✕</button>
</p>
<p>
<button #click.prevent="add()">Add</button>
</p>
</div>
The input is not bound with the array elements. Try this.
var app = new Vue({
el: '#app',
data: function() {
return {
myList: ['First item', 'Second item']
}
},
methods: {
remove(index) {
Vue.delete(this.myList, index)
},
add() {
this.myList.push('')
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<div id="app">
<p v-for="(listItem, index) in myList" class="my-2 field" :key="index">
<input
type="text"
v-model="myList[index]"
:key="index"
/>
<button #click.prevent="remove(index)">✕</button>
</p>
<p>
<button #click.prevent="add()">Add</button>
</p>
</div>
JSFiddle : https://jsfiddle.net/32d41epw/2/

Checkbox array in Vue Js

I have an array of checkboxes, coming from a main system object where I store all system setting. (called getSystem{}).
In this form, Im accessing a User, which has an array of roles [].
How can I check this array of roles, against the getSystem.user_roles?
I know how to do it normally, in javascript obviously. But what would I put in the checkbox input Vue.js wise?
<b-form-group>
<label for="company">Email Address</label>
<b-form-input type="text" id="email" v-model="user.email" placeholder="Enter a valid e-mail"></b-form-input>
</b-form-group>
// Here i can do user.roles to get the array of roles.
// What can I do to loop through the roles and check the box if it exists in the user roles??
<b-form-group v-for="resource, key in getSystem.user_roles" v-if="getSystem.user_roles">
<label>{{resource.role_name}}</label>
<input type="checkbox" [ what do I put here to compare against user.roles, and check the box if exists??] >
</b-form-group>
This behavior is well documented on the Checkbox binding Docs.
Here a little example emulating your logic
new Vue({
el: '#app',
data: {
user: {
email: 'test#test.com',
roles: [{id: 1, name: 'Client'}]
},
roles: [
{
id: 1,
name: 'Client',
},
{
id: 2,
name: 'Admin',
},
{
id: 3,
name: 'Guest',
}
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<div>
<label>Email</label>
<input type="text" v-model="user.email" />
</div>
<div v-for="role in roles" :key="role.id">
<label>{{role.name}}</label>
<input type="checkbox" v-model="user.roles" :value="role"/>
</div>
<p>User's selected roels</p>
{{user.roles}}
</div>
<input type="checkbox" v-model="userRoles" :true-value="[]" :value="resource.role_name">
You should add :true-value="[]".
<b-form-group v-for="resource, key in getSystem.user_roles" v-if="getSystem.user_roles" :key="key">
<label>{{resource.role_name}}</label>
<input type="checkbox" v-model="userRoles" :value="resource.role_name" >
</b-form-group>
<script>
data(){
return {
userRoles: []
}
}
</script>
We can use dynamic check box input rendering with the condition to select values from the customized function (in my example selectUsers). In that function, we can write conditions that we need to compare before append to the selected array.
Demo:
This is the full NuxtJs(vue) component with dummy data.
<template>
<v-container fluid>
<p>{{selected }}</p>
<div v-for="user in user_roles" :key="user[0]">
<input type="checkbox"
#click="()=>{selectUsers(user[0])}"
:value="user[0]"
>
{{user[1]}}
</div>
</v-container>
</template>
<script>
import VueLodash from 'vue-lodash'
import lodash from 'lodash'
export default {
data() {
return {
user_roles:[[1,"dd"],[2,"ddd"],[3,"kksse"],[4,"kske"]] ,
selected:[],
};
},
methods: {
selectUsers(id){
//in here you can check what ever condition before append to array.
if(this.selected.includes(id)){
this.selected=_.without(this.selected,id)
}else{
this.selected.push(id)
}
}
}
}
</script>
In my case, as I am server rendering the checkboxes, what worked for me is to replace :value with just value
#foreach($carOptions as $option)
<div class="form-check">
<input class="mx-2 form-check-input cursor-pointer"
type="checkbox"
value="{{$option}}" <------ HERE in order for vue to work I had to change from :value to value
v-model="offer.carOptions">
<label class="custom-control-label cursor-pointer"
for="leading">{{ __($option) }}</label>
</div>
#endforeach
NOTE: The code snippet is a Laravel Blade Templates.

Categories

Resources