I'm fetching data into the table and on clicking any table row it open a nested colspan inside table row.
I want to close previous table row if i click on another table row (Like accordion does )
This is my Vue File
{{index+1}}
{{statement.paper_quality_id.paper_quality}} -
{{statement.paper_size_id.length}} X {{statement.paper_size_id.width}} -
{{statement.paper_brand_id.paper_brand}} -
{{statement.thickness}}
{{Math.ceil((statement.in_total_before - statement.total_out_before)/500)}}
<td>
<div class="row">
<div
class="col-md-4 text-center"
>{{Math.floor((statement.total_sheets_in_range)/500)}}</div>
<div
class="col-md-4 text-center"
>{{Math.floor((statement.total_sheets_in_range)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div
class="col-md-4 text-center"
>{{Math.floor((statement.total_outward_range)/500)}}</div>
<div
class="col-md-4 text-center"
>{{Math.floor((statement.total_outward_range)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div class="col-md-4 text-center">
{{
Math.floor((((statement.in_total_before - statement.total_out_before) + (statement.total_sheets_in_range)) - statement.total_outward_range)/500)
}}
</div>
<div class="col-md-4 text-center">
{{
Math.floor((((statement.in_total_before - statement.total_out_before) + (statement.total_sheets_in_range)) - statement.total_outward_range)%500)
}}
</div>
</div>
</td>
</tr>
<tr :id="'show_'+index" style="display : none">
<td colspan="6">
<table class="table table-hover">
<tr>
<th>Date</th>
<th>Opening</th>
<th>Inward</th>
<th>Outward</th>
<th>Balance</th>
</tr>
<tr v-for="(_statement,index) in statements_details">
<td>{{_statement.date}}</td>
<td>
<div class="row">
<div
class="col-md-3 text-center"
>{{Math.ceil((_statement.opening.total_in - _statement.opening.total_out)/500)}}</div>
<div
class="col-md-3 text-center"
>{{Math.ceil((_statement.opening.total_in - _statement.opening.total_out)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div class="col-md-3 text-center">{{Math.ceil((_statement.inward)/500)}}</div>
<div class="col-md-3 text-center">{{Math.ceil((_statement.inward)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div
class="col-md-3 text-center"
>{{Math.ceil((_statement.outward)/500)}}</div>
<div
class="col-md-3 text-center"
>{{Math.ceil((_statement.outward)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div
class="col-md-3 text-center"
>{{Math.ceil((_statement.outward)/500)}}</div>
<div
class="col-md-3 text-center"
>{{Math.ceil((_statement.outward)%500)}}</div>
</div>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
This is my js file
PostLedgerID(e) {
e.preventDefault();
const AccountDetail = {
id: this.id,
start_date: this.start_date + ' 00:00:00.957761',
end_date: this.end_date + ' 00:00:00.957761'
}
var vm = this;
axios.post('/Statement/', AccountDetail)
.then((response) => {
console.log(response)
vm.statements = response.data;
}).catch((err) => {
console.log(err)
});
},
//Show Hide Nested Table
statementDetail(rowid, paper_id, brand_id, size_id, thickness) {
const userDetail = {
account_access_key_id: $('#ledger_id').val(),
start_date: this.start_date + ' 00:00:00.957761',
end_date: this.end_date + ' 00:00:00.957761',
paper_quality_id: paper_id,
paper_brand_id: brand_id,
paper_size_id: size_id,
thickness: thickness
}
axios.post('/StatementDetail/', userDetail)
.then((response) => {
console.log(userDetail)
$('#show_' + rowid).toggle();
this.statements_details = response.data;
}).catch((err) => {
console.log(err)
});
}
Related
I have 2 pages, one has a list of products and the other one has a bunch of data for that product. There is also a drop-down in the second page.
The problem I'm having is that I'm struggling to get the drop-down to have the selected product selected.
So for example, if I select product 1 from the first page then on the second page the drop-down will show product 1 and if I select product 2 then the drop-down will show product 2.
Here is my code for productIndex.vue
<template>
<div>
<div class="content-header">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Product Index</h3>
</div>
<div class="card-body p-0">
<table class="table table-sm table-hover">
<thead>
<tr>
<th>ID</th>
<th>Product Name</th>
<th style="width: 180px;"></th>
</tr>
</thead>
<tbody>
<tr v-for="product in products">
<td>{{ product.id }}</td>
<td>{{product.name}}</td>
<td class="text-right">
<a #click="goToProductData(product.id)" class="btn btn-xs btn-primary">
Data
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['products'],
data() {
return {
}
},
methods: {
goToProductData(product_id){
localStorage.setItem('product', product_id);
window.location = `/product-data`;
}
},
}
</script>
and here is my productData.vue
<template>
<div>
<div class="content-header">
<div class="container">
<div class="card">
<div class="card-body">
<div class="row mb-2">
<div class="col-sm-6">
<label for="product_id_select">Product</label>
<select id="product_id_select" class="form-control select2" style="width: 100%;">
<optgroup v-for="product in selectProducts" :label="customer.text">
<option v-for="p in product.children" :value="p.id">{{ p.text }}</option>
</optgroup>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['products'],
data() {
return {
}
},
computed: {
selectProducts() {
let select2Options = [];
Object.keys(this.products).forEach(product => {
let productOptions = [];
this.products[product].forEach(p => {
productOptions.push({ id: p.id, text: p.name });
});
select2Options.push({
text: product,
children: productOptions
});
});
return select2Options;
}
}
}
</script>
You forgot to add the v-model to the select in the second page. You can find some example here.
Your code should be something like:
<select id="product_id_select" v-model="selectedProductId" class="form-control select2" style="width: 100%;">
where selectedProductId is a value in your data (or a computed property) that contains the value inserted into the local storage in the first page
I'm trying to calculate the quantity of items in my vue. The problem I'm having is that my computed property isn't picking up my object, because my thinking was as you can see with the commented out section is that I was going to loop through it and calculate the quantity, but since I'm not able to grab productItems I'm not able to loop through it.
Here is my code
<template>
<div class="content-header">
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-lg-12">
<table class="table">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Qty</th>
</tr>
</thead>
<tbody>
<tr v-for="item in products">
<td>
{{ item['name'] }}
</td>
<td>
<input style="width: 100px; margin-left: 0; display: inline"
type="number" class="form-control"
v-model="productItems[item['name']]['unit']"
>
</td>
</tr>
<tr>
<td></td>
<td>
Consumption total: {{ consumptionTotal }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default{
props: [],
data(){
return {
productItems: {}
},
computed:{
consumptionTotal(){
console.log(this.productItems);
// return Object.keys(this.productItems).reduce((carry, item) => {
// carry += Number(this.productItems[item]['unit'])
// return carry;
// }, Number(0));
},
},
watch: {
},
methods: {
},
mounted() {
}
}
</script>
Try below steps. Hopefully it will helps you.
Step 1: productItems should be an array
Step 2: Calculate functions be like
computed: {
consumptionTotal () {
return this.productItems.reduce((total, item) => {
total += item.unit
return total
}, Number(0))
}
}
Step 3: HTML template will be like
<div class="content-header">
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-lg-12">
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Qty</th>
</tr>
</thead>
<tbody>
<tr v-for="item in productItems" :key="item.id">
<td>{{item.id}}</td>
<td>
{{item.name}}
</td>
<td>
<input style="width: 100px; margin-left: 0; display: inline" type="number" class="form-control" :value="item.unit">
</td>
</tr>
<tr>
<td></td>
<td>
Consumption total: {{ consumptionTotal }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
DEMO
I'm trying to compare prices from last year and this year and the problem I'm getting is this:
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value
I understand what it's saying but I'm not sure how to solve it.
Here is my code:
<template>
<div class="content-header">
<div class="container">
<div class="row">
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<div class="row mb-2">
<div class="col-sm-12">
<label for="year_select">Select Year</label>
<select id="year_select" #change="getYearComparison()" class="form-control" style="width: 100%;" v-model="yearSelect">
<option v-for="year in years" :value="year.id">
{{ year.year }}
</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-lg-12">
<div class="row">
<div class="col-lg-12">
<div class="row">
<div class="col-lg-12">
<table class="table">
<thead>
<tr class="text-center">
<th colspan="4" style="border-right: #dee2e6 solid 1px">
Previous Year
</th>
<th colspan="3" style="border-right: #dee2e6 solid 1px">
This year
</th>
<th colspan="2">
Variance
</th>
</tr>
</thead>
<tr v-for="c in compare">
<td>
{{ c.prev_price }}
</td>
<td>
{{ c.curr_price }}
</td>
<td style="border-right: #dee2e6 solid 1px">
{{ c.v_price }}
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['compare'],
data(){
return {
years: [],
tariffSelect: null
}
},
computed: {
},
methods: {
getYears(){
axios.get('/api/years/getYears').then(response => {
this.years = response.data.years;
});
},
getYearComparison(){
axios.get(`/api/product/${this.tariffSelect}/comparison`).then(response => {
this.compare = response.data.compare;
})
}
},
mounted(){
this.getYears();
}
}
</script>
compare is a prop, meaning that it's to be transferred to your component, the "child" by another component (or the Vue app), the "parent". On the other end, your child component should communicate a value change to its parent using an event.
In your parent component, you can do this:
<template>
<child-component :compare="compare" #updateCompare="compare = $event"/>
</template>
<script>
export default {
data() {
return { compare: '' }; // Put a default value here that makes sense
}
};
</script>
And in your child component, you need to emit the event, so you can replace this line:
this.compare = response.data.compare;
By this one:
this.$emit('updateCompare', response.data.compare);
You can take a look at the documentation for events.
I working on form which has nested form groups & form arrays but I am not able to bind values in ts.
I am new to angular so dont have much clarity on formgroup and form arrays.
below json can have multiple arrays within formgroups and nested form arrays within form group.
Here is the sample example which i want to execute and make below json structure from this form
Json using this form :
{
ip:'1.2.3.4',
create_adjacency:{
customerName:'ABC',
traffic_group:[{
_display_name:'DEF',
traffic_group_limits:{
calls:'23' }
}]
}
}
HTML -
<div class="page-container pb-25 ">
<form [formGroup]="firstFormGroup">
<div class="form-group custom-input select-custom-prime">
<label>IP</label>
<input
placeholder="Select"
formControlName="ip"
/>
</div>
<div class="row mb-20" formGroupName="create_adjacency">
<div class="col-xl-4 col-lg-6 col-md-6">
<div
class="form-group custom-input select-custom-prime"
>
<label>Customer Name</label>
<input
placeholder="Select"
formControlName="customerName"
/>
</div>
</div>
<div formArrayName="traffic_group">
<div class="col-xl-3 col-lg-6 col-md-6">
<div
class="form-group custom-input mr-10 select-custom-prime" >
<label>Traffic group Name</label>
<input
formControlName="_display_name"
/>
</div>
</div>
<table
class="mt-30 table table-striped table-bordered wd-98"
>
<thead>
<tr>
<th>Traffic Group Name</th>
<th>Concurrent Calls</th>
</tr>
</thead>
<tbody formGroupName="traffic_group_limits">
<tr>
<td>
<div class="">
<div
class="form-group custom-input select-custom-prime"
>
<input
pInputText
autofocus
disabled
type="text"
class="form-control"
/>
</div>
</div>
</td>
<td>
<div class="">
<div
class="form-group custom-input select-custom-prime"
>
<input
formControlName="calls"
pInputText
autofocus
class="form-control"
/>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</form>
</div>
Ts code -
this.firstFormGroup = this.formBuilder.group({
ip: [''],
create_adjacency: this.formBuilder.group({
customerName: ["", Validators.required],
traffic_groups: this.formBuilder.array([this.traffic_groups])
})
});
get traffic_groups(): FormGroup {
return this.formBuilder.group({
_display_name: ["", Validators.required],
traffic_group_limits: this.formBuilder.group({
"call-appearances": ["", Validators.required]
})
});
}
In my opinion, as much angular has their own way of doing this, it might be a little intimidating to a beginner. So I prefer breaking down the formgroups and then constructing the final json from all the forms all together.
.html
<div class="page-container pb-25 ">
<form [formGroup]="firstFormGroup">
<div class="form-group custom-input select-custom-prime">
<label>IP</label>
<input
placeholder="Select"
formControlName="ip"
/>
</div>
<div class="row mb-20" [formGroup]="adjacencyFormGroup">
<div class="col-xl-4 col-lg-6 col-md-6">
<div
class="form-group custom-input select-custom-prime"
>
<label>Customer Name</label>
<input
placeholder="Select"
formControlName="customerName"
/>
</div>
</div>
<div [formGroup]="trafficFormGroup">
<div class="col-xl-3 col-lg-6 col-md-6">
<div
class="form-group custom-input mr-10 select-custom-prime" >
<label>Traffic group Name</label>
<input
formControlName="_display_name"
/>
</div>
</div>
<table
class="mt-30 table table-striped table-bordered wd-98"
>
<thead>
<tr>
<th>Traffic Group Name</th>
<th>Concurrent Calls</th>
</tr>
</thead>
<tbody [formGroup]="trafficGroupLimit">
<tr>
<td>
<div class="">
<div
class="form-group custom-input select-custom-prime"
>
<input
pInputText
autofocus
disabled
type="text"
class="form-control"
/>
</div>
</div>
</td>
<td>
<div class="">
<div
class="form-group custom-input select-custom-prime"
>
<input
formControlName="calls"
pInputText
autofocus
class="form-control"
/>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</form>
</div>
.ts
this.firstFormGroup = this.formBuilder.group({
ip: [''],
create_adjacency: [{}]
});
this.adjacencyFormGroup = this.formBuilder.group({
customerName: ["", Validators.required],
traffic_groups: [[]])
});
this.trafficFormGroup = this.formBuilder.group({
_display_name: ["", Validators.required],
traffic_group_limits: [{}]
});
this.trafficGroupLimit = this.formBuilder.group({
calls: [''],
});
function to create json
createFormJSON() {
this.trafficFormGroup.patchValue({
traffic_group_limits: this.trafficGroupLimit.value
});
this.adjacencyFormGroup.patchValue({
traffic_groups: this.allTrafficGroups // store all traffic groups in this array before patching
});
this.firstFormGroup.patchValue({
create_adjacency: this.adjacencyFormGroup.value,
});
}
I am working on Laravel + spark + vue js. Following is my code
app js
Vue.component('spark-emergency', {
data() {
return {
emergencies:[],
deleteEmergency:[],
editEmergency:[],
editEmergencyForm: new SparkForm({}),
deleteEmergencyForm: new SparkForm({}),
newEmergency: new SparkForm({
name: '',
type: '',
description:''
})
};
},
created() {
this.getEmergencies();
},
methods: {
getEmergencies() {
this.$http.get('/get-emergencies-plan-template')
.then(response => {
this.emergencies = response.data;
});
},
deleteEmergencyPlanTemplateConfirmation(emergency){
this.deleteEmergency = emergency
$('#modal-delete-emergency').modal('show');
},
deleteEmergencyPlanTemplate(){
Spark.delete(`/delete-emergencies-plan-template/${this.deleteEmergency.slug}`, this.deleteEmergencyForm)
.then(() => {
Bus.$emit('updateEmergencies');
$('#modal-delete-emergency').modal('hide');
});
},
createEmergencyPlanTemplate(){
Spark.post('/save-emergency-plan-template', this.newEmergency)
.then(() => {
this.newEmergency.name = '';
this.newEmergency.type = '';
this.newEmergency.description = '';
Bus.$emit('updateEmergencies');
});
},
editEmergencyPlanTemplate(emergency){
this.editEmergency = emergency
$('#modal-edit-emergency').modal('show');
},
updateEmergencyPlanTemplate(){
}
}
});
Blade file
<spark-emergency inline-template>
<div class="spark-screen container">
<div class="row">
<div class="col-md-12">
<!-- create new emergency -->
<div class="panel panel-default">
<div class="panel-heading">Create emergency</div>
<div class="panel-body">
<form class="form-horizontal" role="form"></form>
</div>
</div>
<!-- listing of emergencies -->
<div class="panel panel-default">
<div class="panel-heading">Emergencies Plan Template</div>
<div class="panel-body">
<table class="table table-borderless m-b-none">
<thead>
<th>Name</th>
<th></th>
</thead>
<tbody>
<tr v-for="emergency in emergencies">
<td>
<div class="btn-table-align">
#{{ emergency.name }}
</div>
</td>
<!-- Delete Button -->
<td>
<button class="btn btn-danger-outline" #click="deleteEmergencyPlanTemplateConfirmation(emergency)">
<i class="fa fa-times"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Edit Emergency Modal -->
<div class="modal fade" id="modal-edit-emergency" tabindex="-1" role="dialog"></div>
<!-- Delete Emergency Modal -->
<div class="modal fade" id="modal-delete-emergency" tabindex="-1" role="dialog"></div>
</div>
</div>
</div>
</spark-emergency>
Before adding add new and edit logic, it was working perfectly fine but after that Bus.$emit('updateEmergencies'); stopped working and now it is not working.
Any suggestions what can be the reason?