I have a table that lists out all my products and their prices and I have the prices as input
and what I would like to do is, when I click on save then I need to be able to save all those prices that I changed at
one time.
I'm not sure how to go about doing that.
Here is my code
<template>
<div>
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr v-for="product in products">
<td>{{product.name}}</td>
<td>
<input #change="onChange(product)" v-model="product.prices">
</td>
</tr>
</tbody>
</table>
<div>
<div class="btn btn-success" #click="updatePrices()">
Save Prices
</div>
</div>
</template>
<script>
export default {
props: ['products'],
data() {
return {
product: {
price: null
}
}
},
methods: {
updatePrices(){
console.log(this.products.price);
}
},
mounted(){
}
}
</script>
Your question is about two parts of data passing.
From Vue Component to Vue Parent.
From Vue Client to Server.
And also, you may be confused with component data and props
You can check my answer
//component
Vue.component('price-table', {
props:[
'parentProducts',
],
data: function() {
return {
products:[]
};
},
methods: {
updatePrice(){
console.log('update prices from component to parent');
console.log(this.products);
this.$emit('update-prices', this.products);
}
},
mounted:function(){
console.log('pass products from parent to component');
this.products = this.parentProducts;
}
});
//parent
var vm = new Vue({
el: '#app',
data: () => ({
products:[
{
name:'Apple',
price:'10'
},
{
name:'Banana',
price:'12'
},
{
name:'Coconut',
price:'20'
},
]
}),
methods:{
savePricesToServer(products){
console.log('save prices to server');
console.log(products);
//do ajax here
}
}
});
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>Price Table</h2>
<price-table
inline-template
:parent-products="products"
v-on:update-prices="savePricesToServer"
>
<div>
<table border='1' width="100%">
<tr>
<th>Product</th>
<th>Price</th>
</tr>
<tr v-for="(product, productIndex) in products" :key="productIndex">
<td>{{ product.name}}</td>
<td>
<input type="number" v-model="product.price">
</td>
</tr>
</table>
<button #click="updatePrice">Update Price</button>
</div>
</price-table>
</div>
</body>
</html>
It is showing how to use custom event to pass data from component back to parent https://v2.vuejs.org/v2/guide/components-custom-events.html
Related
I'm processing the incoming data with Ajax as follows. But I can't make it compatible with dataTable. I've read the Datatable Ajax documentation. But I was never successful. How do I pull the following data into the dataTable? I want to make these codes compatible for Data Table.
You can see multiple parse operations in my code. Please do not warn about it. Net Core, I can only process the JSON file in this way. The only thing I want from you is to show this data that I have processed successfully in the datatable.
<div class="card" id="view-maincategorylist">
<div class="card-body">
<div class="table-responsive">
<table id="datatablex" class="table table-striped table-bordered" style="width:100%">
<thead>
<tr>
<th class="text-center">Fotoğraf</th>
<th class="text-center">Ana Kategori Adı</th>
<th class="text-center">Seçenekler</th>
<th class="text-center">İşlemler</th>
</tr>
</thead>
<tbody id="table-maincategories">
</tbody>
</table>
</div>
</div>
</div>
<script>
function GetMainCategoryList() {
$.ajax({
url: "/Admin/BusinessCategories/MainCategories/",
contentType: "application/json",
dataType: "json",
type: "Get",
success: function (data) {
var item = jQuery.parseJSON(data);
$("#table-maincategories").empty();
$.each(JSON.parse("[" + item + "]"), (index, value) => {
for (let element of value) {
$("#table-maincategories").append(`<tr class="text-center">
<td><img src="${element.Image}" style="height:80px;" /></td>
<td>${element.Name}</td>
<td>
<div class="form-check">
<a href="/Admin/BusinessCategories/MainShowMenu/${element.Id}" onclick="location.href=this.href;">
<input class="form-check-input" type="checkbox" id="flex_${element.Id}">
</a>
<label class="form-check-label" for="flex_${element.Id}">Menüde Göster</label>
</div>
</td>
<td>
<a onclick="ShowEditMainCategory(${element.Id})" class="btn btn-primary"><i class="bx bx-edit"></i> Düzenle</a>
<a onclick="DeleteMainCategory(${element.Id});" data-name="${element.Name}" id="del_${element.Id}" class="btn btn-danger delete-button"><i class="bx bx-trash"></i> Sil</a>
</td> </tr>`);
var checkbox = document.getElementById('flex_' + element.Id);
if (element.ShowMenu == true) {
checkbox.checked = true;
}
else {
checkbox.checked = false;
}
}
});
$('#datatable').DataTable();
ViewShowHide(1);
},
error: function () {
Swal.fire('Veriler Okunamadı!', '', 'error')
}
})
}
</script>
Problem Images:
image 1
image 2
image 3
JSON Data Output:
https://easyupload.io/1bsb75
I am just learning Vuejs with laravel. and my Delete is Working correctly but when it redirect to index page after row is deleted that row is not removed until it is loaded..
And for When Category is added new data is not shown until browser is loaded...
This is my Categories Component `
<form role="form" method="POST" enctype="multipart/form-data" #submit.prevent="createCategory" v-if="adding">
<div class="card-header">
<h3 class="card-title">Create New Category</h3>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Category Name</label>
<input type="text" class="form-control" id="category_name" v-model="category_name" placeholder="Enter Category Name">
</div>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">Submit</button>
<button #click.prevent="cancel" class="btn btn-danger">Cancel</button>
</div>
</form>
<div class="card-body" v-else>
<div class="card-header" >
<h3 class="card-title"><a class="btn btn-block btn-outline-secondary btn-lg" #click.prevent="add()"> Create New Category</a></h3>
</div>
<table id="example2" class="table table-bordered table-hover" >
<head>
<tr>
<th>ID</th>
<th>Category Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-for="(category,index) in model" :category="category" v-bind:key="category.id">
<td>{{category.id}}</td>
<td>{{category.category_name}}</td>
<td>Edit | <a #click="deleteCategory(category.id,index)" class="btn-outline-
danger">Delete</a></td>
</tr>
</body>
</table>
</div>
</div>
`
<script>
export default {
props:['model'],
data(){
return {
model:[],
section_id: 0,
sections: [],
parent_id: 0,
categories: [],
adding:false,
category_name:'',
}
},
methods:{
add(){
this.adding=true;
},
cancel(){
this.adding=false;
},
createCategory(){
axios.post(`categories `,{
category_name:this.category_name,
}).catch(error => {
console.log('Error')
})
.then(res=>{
this.adding=false;
})
},
deleteCategory(id,index){
if(confirm('Are You Sure ?')){
axios.delete('categories/'+id)
.then(resp => {
this.model.splice(index, 1);
})
.catch(error => {
console.log(error);
})
}
}
},
}
</script>
<table id="example2" v-if="flag" class="table table-bordered table-hover" >
<head>
<tr>
<th>ID</th>
<th>Category Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-for="(category,index) in model" :category="category" v-bind:key="category.id">
<td>{{category.id}}</td>
<td>{{category.category_name}}</td>
<td>Edit | <a #click="deleteCategory(category.id,index)" class="btn-outline-
danger">Delete</a></td>
</tr>
</body>
</table>
in data add flag:false,
data(){
return {
model:[],
section_id: 0,
sections: [],
parent_id: 0,
categories: [],
adding:false,
category_name:'',
flag:false
}
},
in your functions make your flag false in case of success response
deleteCategory(id,index){
this.flag=false;
if(confirm('Are You Sure ?')){
axios.delete('categories/'+id)
.then(resp => {
this.model.splice(index, 1);
this.flag=true;
})
.catch(error => {
console.log(error);
this.flag=false;
})
}
}
I think that you are overcomplicate this. Just create an API that retrieve all the categories. So after each addition or deletion, then just call that API.
I am creating a form in which you add cities on the basis of countries you get from dynamic drop-down. I am able to get the category_id (foreign key) in Vuejs but I don't how to pass it to the laravel back-end. I want to create a subcategory object with name and category_id. category_id is foreign key. I am unable to get category_id and it is passing NULL to db.
**Category = Country**
**Subcategory = City**
<template id="add-post">
<div>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>City Name</th>
<th>Country id</th>
</tr>
</thead>
<tbody>
<tr v-for="(subcategory, index) in citylist" :key="subcategory.id">
<td>{{ index + 1 }}</td>
<td>{{ subcategory.name }}</td>
<td>{{ subcategory.category_id }}</td>
</tr>
</tbody>
</table>
<h3>Add City</h3>
<form v-on:submit.prevent = "createPost">
<select v-model="countryid" name="country" class="form-control" #change="myFunction()">
<option countryid disabled>Select Country</option>
<option v-for="category in categories" v-bind:value='category.id' v-text="category.name">{{category.name}}</option>
</select>
<div class="form-group">
<label for="add-name">Name</label>
<input v-model="subcategory.name" class="form-control" required />
</div>
<button type="submit" class="btn btn-xs btn-primary">Add City</button>
<!-- <button v-on:click="setPostId()">click</button> -->
<router-link class="btn btn-xs btn-warning" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<script>
export default {
data: function () {
return {
categories: [],
category: '',
countryid:'',
subcategories: [],
subcategory: {name: '', category_id: ''}
};
},
mounted(){
this.loadCategories()
},
created: function() {
let uri = 'http://localhost:8000/cities/';
Axios.get(uri).then((response) => {
this.subcategories = response.data;
});
},
computed: {
citylist: function(){
if(this.subcategories.length) {
return this.subcategories;
}
}
},
methods: {
myFunction: function() {
console.log(this.countryid)
},
loadCategories(){
axios.get('/api/categories')
.then(response => this.categories = response.data)
.catch(error => console.log(error))
},
createPost: function() {
let uri = 'http://localhost:8000/addsubcategory/';
Axios.post(uri, this.subcategory).then((response) => {
this.$router.push({name: 'City'})
})
}
}
}
</script>
you can make drop down
<select v-model="fruit" id="deptList">
<option v-for="company_master in company_masters.data" v-bind:value="company_master.CompanyId"> {{company_master.CompanyName}}
</option>
</select>
and call the data with axios like
axios.get("api/company_master").then(response => (this.company_masters = response.data));
also define
company_masters:[],
fruit:'',
app.js
var Users = {
template: `
<tr v-for="list in UsersData">
<th>{{ list.idx }}</th>
<td>{{ list.id }}</td>
</tr>
`,
data: function () {
return {
UsersData //get data from query
}
}
}
var mainview = new Vue({
el: "#mainview",
components: {
'users': Users
},
method: {}
})
layout.blade.php
<body>
<div class="container">
<aside>...</aside>
<main id="mainview">
#section('content')
#show
</mainview>
</div>
</body>
index.blade.php
#extends('layout')
#section('content')
<table>
<thead>
<tr>
<th>IDX</th>
<th>ID</th>
</tr>
</thead>
<tbody>
<users></users>
</tbody>
</table>
#endsection
ERROR LOG from chrome console
[Vue warn]: Cannot use v-for on stateful component root element because it renders multiple elements:
<tr v-for="list in UsersData">
<th>{{ list.idx }}</th>
<td>{{ list.id }}</td>
</tr>
vue.js:525 [Vue warn]: Multiple root nodes returned from render function. Render function should return a single root node.
(found in component )
How should I fix code?
Your template has to have one root element. It's just one rule you cannot break. Since you're making a table, it would make sense to make tbody the root element.
var Users = {
template: `
<tbody>
<tr v-for="list in UsersData">
<th>{{ list.idx }}</th>
<td>{{ list.id }}</td>
</tr>
</tbody>
`,
data: function () {
return {
UsersData //get data from query
}
}
}
index.blade.php
#extends('layout')
#section('content')
<table>
<thead>
<tr>
<th>IDX</th>
<th>ID</th>
</tr>
</thead>
<users></users>
</table>
#endsection
For the lazy: Vue interprets the root element having a v-for loop on it as producing multiple root level elements (a nono in modern JS frameworks).
Just wrap your template in a superfluous blank <div>. 👌
I struggled with this, until I realized you can just add a section tag over everything in template and then this error goes away.
Example
//gives error
<template>
<div classname="allFutures" v-for="(items, index) in arr">
<Future title="Shee" />
</div>
</template>
// do this instead
<template>
<section id="main" class="main-alt">
<div classname="allFutures" v-for="(items, index) in arr">
<Future title="Shee" />
</div>
</section>
</template>
I am implementing datatable. I can see data is coming from database in xhr using developer tools but it is not showing in the table. Please tell me what is the problem with my code.
#section Body{
<div class="row">
<div class="col-md-9">
<div class="block">
<div class="content">
<table cellpadding="0" cellspacing="0" width="100%" class="table" id="myDbTable">
<thead>
<tr>
<th data-hide>ID</th>
<th data-hide >Name</th>
<th data-hide >E-mail</th>
<th data-hide>Phone</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
}
#section Scripts{
<script>
var DataColumnsCount = 4;
//***Start Fatching Data for datatable *** start //
function fetchEmployeeTableList() {
$('#myDbTable').DataTable({
"columns": [
{"data" : "Id"},
{ "data": "Name" },
{ "data": "Email" },
{ "data": "Phone" }
]
}
);
}
$.ajax({
type: 'GET',
url: "#Url.Action("GetEmployees","Employee")",
dataType: 'json',
data: "{}",
dataSrc: 'DataSet',
success: fetchEmployeeTableList});
</script>
}
Please help me in this regard.