Reputation: 87
I am fetching the JSON data(Orders) from REST API and displaying in a dynamic HTML table using Vue js. I have a "Print" button for each row in the table. The purpose of the button is printing the data of the row in a structure, basically a bill. For that, I want to highlight the newly added row until the Print button is clicked by the user. How do I achieve this? I'm refreshing the table every minute. This is my code.
<tr v-for="orders, index in orders">
<th scope="row">{{ index + 1 }}</th>
<td>{{ orders.id }}</td>
<td>{{ orders.billing.first_name + " " +orders.billing.last_name }}</td>
<td>{{ orders.date_created }}</td>
<td>{{ orders.billing.phone}}</td>
<td>{{ orders.billing.address_1 + ", " + orders.billing.address_2 + ", " + orders.billing.city + orders.billing.postcode }}</td>
<td>{{ orders.line_items.name}}</td>
<td>{{ orders.total}}</td>
<td><button class="btn btn-primary" (click)="printBill(data)">Print</button></td>
</tr>
</tbody>
</table>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
orders: []
},
mounted: function() {
axios.get('https://localhost/Site/wp-json/wc/v3/orders?consumer_key=KEY&consumer_secret=KEY1')
.then(response => {
this.orders = response.data;
console.log(response);
})
.catch(error => {
console.log(error);
});
},
})
</script>
Upvotes: 2
Views: 849
Reputation: 3665
Add an isPrinted
flag to each row of data, making sure you retain this if rows had been previously flagged. Also, call the API every minute.
mounted: function() {
// Call the API the first time
this.refreshData()
// Then call the API every minute
this.setIntervalId = setInterval(this.refreshData, 60000)
},
beforeDestroy: function() {
// Stop refreshing data after the component is destroyed!
clearInterval(this.setIntervalId)
}
methods: {
// Extract refresh logic into a method
refreshData () {
axios.get('https://localhost/Site/wp-json/wc/v3/orders?consumer_key=KEY&consumer_secret=KEY1')
.then(response => {
// Note the orders we previously flagged as printed, so we can reapply the flag after refreshing
const previouslyFlaggedIds = this.orders.filter(x => x.is_printed).map(x => x.id);
this.orders = response.data.map(x => ({...x, is_printed: previouslyFlaggedIds.find(y => y === x.id) != null}));
})
.catch(error => {
console.log(error);
});
}
}
Use this to style the rows
<tr
v-for="(order, index) in orders"
:key="order.id"
:class="{highlight: !order.is_printed}"
>
Set is_printed when rows are printed.
<td><button class="btn btn-primary" @click="printBill(order)">Print</button></td>
methods: {
printBill(order) {
order.is_printed = true
}
}
Upvotes: 1
Reputation: 4801
I wrote a small example, have a look:
<template>
<div id="app">*
<tr
v-for="(order, index) in orders"
:key="index"
:class="{highlight: orders[index].isPrinted === undefined}"
>
<th scope="row">{{ index + 1 }}</th>
<td>{{ order.name }}</td>
<td>{{ order.something}}</td>
<td>
<button class="btn btn-primary" @click="printBill(index)">Print</button>
</td>
</tr>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
orders: []
};
},
methods: {
printBill(index) {
//code to print the bill
//change flag
this.$set(this.orders[index], "isPrinted", true);
}
},
mounted() {
//axios request - data sample
this.orders = [
{
name: "first",
something: "whatever"
},
{
name: "second",
something: "whatever"
},
{
name: "third",
something: "whatever"
},
{
name: "fourth",
something: "whatever"
},
{
name: "fifth",
something: "whatever"
}
];
}
};
</script>
<style>
.highlight {
background-color: blue;
color: white;
}
th {
width: 20%;
}
td {
width: 20%;
}
</style>
You can run it here.
As you can see that I am adding a flag to elements in orders array whenever printBill
method runs.
By tracking newly added property we can conditionally display highlight class.
Upvotes: 1