I have this table with checkboxes. I use computed property in <th> v-model to check all the checkboxes in <td>
The problem is with my development it is working perfectly, but in deployment/build, it shows the error below when I click the checkbox responsible for checking all the checkboxes.
this is my table:
<table id="table">
<tr>
<th style="text-align: center">
<input
type="checkbox"
name="tableCheckBox"
v-model="firstSelectAll"
/>
</th>
<th style="text-align: right">#</th>
<th>Name</th>
<th>Program</th>
<th>Iteration</th>
<th>Stream</th>
<th>Group</th>
</tr>
<tr
v-for="(data, index) in firstFetchUserData"
:key="data.ind_id"
:value="data.ind_id"
style="cursor: pointer"
>
<td class="td-checkbox">
<input
type="checkbox"
v-model="selected"
:value="data"
number
/>
</td>
<td>{{ data.program_name }}</td>
<td>{{ data.iteration_name }}</td>
<td>{{ data.stream_name }}</td>
<td>{{ data.group_name }}</td>
</tr>
</table>
and this is my computed property that manages to check all of the checkboxes in <td>
data: () => ({
selected: [],
firstFetchUserData: []
}),
computed:{
firstSelectAll: {
get: function () {
return this.firstFetchUserData
? this.selected.length == this.firstFetchUserData.length
: false;
},
set: function (value) {
var selected = [];
if (value) {
this.firstFetchUserData.forEach(function (user) {
selected.push(user);
});
}
this.selected = selected;
},
},
}
here you can see in this link Check all checkboxes vuejs, I reference my code to the highest upvote in answers.
Related
First I must say that I'm a complete newbie in coding and Vue it's the first framework I'm learning and I'm terrible working with arrays at the moment. In the practice I am doing I am displaying the first five elements of the array in a table (I've filtered them in a new variable to do the v-for).
Now I need to add a button that when clicked will show me a new row of the original array, but I'm a bit stuck on how to do it. As u may see in the code below, contactList is the variable that has all the data, but I have no clue how to link it to the filtered one to show more data when clicked.
<template>
<h1 class="display-1 text-primary">Contacts</h1>
<button type="button" class="btn btn-outline-primary btn-lg" #click="addRandom">Add random</button>
<div class="container container__pos">
<table class="table table-hover">
<thead>
<tr>
<th class="col col__style">Picture</th>
<th class="col col__style">Name</th>
<th class="col col__style">Popularity</th>
<th class="col col__style">Won an Oscar</th>
<th class="col col__style">Won an Emmy</th>
</tr>
</thead>
<tbody>
<tr v-for="(element, index) of contactListed" :key="index">
<td scope="row">
<img
:src="element.pictureUrl"
:alt="element.name + ` image`"
class="image"
/>
</td>
<td> {{ element.name }}</td>
<td>{{ element.popularity }}</td>
<td>{{ wonAward(element.wonOscar) }}</td>
<td>{{ wonAward(element.wonEmmy) }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import contacts from "./contacts.json";
export default {
data() {
return {
contactList: contacts,
contactListed: contacts.slice(0, 5),
};
},
methods: {
wonAward(element) {
if (element === true || element === true){
return "winner";
} else {
return "";
}
},
},
};
</script>
You can use a computed variable that holds the first N elements of the array, and have your button increment the value of N, like this:
<script>
import contacts from "./contacts.json";
export default {
data() {
return {
contactList: contacts,
nItems: 5
};
},
computed: {
contactListed() {
return this.contacts.slice(0, this.nItems)
}
},
methods: {
addRow() {
this.nItems++;
},
wonAward(element) {
if (element === true || element === true){
return "winner";
} else {
return "";
}
},
},
};
</script>
<template>
...
<button #click="addRow()" />
</template>
I have this simple table:
<v-simple-table>
<template v-slot:default class="my-20 py-20">
<thead>
<tr>
<th class="text-left">Attribute</th>
<th class="text-left">Operator</th>
<th class="text-left">Values</th>
</tr>
</thead>
<tbody>
<tr v-for="(ruleDetail, j) in ruleDetails">
<td>{{ ruleDetail.attribute_name }}</td>
<td>{{ ruleDetail.operator_name }}</td>
<td>{{ ruleDetail.value }}</td>
</tr>
</tbody>
</template>
</v-simple-table>
I would like to hide the row where
ruleDetail.attribute_name == Label batch
What is the best practice to do that?
//all from API
//this.ruleDetails = response.data.details
//tried to filter, but it's not working.
this.ruleDetails = response.data.campaigns.filter((item) => {
return item.attribute_name != 'Label batch'
})
Try to use includes in filter in computed property :
computed: {
filteredRules() {
return this.ruleDetails.filter((item) => !item.attribute_name.toLowerCase().includes(('Label batch').toLowerCase())
}
}
and then in templae:
<tr v-for="(ruleDetail, j) in filteredRules">
Your code is perfect and it should work. One suggestion, cross check response.data.campaigns to see if you are getting the proper response in this or not.
Working Demo as per the code you posted :
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
campaigns: [
{
attribute_name: 'UV Index (Current Weather)',
operator_name: 'Lesser number',
value: 7
},
{
attribute_name: 'Temperature (Current Weather)',
operator_name: 'Greater or equal number',
value: 17
},
{
attribute_name: 'Label batch',
operator_name: 'Equal numbers',
value: 66235
}
],
ruleDetails: []
}
},
mounted() {
this.ruleDetails = this.campaigns.filter((item) => {
return item.attribute_name != 'Label batch'
})
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.6.4/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify#2.6.4/dist/vuetify.min.css"/>
<div id="app">
<v-app id="inspire">
<v-simple-table>
<template v-slot:default>
<thead>
<tr>
<th class="text-left">Attribute</th>
<th class="text-left">Operator</th>
<th class="text-left">Values</th>
</tr>
</thead>
<tbody>
<tr v-for="(ruleDetail, j) in ruleDetails">
<td>{{ ruleDetail.attribute_name }}</td>
<td>{{ ruleDetail.operator_name }}</td>
<td>{{ ruleDetail.value }}</td>
</tr>
</tbody>
</template>
</v-simple-table>
</v-app>
</div>
I'm trying to set up a Vue app with some simple routing so I can navigate to different pages. I installed Vue-Router through npm and I've tried following a couple tutorials online but, I can't seem to figure out why my is not clickable or why, when I manually type in the URL, it doesn't change anything. Any help is appreciated. Thank you.
main.js:
import {createApp} from 'vue'
import App from './App.vue'
import "./vue-api-call/styles.css"
import VueRouter from 'vue-router'
import About from "./About"
import Home from "./Home";
const routes = [
{path: '/about', component: About},
{path: '/home', component: Home}
]
const router = new VueRouter({routes})
createApp(App, router).mount("#app")
export default router
App.vue:
<!-- This first part of the file, the template part, is basically like an HTML page. Whatever we put in here will
display when we use 'npm run serve'. -->
<template>
<!-- The <div> tag is used as a container for HTML elements - which is then styled with CSS or manipulated with
JavaScript. -->
<div id="app">
<!-- <nav>Hello</nav>-->
<!-- The router-view tag will display info that comes from the router-link tag. More information here:
https://next.router.vuejs.org/guide/#html -->
<router-view>
<router-link to="/about">About</router-link>
</router-view>
<Layout>
<!-- begin form -->
Add a new video game with the form below:
<form id="demo">
<!-- text -->
<br>
<p>
<input type="text" v-model="msg" placeholder="Add Game">
{{ msg }}
</p>
<br>
<p>
<input type="checkbox" v-model="checked">
{{ checked ? "yes" : "no" }}
</p>
<br>
<!-- select -->
<p>
<select v-model="selected">
<option>one</option>
<option>two</option>
</select>
</p>
<br>
<p>
<button type="submit" v-on:click="createVideoGame()">Submit Form</button>
</p>
</form>
<br>
<button v-on:click="customer()"> Customer Button</button>
<br>
<table>
<thead>
<tr>
<th scope="col">Customer ID</th>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Middle Name</th>
<th scope="col">Birthday</th>
<th scope="col">Gender</th>
<th scope="col">Email</th>
<th scope="col">Username</th>
<th scope="col">Is Deleted</th>
</tr>
</thead>
<tbody>
<tr v-for="customer in customerInfo" :key="customer.customerId">
<td>{{ customer.customerId }}</td>
<td>{{ customer.cusFirstName }}</td>
<td>{{ customer.cusLastName }}</td>
<td>{{ customer.cusMiddleName }}</td>
<td>{{ customer.dateOfBirth }}</td>
<td>{{ customer.gender }}</td>
<td>{{ customer.email }}</td>
<td>{{ customer.username }}</td>
<td>{{ customer.isDeleted }}</td>
</tr>
</tbody>
</table>
<br><br>
<button v-on:click="videoGame()"> VideoGame Button</button>
<br>
<table>
<thead>
<tr>
<th scope="col">Video Game ID</th>
<th scope="col">Title</th>
<th scope="col">Release Year</th>
<th scope="col">Price</th>
<th scope="col">Stock</th>
<th scope="col">Image</th>
</tr>
</thead>
<tbody>
<tr v-for="game in gameInfo" :key="game.videoGameId">
<td>{{ game.videoGameId }}</td>
<td>{{ game.videoGameTitle }}</td>
<td>{{ game.yearReleased }}</td>
<td>{{ game.price }}</td>
<td>{{ game.stock }}</td>
<td>{{ game.videoGameImage }}</td>
</tr>
</tbody>
</table>
<br><br>
<button v-on:click="order()"> Order Button</button>
<br>
<table>
<thead>
<tr>
<th scope="col">Order ID</th>
<th scope="col">Order Date</th>
<th scope="col">Credit Card Provider</th>
<th scope="col">Credit Card Number</th>
<th scope="col">Total</th>
<th scope="col">Subtotal</th>
<th scope="col">Discount</th>
<th scope="col">Customer ID</th>
<th scope="col">Address ID</th>
</tr>
</thead>
<tbody>
<tr v-for="order in orderInfo" :key="order.orderId">
<td>{{ order.orderId }}</td>
<td>{{ order.orderDate }}</td>
<td>{{ order.creditCardProvider }}</td>
<td>{{ order.creditCardNumber }}</td>
<td>{{ order.total }}</td>
<td>{{ order.subtotal }}</td>
<td>{{ order.discount }}</td>
<td>{{ order.customerId }}</td>
<td>{{ order.addressId }}</td>
</tr>
</tbody>
</table>
<br><br>
<button v-on:click="purchase()"> Purchase Button</button>
<br>
<table>
<thead>
<tr>
<th scope="col">Purchase ID</th>
<th scope="col">Order ID</th>
<th scope="col">Video Game ID</th>
<th scope="col">Shipment Date</th>
</tr>
</thead>
<tbody>
<tr v-for="[purchase] in [purchaseInfo]" :key="purchase.purchaseId">
<td>{{ purchase.purchaseId }}</td>
<td>{{ purchase.orderId }}</td>
<td>{{ purchase.videoGameId }}</td>
<td>{{ purchase.shipmentDate }}</td>
</tr>
</tbody>
</table>
<br><br>
<button v-on:click="address()"> Address Button</button>
<br>
<table>
<thead>
<tr>
<th scope="col">Address ID</th>
<th scope="col">Customer ID</th>
<th scope="col">State ID</th>
<th scope="col">City</th>
<th scope="col">Zip</th>
<th scope="col">Suite Number</th>
<th scope="col">PO Box</th>
</tr>
</thead>
<tbody>
<tr v-for="address in addressInfo" :key="address.addressId">
<td>{{ address.addressId }}</td>
<td>{{ address.customerId }}</td>
<td>{{ address.stateId }}</td>
<td>{{ address.city }}</td>
<td>{{ address.zip }}</td>
<td>{{ address.suiteNumber }}</td>
<td>{{ address.poBox }}</td>
</tr>
</tbody>
</table>
<br><br>
<button v-on:click="state()"> State Button</button>
<br>
<table>
<thead>
<tr>
<th scope="col">State ID</th>
<th scope="col">State</th>
</tr>
</thead>
<tbody>
<tr v-for="state in stateInfo" :key="state.stateId">
<td>{{ state.stateId }}</td>
<td>{{ state.state }}</td>
</tr>
</tbody>
</table>
<br><br>
</Layout>
</div>
</template>
<!-- Still not entirely sure what this script part is. Pretty sure it's some functionality stuff added by Vue -->
<script>
import Layout from "./components/Layout.vue"
import axios from "axios"
// import PageHeading from "./components/PageHeading.vue"
// import NavBar from "./components/NavBar.vue"
export default {
name: 'App', variant: "variant", variantType: "variantType", disableButton: "disableButton",
username: "", password: "",
data: () => {
return {
// These variables are used above and are what initially is shown above the buttons.
customerInfo: [],
gameInfo: [],
orderInfo: "waiting for order",
purchaseInfo: "waiting for purchase",
addressInfo: "waiting for address",
stateInfo: "waiting for state",
username: "",
password: "",
msg: "",
checked: true,
picked: "",
selected: ""
}
},
components: {
Layout,
// NavBar, PageHeading,
},
mounted() {
// this.test()
},
methods: {
// Gets customer info and displays it.
customer: function () {
if (this.customerInfo === "waiting for customer") {
axios
.get('http://localhost:8000/customers/?format=json')
.then(response => (this.customerInfo = response.data))
} else {
this.customerInfo = "waiting for customer"
}
},
// Gets video game info and displays it.
videoGame: function () {
if (this.gameInfo === "waiting for game") {
axios
.get('http://localhost:8000/videoGames/?format=json')
.then(response => (this.gameInfo = response.data))
} else {
this.gameInfo = "waiting for game"
}
},
// Gets order info and displays it.
order: function () {
if (this.orderInfo === "waiting for order") {
axios
.get('http://localhost:8000/orders/?format=json')
.then(response => (this.orderInfo = response.data))
} else {
this.orderInfo = "waiting for order"
}
},
// Gets purchase info and displays it.
purchase: function () {
if (this.purchaseInfo === "waiting for purchase") {
axios
.get('http://localhost:8000/purchases/?format=json')
.then(response => (this.purchaseInfo = response.data))
} else {
this.purchaseInfo = "waiting for purchase"
}
},
// Gets address info and displays it.
address: function () {
if (this.addressInfo === "waiting for address") {
axios
.get('http://localhost:8000/addresses/?format=json')
.then(response => (this.addressInfo = response.data))
} else {
this.addressInfo = "waiting for address"
}
},
// Gets state info and displays it.
state: function () {
if (this.stateInfo === "waiting for state") {
axios
.get('http://localhost:8000/states/?format=json')
.then(response => (this.stateInfo = response.data))
} else {
this.stateInfo = "waiting for state"
}
},
createVideoGame() {
axios.post('http://127.0.0.1:8000/videoGames/', {
videoGameId: '111',
videoGameTitle: 'Test Video Game 1',
yearReleased: '2021',
price: '10.00',
stock: '5',
videoGameImage: 'testImage'
})
},
// login: function () {
// console.log(this.username)
// console.log(this.password)
// const bcrypt = require("bcryptjs")
// bcrypt.compare(this.password, "hash", (err, result) => {
// if (err) {
// console.error(err)
// return
// }
// console.log(result) // true or false
// });
}
}
// methods: {
// addUser(){
// console.log(this.encryptPassword(this.password))
// },
// encryptPassword(password)
// const salt = bcrypt.genSaltSync(10)
// return bcrypt.hashSync(password, salt)
// },
</script>
<!-- This style tag is for the entire page, I think. If you change something in here, like the background-color, it
will change it on the webpage. It's exactly like the style tag in a CSS/HTML page I'm pretty sure. -->
<!-- if you use the !important; rule, it will override ALL previous styling rules for that specific property on that
element! -->
<style>
body {
margin: 0;
padding: 0;
background-color: #c5fcc5 !important;
}
table, th, td {
border: 1px solid darkgreen;
text-align: center;
}
</style>
You forgot to tell Vue to use the VueRouter. From the Official Docs.
import { createApp } from 'vue';
import App from './App.vue';
...
...
const routes = [
{path: '/about', component: About},
{path: '/home', component: Home}
];
const router = new VueRouter({routes});
createApp(App).use(router).mount('#app'); // <== Here
export default router;
I am fetching data(Orders) from external Api in Vue using axios. I obtain JSON data and i am able to show it in a HTML table. Now i am trying filter the data to show only related data to use. In my Json data, i have a field called "order status: Completed / processing". Now i only want to show the json data which are have status like "Processing" to achieve my goal.
I am trying to use v-if with v-for but I m unable to get the certain orders data and view.
The table is set to update for each minute.
Here is my code:
html code
**<div class ="container mt-4" id="app">
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">Order id</th>
<th scope="col">Name</th>
<th scope="col">Order Date</th>
<th scope="col">Phone</th>
<th scope="col">Address</th>
<th scope="col">Items</th>
<th scope="col">Total</th>
<th scope="col">Print</th>
</tr>
</thead>
<tbody>
<tr
v-for="(order, index) in orders" v-if="order.status === "processing""
:key="order.id"
:class="{highlight: !order.is_printed}"
>
<td>{{ order.id }}</td>
<td>{{ order.billing.first_name + " " +order.billing.last_name }}</td>
<td>{{ order.date_created }}</td>
<td>{{ order.billing.phone}}</td>
<td>{{ order.billing.address_1 + ", " + order.billing.address_2 + ", " + order.billing.city + order.billing.postcode }}</td>
<td>{{ order.line_items[0].name}} </td>
<td>{{ order.total}}</td>
<td><button class="btn btn-primary" #click="printBill(order)">Print</button>
</tr>
</tbody>
</table>**
Vue
<script>
var app = new Vue({
el: '#app',
data: {
orders: []
},
mounted: function() {
// API Call function to be implemented here....
</script>
I think this should do the trick.
According to Vue documentation it's best to put any logic into computed properties https://v2.vuejs.org/v2/guide/computed.html
new Vue({
el: "#app",
data: {
orders: [
{ id: 1, status: "processing"},
{ id: 2, status: "other" }
]
},
computed: {
filteredOrders() {
return this.orders.filter(order => order.status === 'processing');
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<thead>
<tr>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
<tr v-for="order in filteredOrders" :key="order.id">
<td>{{ order.status }}</td>
</tr>
</tbody>
</table>
</div>
its better to filter data after you get them from api.
based on vue.js document it’s not recommended to use v-if and v-for together, read this:
https://v2.vuejs.org/v2/guide/list.html#v-for-with-v-if
try this
let filteredData = this.orders.filter(order => order.status === "processing")
Here is my javascript/vue.js code:
import _ from 'lodash'
export default{
props:['campanha'],
data (){
return{
list:[],
filter: '',
href: '/campanha/9/edit'
}
},
methods:{
url: function (href){
return '/campanha/'+this.href+'/edit'
}
},
mounted: function (){
this.list = JSON.parse(this.campanha)
},
computed: {
filteredCampanhas(){
var self = this
return this.list.filter(function(campanhas) {
return campanhas.nome.indexOf(self.filter) > -1
})
}
}
}
And here it`s my html:
<template>
<div>
<div class="well">
Novo Cadastro <span class="glyphicon glyphicon-plus" aria-hidden="true"/><br></br>
<input type="text" class="form-control" placeholder="Filtrar Campanhas" v-model="filter">
</div>
<div class="table-responsive">
<table class="table table-borderless">
<thead>
<tr>
<th>Id</th>
<th>Nome</th>
<th>Data Início</th>
<th>Data Término</th>
<th>Hora Inícío</th>
<th>Hora Término</th>
</tr>
</thead>
<tbody>
<!--{{ url('/campanha/' . $item->id_campanha . '/edit') }}
href: '/campanha/9/edit'
<td><a v-bind:href="href">{{ c.nome }}</a></td>
!-->
<tr v-for="c in filteredCampanhas">
<td>{{ c.id_campanha }}</td>
<td><a :href="url(c.id_campanha)">{{ c.nome }}</a></td>
<td>{{ c.data_inicio }}</td>
<td>{{ c.data_termino }}</td>
<td>{{ c.hora_inicio }}</td>
<td>{{ c.hora_termino }}</td>
</tr>
</tbody>
</table>
</div>
<div>
</template>
I have tried to put some data into href section of my tag a, to link to another page, but it`s not working.
Try following:
methods:{
url: function (href){
return '/campanha/'+ href+'/edit'
}
},
When you are using this.href it will start to pick href from data of vue instance,