change button switch toggle in vuejs - vue.js

I have a button that when I click it changes the status of the record, but when I update, the color of the button does not change, if I refresh the page if it changes, how can I make the button change when I update the record
Table:
<div class="card-body">
<table id="tblProfiles" class="table table-bordered table-hover dt-responsive">
<thead>
<tr>
<th>Description</th>
<th>Status</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr v-for="(profile, index) in profiles" :key="index">
<td>{{ profile.description }}</td>
<td>
<button
class="btn-sm"
:class="[profile.status == 1 ? 'btn-success' : 'btn-danger']"
#click="statusUpdate(profile.id)"
>{{profile.status == 1 ? 'Active' : 'Inactive'}}
</button>
</td>
<td>
<button class="btn btn-info btn-sm">Details</button>
</td>
</tr>
</tbody>
</table>
</div>
Method:
// ...
statusUpdate: async function(id) {
try {
const response = await profileService.activateDesactivate(id);
console.log(response);
} catch (error) {
console.log(error);
}
}

Send profile object insted of id prop:
<div class="card-body">
<table id="tblProfiles" class="table table-bordered table-hover dt-responsive">
<thead>
<tr>
<th>Description</th>
<th>Status</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr v-for="(profile, index) in profiles" :key="index">
<td>{{ profile.description }}</td>
<td>
<button
class="btn-sm"
:class="[profile.status == 1 ? 'btn-success' : 'btn-danger']"
#click="statusUpdate(profile)"
>{{profile.status == 1 ? 'Active' : 'Inactive'}}
</button>
</td>
<td>
<button class="btn btn-info btn-sm">Details</button>
</td>
</tr>
</tbody>
</table>
</div>
Method receives profile objetc and update it as you want. In your case status prop changes the color class of your button.
statusUpdate: async function(profile) {
try {
const response = await profileService.activateDesactivate(profile.id);
profile.status = 1;
console.log(response);
} catch (error) {
console.log(error);
}
},

Related

How to update the value in particular TextBox in Table row using change event in Vue Js

While change the Quantity in the particular TextBox in table row, need to update the calculated Value (Unit Price * Quantity) in another TextBox in the same row.
Template
<template>
<div class="container col-md-12">
<h3>Product List</h3>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Product Name</th>
<th scope="col">Net Content</th>
<th scope="col">MRP</th>
<th scope="col">Discount</th>
<th scope="col">Unit Price</th>
<th scope="col">Quantity</th>
<th scope="col">Value</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<template v-for="group in productgroups">
<tr>
<td colspan="9"><b>{{ group.groupName }}</b></td>
</tr>
<tr v-for="(product, index) in filteredProducts(group.id)" v-bind:key="product.id">
<td class="text-center" scope="row">{{ index + 1 }}</td>
<td>{{ product.productName }}</td>
<td class="text-right">{{ product.netContent }} {{ product.uommasters.uomId }}</td>
<td class="text-right">{{ product.mrp }}</td>
<td class="text-right">{{ product.discountAmount }}</td>
<td class="text-right">
<input type="number" class="form-control" v-bind:id="`salePrice${product.id}`" required name="salePrice" v-model="product.salePrice" readonly />
</td>
<td>
<input type="number" class="form-control" v-bind:id="`quantity${product.id}`" required name="quantity"
#change="getValue(product.id, product.salePrice, product.quantity)" v-model="product.quantity" />
</td>
<td>
<input type="number" class="form-control" :id="'productValue'+product.id" required name="productValue" v-model="product.productValue" readonly />
</td>
</tr>
</template>
</tbody>
</table>
</div>
Script
<script>
import moment from 'moment';
import ProductDataService from "../../services/ProductDataService";
import ProductgroupDataService from "../../services/ProductgroupDataService";
export default {
name: "product-index",
data() {
return {
products: [],
productgroups: [],
productTotal: 0,
};
},
methods: {
getValue(productId, price, qty) {
this.productTotal = price * qty;
alert(this.productTotal);
this.product.discountAmount = this.productTotal;
alert(this.product.discountAmount);
},
filteredProducts(groupId) {
var fproducts = this.products.filter(function(product) {
return product.groupCode == groupId;
});
return fproducts;
},
retreiveProducts() {
ProductDataService.getAll()
.then(response => {
this.products = response.data;
})
.catch(e => {
alert(e);
console.log(e);
})
},
retreiveGroups() {
ProductgroupDataService.getAll()
.then(response => {
this.productgroups = response.data;
})
.catch(e => {
console.log(e);
});
},
},
created() {
this.retreiveProducts();
},
mounted() {
this.retreiveGroups();
},
};
I have populated the products from database using API by grouping and need to update the value while change the quantity using onchange event.

How to add pagination in api driven vue app?

I have a get api that looks like this -
this.$API +"api/v1/puzzles/getAll?page=" + this.pageNo +"&limit=" + this.pageLimit,
It accepts two params page and limit. How to make pagination for this get api ?
My html code:
<md-card>
<md-card-header data-background-color="green">
<h4 class="title">List of Puzzles</h4>
<p class="category">The list of puzzles you have uploaded</p>
</md-card-header>
<md-card-content class="justify-content-center">
<table>
<thead>
<tr>
<th><b>Puzzle Question</b></th>
<th><b>Option 1</b></th>
<th><b>Option 2</b></th>
<th><b>Option 3</b></th>
<th><b>Option 4</b></th>
<th><b>Correct Answer</b></th>
<th><b>Action</b></th>
</tr>
</thead>
<tbody>
<tr v-for="(data, index) in puzzleList.puzzles" :key="index">
<td class="q-img"><img :src="data.qImage" alt="" /></td>
<td
class="ans-img"
v-for="(collection, index) in data.qOptions"
:key="index"
>
<img :src="collection.oImage" alt="" />
</td>
<td style="padding-left: 32px">
<h2>{{ data.qAnswer }}</h2>
</td>
<router-link to="/editPuzzle"
><td style="padding-top: 70px">
<button class="btn btn-success">Edit</button>
</td></router-link
>
<td>
<button
v-on:click="deletePuzzle(data.id)"
class="btn btn-danger"
>
Delete
</button>
</td>
</tr>
</tbody>
<!-- <pagination v-model="pageNo" :pageLimit="500" #paginate="myCallback"/> -->
</table>
</md-card-content>
</md-card>
data() {
return {
siteURL: this.$axios.defaults.siteURL,
puzzleList: [],
pageNo: 1,
pageLimit: 4,
token: localStorage.getItem("_token"),
puzzleId: "",
};
},
I tried to use third-party packages but couldnt make it work. I have taken 2 variables inside return above like pageNo: 1 and pageLimit: 4 and haven't found any solution anywhere with this type of api. Please show me detaily, how should I implement this ?
Update:
<table>
<thead>
<tr>
<th><b>Puzzle Question</b></th>
<th><b>Option 1</b></th>
<th><b>Option 2</b></th>
<th><b>Option 3</b></th>
<th><b>Option 4</b></th>
<th><b>Correct Answer</b></th>
<th><b>Action</b></th>
</tr>
</thead>
<tbody>
<tr v-for="(data, index) in puzzleList.puzzles" :key="index">
<td class="q-img"><img :src="data.qImage" alt="" /></td>
<td
class="ans-img"
v-for="(collection, index) in data.qOptions"
:key="index"
>
<img :src="collection.oImage" alt="" />
</td>
<td style="padding-left: 32px">
<h2>{{ data.qAnswer }}</h2>
</td>
<router-link to="/editPuzzle"
><td style="padding-top: 70px">
<button class="btn btn-success">Edit</button>
</td></router-link
>
<td>
<button
v-on:click="deletePuzzle(data.id)"
class="btn btn-danger"
>
Delete
</button>
</td>
</tr>
<pagination
v-model="pageNo"
:pageLimit="4"
#paginate="myCallback"
/>
</tbody>
</table>
methods:{
myCallback(e) {
this.pageNo = e;
this.getPuzzle();
},
getPuzzle: function () {
this.$axios
.get(
this.$API +
"api/v1/puzzles/getAll?page=" +
this.pageNo +
"&limit=" +
this.pageLimit,
{
headers: {
Authorization: "Bearer " + this.token,
},
}
)
.then((res) => {
this.puzzleList = res.data.data;
this.puzzleId = res.data.data.puzzles[0].id;
console.log(this.puzzleId);
});
},
any third-party of pagination api has the property that you should set the current page and the limit or total, the main of pagination is that current page,page size, total and the callback of current page changes, the lifecycle is that:
init: you fetch the api with the params(currentpage, pagesize) to get data, then according to your response ,you can get the total count of your data
use the 1 step response like total count, and give it to your pagination component
don't forget to declare your onChange callback ,which the pagination component necessary to use, in the callback ,you just change the current page which user click and fetch your api again to get the new data.

How to get the ID from a table inside a b-modal and display on the page in VUEJS

I am facing issue where i want to get the ID from the table when clicking on the button inside a modal and display it on the main page.
Here is the HTML code
<template>
<div class="hello">
<p>Selected id :</p>
<b-button class="mt-2" variant="primary" v-b-modal.modal-xl>
Select codes
</b-button>
<b-modal id="modal-xl" size="lg" centered hide-footer="true">
<table class="table sortable" data-page-list="[10, 25, 50, 100, all]">
<thead>
<tr>
<th>ID</th>
<th>Code</th>
<th>Button</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2222</td>
<td>
<b-button variant="primary">Select</b-button>
</td>
</tr>
<tr>
<td>2</td>
<td>33333</td>
<td>
<b-button variant="primary">Select</b-button>
</td>
</tr>
<tr>
<td>3</td>
<td>4444</td>
<td>
<b-button variant="primary">Select</b-button>
</td>
</tr>
</tbody>
</table>
</b-modal>
</div>
</template>
Here is the Codesandbox for it.
Any help much appreciated.
One way to do that is to save the selected ID as the local state. In addition, I'd recommend using v-for and an array to store the codes list, and then you can pass the id to the event:
<template>
<div class="hello">
<p>Selected id: {{ selected }}</p>
<b-button class="mt-2" variant="primary" v-b-modal.modal-xl>
Select codes
</b-button>
<b-modal id="modal-xl" size="lg" centered hide-footer="true">
<table class="table sortable" data-page-list="[10, 25, 50, 100, all]">
<thead>
<tr>
<th>ID</th>
<th>Code</th>
<th>Button</th>
</tr>
</thead>
<tbody>
<tr v-for="code in codes" :key="code.id">
<td>{{ code.id }}</td>
<td>{{ code.code }}</td>
<td>
<b-button variant="primary" #click="onSelected(code.id)">Select</b-button>
</td>
</tr>
</tbody>
</table>
</b-modal>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
data() {
return {
codes: [
{id: 1, code: 2222},
{id: 2, code: 3333},
{id: 3, code: 4444},
],
selected: null
}
},
methods: {
onSelected: function(id) {
this.selected = id;
}
}
};
</script>
You can check out a working example here.

Is Vue 3 backwards compatible with Vue 2?

In different posts around the internet (for example this one) I found that Vue 2 code should work with Vue 3 but for me it does not. For example I have simple component
<template>
<div class="overflow-x-auto bg-white rounded-lg shadow overflow-y-auto relative">
<table class="table">
<thead>
<tr class="text-left">
<th>
<label>
<input type="checkbox">
</label>
</th>
<th>User ID</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Gender</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<label>
<input type="checkbox" name="1">
</label>
</td>
<td> <span>{{ id }}</span> </td>
<td> <span>Cort</span> </td>
<td> <span>Tosh</span> </td>
<td> <span>{{ email }}</span> </td>
<td> <span>Male</span> </td>
<td> <span>327-626-5542</span> </td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
id: 1,
email: 'test#mail.com'
}
},
mounted() {
alert('mounted');
},
created() {
alert('created');
}
};
</script>
The table is generated just fine, but both mounted and created not fired when component made. Also the email and id not shown. Only the table is shown.
Your code works:
Vue.createApp({
data() {
return {
id: 1,
email: 'test#mail.com'
}
},
created() {
alert('created')
},
mounted() {
alert('mounted')
}
}).mount('#app')
<script src="https://unpkg.com/vue#next"></script>
<div id="app" class="overflow-x-auto bg-white rounded-lg shadow overflow-y-auto relative">
<table class="table">
<thead>
<tr class="text-left">
<th>
<label>
<input type="checkbox">
</label>
</th>
<th>User ID</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Gender</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<label>
<input type="checkbox" name="1">
</label>
</td>
<td> <span>{{ id }}</span> </td>
<td> <span>Cort</span> </td>
<td> <span>Tosh</span> </td>
<td> <span>{{ email }}</span> </td>
<td> <span>Male</span> </td>
<td> <span>327-626-5542</span> </td>
</tr>
</tbody>
</table>
</div>

Data is not showing up in html

I am running into a issue with showing the data from my variable, itemListPrice. I have checked in the console and the data is populated into the itemListPrice, but its not showing up in my html, am I loading it all wrong?
Here is the markup
<div id="app2">
<div id="TableContainer" style="width:798px !important">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<td><label>Catalog Name</label></td>
</tr>
</thead>
<tbody>
<tr>
<td>{{ currentCatalogName }}</td>
</tr>
</tbody>
</table>
<table class="table">
<thead>
<tr>
<td><label>Item Name</label></td>
</tr>
</thead>
<tbody>
<tr>
<td> {{ itemPriceList.Name }}</td>
</tr>
</tbody>
</table>
<table class="table">
<thead>
<tr>
<td colspan="2"><label>Item List</label></td>
</tr>
</thead>
<tbody>
<tr>
<td width="575px">${{ itemPriceList.ItemListPrice }}</td>
<td>${{ itemPriceList.ItemListPrice }}</td>
</tr>
</tbody>
</table>
<table class="table">
<thead>
<tr>
<td colspan="3"><label>Item Features</label></td>
<td></td>
</tr>
</thead>
<tbody>
<template v-for="item in itemPriceList.ItemFeatures">
<tr v-if="item.FeatureQuantity != 0">
<td width="250px">{{ item.FeatureName }}</td>
<td>{{ item.FeatureQuantity }}</td>
</tr>
</template>
</tbody>
</table>
<table class="table">
<thead>
<tr>
<td><label>Item IAM</label></td>
</tr>
</thead>
<tbody>
<tr>
<td>{{ itemPriceList.ItemIAM }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
and here is my code
new Vue({
el: '#app2',
beforeCreate: function () {
StartBusyIndicator("#ItemPriceListWindow");
},
created: function () {
this.GetItemDetails();
},
mounted: function () {
StopBusyIndicator("#ItemPriceListWindow");
},
data: {
itemPriceList: [],
orderItems: currentOrderItems,
currentCatalogName: currentCatalog,
priceList: null
},
methods: {
GetItemDetails: function () {
TryCatch(function() {
let result = GetItemPriceDetails();
this.itemPriceList = result;
priceList = result;
});
},
GetOrderItems: function () {
},
OptionPriceSplitter: function (optionprice) {
return TryCatch(function() {
let sentenceSplit = optionprice.split('& ');
let comp = '';
for (let i = 0; i < sentenceSplit.length; i++) {
comp += sentenceSplit[i] + '\n';
}
return sentenceSplit;
});
},
GlobalListPriceCalculation: function (globalgroupid) {
return TryCatch(function() {
let listPrice = 0.00;
let priceList = this.itemPriceList;
let result = priceList.GlobalListPrices.filter(function(item) {
if (item.GlobalGroupID == globalgroupid) {
listPrice = listPrice + item.Price;
}
});
if (listPrice == 0) {
listPrice = "";
} else {
listPrice = "$" + listPrice.toFixed(2);
}
return listPrice;
});
}
}
});
assuming TryCatch(cb) is something along the lines of
function TryCatch(cb){ let x = null; try { x = cb() } catch(e) {} return x; }
you loose 2 important things:
this (you could bind it via cb.call(this))
utterly usefull error messages
furher points:
I have checked in the console
checkout the excellent browser plugin for ff and chrome vue-devtools
itemPriceList = []
you initalize itemPriceList as array, use it as array item in itemPriceList, but also use it as object {{ itemPriceList.Name }} - what shall it be ?