<div id="shopping-list">
<table class="pf-c-table pf-m-grid-lg" role="grid" aria-label="Shopping list">
<caption>
<span id="caption-text">{{totalItemsChecked}} of {{totalItems}} items checked</span>
<button class="pf-c-button pf-m-primary" type="button" @click="doCheckAllProducts" :disabled="checkAllBtnDisabled">
Check all
</button>
<button class="pf-c-button pf-m-secondary" type="button" @click="doUncheckAllProducts" :disabled="uncheckAllBtnDisabled">
Uncheck all
</button>
</caption>
<thead>
<tr>
<td />
<th scope="col">
Item
</th>
<th scope="col">
Quantity
</th>
</tr>
</thead>
<tbody>
<tr v-for="(product, index) in products" :key="index" :class="[{'checked': product.isChecked}]">
<td class="pf-c-table__check">
<input type="checkbox" name="product.name" :aria-labelledby="`item-${index}-${product.name}`" v-model="product.isChecked"/>
</td>
<th data-label="Item">
<div id="`item-${index}-${product.name}`">{{product.name}}</div>
</th>
<td data-label="Quantity">
{{product.quantity}}
</td>
</tr>
</tbody>
</table>
</div>
new Vue({
el: '#shopping-list',
data: {
products: [
{
name: 'Sugar',
quantity: '1 Cup',
isChecked: false
},
{
name: 'Butter',
quantity: '1/2 Cup',
isChecked: false
},
{
name: 'Eggs',
quantity: '2',
isChecked: true
},
{
name: 'Milk',
quantity: '1/2 Cup',
isChecked: false
}
]
},
computed: {
totalItems () {
return this.products.length
},
totalItemsChecked () {
return this.products.filter(p => p.isChecked).length
},
checkAllBtnDisabled () {
return this.totalItemsChecked === this.totalItems
},
uncheckAllBtnDisabled () {
return this.totalItemsChecked === 0
}
},
methods: {
doCheckAllProducts () {
if (this.checkAllBtnDisabled) return
this.products.map(p => p.isChecked = true)
},
doUncheckAllProducts () {
if (this.uncheckAllBtnDisabled) return
this.products.map(p => p.isChecked = false)
}
}
})
View Compiled