I have an array of products to fill (Product fields: {type:"",name:""}).
There is a variable that takes the number of products to enter. Then, for each product, a separate div is rendered with one select and one input text.
I need to get data from each such block and put them in an array.
<div v-for="n in parseInt(countProd)" :key="n">
<div>
<select>
<option>option1</option>
<option>option2</option>
<option>option3</option>
</select>
<input placeholder="Product name">
</div>
</div>
Let me know if this make sense.
new Vue({
el: '#app',
data() {
return {
title: "Vue 2 app",
countProd:0,
products:[]
};
},
watch:{
countProd(newVal,old){
console.log(old,newVal)
this.products=Array.from({length:newVal},(v,i)=>{
return { type:'1', name:''}
})
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
No. of Products:
<input v-model="countProd" />
<div v-for="(p,n) in products" :key="n">
<div>
<select v-model="products[n].type">
<option value="1">option1</option>
<option value="2">option2</option>
<option value="3">option3</option>
</select>
<input placeholder="Product name" v-model="products[n].name">
</div>
</div>
<p v-if="products.length>0">{{products}}</p>
</div>
Related
I have the following vue component CreateProduct.vue
<template>
<div>
<div class="row mb-4">
<label for="category" class="col-md-4 col-form-label text-md-end">Category</label>
<div class="col-md-6">
<select class="form-select col-md-6">
<option value="">Select category</option>
<option v-for="item in categories" :key="item.id" :value="item.id">{{item.category}}</option>
</select>
</div>
</div>
<div class="row mb-4">
<label for="subcategory" class="col-md-4 col-form-label text-md-end">Subcategory</label>
<div class="col-md-6">
<select name="subcategory_id" id="subcategories" class="form-select col-md-6">
<option value="">Select subcategory</option>
<option value="">Subcategory A</option>
</select>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
categories : {},
subcategories : {}
}
},
mounted() {
axios.get('/api/categories')
.then(response => {
this.categories = response.data;
});
},
}
</script>
The component is supposed to fetch all the categories. However, I am not getting any category on the browser. Just blank. What could be the issue>
Your code looks fine, I am just creating a code snippet below, You can check and try to find out the root cause.
Just for the demo I am mocking the response. But you can use the response getting from axios call.
Demo :
new Vue({
el: '#app',
data: {
categories : [],
subcategories : []
},
mounted() {
// Just for the demo I am mocking the response. But you can cross check if this is the same type you are getting from axios call.
const responseData = [{
id: 1,
category: 'Category 1'
}, {
id: 2,
category: 'Category 2'
}, {
id: 3,
category: 'Category 3'
}, {
id: 4,
category: 'Category 4'
}];
this.categories = responseData
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="row mb-4">
<label for="category" class="col-md-4 col-form-label text-md-end">Category</label>
<div class="col-md-6">
<select class="form-select col-md-6">
<option value="">Select category</option>
<option v-for="item in categories" :key="item.id" :value="item.id">{{ item.category }}</option>
</select>
</div>
</div>
<div class="row mb-4">
<label for="subcategory" class="col-md-4 col-form-label text-md-end">Subcategory</label>
<div class="col-md-6">
<select name="subcategory_id" id="subcategories" class="form-select col-md-6">
<option value="">Select subcategory</option>
<option value="">Subcategory A</option>
</select>
</div>
</div>
</div>
Picture of interlinkage between forms and fields.
I have searched this forum for an answer, as I suspect this has been asked before, but I haven't managed to find an answer.
I just picked up using Vue and Laravel, where I am building a form. Right now I am building a test to learn how to do it before I add complexity. The right form consists of 1 select-box and 3 text fields.
My requirements for the form are:
One button to duplicate the entire form.
One button in each form (also ones that are duplicated), which adds the 3 input-text fields in the form, by duplication the fields in the div called "registration_grid". One form may require the text-fields to be duplicated 10 times, others only 1 or 2...
I realize the code is a bit messy in its context, but it is put together by various pieces I found in tutorials along the way.
var app = new Vue({
el: '.container',
data: {
workouts: [
{
workout_unit: '',
workout_weight: '',
workout_comment: ''
}
]
},
methods: {
addNewEmployeeForm () {
this.workouts.push({
workout_unit: '',
workout_weight: '',
workout_comment: ''
})
},
deleteEmployeeForm (index) {
this.workouts.splice(index, 1)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<div class="container">
<button class="btn btn-primary" type="button" name="button" #click="addNewEmployeeForm">Add form fields</button>
<div class="card" v-for="(workout, index) in workouts">
<div class="card-body">
<i class="far fa-trash-alt float-right" #click="deleteEmployeeForm(index)"></i>
<h4 class="card-title">Test form - #{{index}}</h4>
<div class="employee-form">
<select class="form-select form-select-sm" aria-label=".form-select-sm example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<div class="registration_grid">
<input type="text" class="form-control" name="unit" placeholder="unit" v-model="workout.workout_unit">
<input type="text" class="form-control" name="weight" placeholder="weight" v-model="workout.workout_weight">
<input type="text" class="form-control" name="comment" placeholder="comment" v-model="workout.workout_comment">
</div>
</div>
</div>
</div>
Can this be done by Vue, and if so how?
You need to access the form data with workouts[index].unit for the v-model instead of workout.workout_unit
var app = new Vue({
el: '.container',
data: {
workouts: [
{
unit: '',
weight: '',
comment: ''
}
]
},
methods: {
addRow () {
this.workouts.push({
unit: '',
weight: '',
comment: ''
})
},
deleteRow (index) {
this.workouts.splice(index, 1)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<div class="container">
<button class="btn btn-primary" type="button" name="button" #click="addRow">Add form fields</button>
<div class="card" v-for="(workout, index) in workouts">
<div class="card-body">
<i class="far fa-trash-alt float-right" #click="deleteRow(index)"></i>
<h4 class="card-title">Test form - {{index}}</h4>
<div class="employee-form">
<select class="form-select form-select-sm" aria-label=".form-select-sm example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<div class="registration_grid">
<input type="text" class="form-control" name="unit" placeholder="unit" v-model="workouts[index].unit">
<input type="text" class="form-control" name="weight" placeholder="weight" v-model="workouts[index].weight">
<input type="text" class="form-control" name="comment" placeholder="comment" v-model="workouts[index].comment">
</div>
</div>
</div>
</div>
</div>
Modified example to only duplicate the input fields
var app = new Vue({
el: '.container',
data: {
workouts: [
{
unit: '',
weight: '',
comment: ''
}
]
},
methods: {
addRow () {
this.workouts.push({
unit: '',
weight: '',
comment: ''
})
},
deleteRow (index) {
this.workouts.splice(index, 1)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<div class="container">
<button class="btn btn-primary" type="button" name="button" #click="addRow">Add form fields</button>
<div class="card">
<div class="card-body">
<h4 class="card-title">Test form</h4>
<div class="employee-form">
<select class="form-select form-select-sm" aria-label=".form-select-sm example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<div class="registration_grid" v-for="(workout, index) in workouts">
<input type="text" class="form-control" name="unit" placeholder="unit" v-model="workouts[index].unit">
<input type="text" class="form-control" name="weight" placeholder="weight" v-model="workouts[index].weight">
<input type="text" class="form-control" name="comment" placeholder="comment" v-model="workouts[index].comment">
<i class="far fa-trash-alt float-right" #click="deleteRow(index)"></i>
</div>
</div>
</div>
</div>
</div>
I just want to know if what i'm doing is correct.
The goal
here is to convert all input fields in a v-model.
Right now im using jQuery to do that, and is working well.
Is there any way to do it with pure vue.js?
Some considerations:
I don't want to use v-model or any vue attribute on the html like ref="foo".
The data must be in and object and I don't want to predefine.
Thanks
const vueApp = new Vue({
el: '#vue-app',
data: {
dataForm: {}
},
created() {
$("input").each(function(){
var $input_name = 'dataForm.' + $(this).attr('name');
$(this).attr('v-model', $input_name);
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="vue-app">
<div class="">
First Nane : {{ dataForm.firstName }}
</div>
<div class="">
Last Name : {{ dataForm.lastName }}
</div>
<div class="">
<input type="text" name="firstName" value="">
<input type="text" name="lastName" value="">
</div>
</div>
Here i have an #click event
<h2 #click="action(customer.id)">{{ customer.name }}</h2>
When any result is clicked append this result to the input. Any ideas ?
<input class="search" type="text" name="search" v-model="search" placeholder="Search posts..."
#focus="magic_flag = true">
<div v-if="magic_flag">
<div class="post" v-for="customer in filteredCustomer">
<h2 #click="action(customer.id)">{{ customer.name }}</h2>
</div>
</div>
How can i append the clicked result from the search to the input?
js here updated:
methods: {
action(item) {
this.selected = item
this.search = item.name
this.magic_flag=false;
}
},
I display the rest of the content here updated:
<div v-if="selected">
<div class="post" v-for="customer in filteredCustomer">
<div v-if="customer === selected">
<h1>{{ customer.name }}</h1>
<h1>{{ customer.id }}</h1>
<h1>{{ customer.address }}</h1>
</div>
</div>
</div>
Instead of passing customer.id to the action method, you can pass customer object as parameter to action.
You can do something like this.
var vm = new Vue({
el: '#app',
data: {
search: "",
filteredCustomer:[{name:'test1',id:1},{name:'test2',id:2},{name:'test3',id:3}]
},
methods: {
action (customer) {
this.search=customer.name
this.filteredCustomer=this.filteredCustomer.filter(o=> o.id!=customer.id)
}
}
});
h2{cursor:pointer}
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js" type="text/javascript"></script>
<div id="app">
<input class="search" type="text" name="search" v-model="search" placeholder="Search posts..."
>
<div >
<div class="post" v-for="customer in filteredCustomer">
<h2 href #click="action(customer)">{{ customer.name }}</h2>
</div>
</div>
</div>
I have following template:
<template>
<div class="is-half">
<form #submit.prevent="save">
<input type="hidden" name="bookID" :value="book.id">
<div class="field">
<label class="label">Title</label>
<div class="control">
<input class="input" type="text" placeholder="Title" :value="book.title">
</div>
</div>
<div class="control">
<div class="select">
<select>
<option
v-for="author in this.$store.state.authors"
:value="author.name"
:selected="author.name == book.author"
>{{ author.name }}</option>
</select>
</div>
</div>
<div class="field">
<label class="label">Description</label>
<div class="control">
<textarea class="textarea" placeholder="Description" :value="book.description"></textarea>
</div>
</div>
<div class="control">
<button class="button is-primary">Submit</button>
</div>
</form>
</div>
</template>
<script>
export default {
data() {
return {
book : {
id: null,
title: '',
isbn: '',
author: '',
description: '',
added: ''
}
}
},
methods: {
save(book) {
console.log(this.book);
}
},
created() {
if(this.$store.state.book != 'undefined'){
this.book = Object.assign({}, this.$store.state.book);
}
},
computed: {}
}
</script>
<style></style>
I am trying to update the value of selected item, but whenever I press save, the object has the same values which it gets on load.
How can I update values if the I load new object, or insert new object if id is null?
If i understand your question, the problem is that when you type something in the input, it doesn't update the model.
The problem is you're using :value to bind the values and this is a one-way binding. For 2 way binding replace all :value with v-model: v-model="book.title"