I want to use Vuetify's v-list-item-group component for my Vue app. This list represents nodes that are related to a graph. I can select none, some or all of them and delete the selected ones.
For a better user experience I want to provide a "select all / deselect all" checkbox at the top next to the header. If only some nodes are selected, the checkbox should render the indeterminate state.
Currently this is the code I'm using
<div id="app">
<v-app id="inspire">
<v-list>
<v-list-item>
<v-list-item-action>
<v-checkbox :indeterminate="someNodesSelected" :input-value="allNodesSelected" @click="toggleCompleteSelection" />
</v-list-item-action>
<v-list-item-content>
<v-list-item-title v-text="graphWithNodes.name"></v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-btn icon :disabled="noNodesSelected" @click="deleteNodes">
<v-icon color="error">mdi-delete</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
<v-list-item-group v-model="selectedNodeIds" multiple>
<v-list-item v-for="node in graphWithNodes.nodes" :key="node.id" :value="node.id">
<template v-slot:default="{ active, toggle }">
<v-list-item-action>
<v-checkbox :input-value="active" :true-value="node.id" @click="toggle" />
</v-list-item-action>
<v-list-item-content>
<v-list-item-subtitle v-text="node.id"></v-list-item-subtitle>
</v-list-item-content>
</template>
</v-list-item>
</v-list-item-group>
</v-list>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
selectedNodeIds: [],
graphWithNodes: {
id: 1,
name: "The graph",
nodes: [{
id: 1,
graphId: 1
}, {
id: 2,
graphId: 1
}]
},
}
},
computed: {
noNodesSelected() {
return this.selectedNodeIds.length === 0;
},
someNodesSelected() {
return this.selectedNodeIds.length > 0 && !this.allNodesSelected;
},
allNodesSelected() {
return (
this.selectedNodeIds.length === this.graphWithNodes.nodes.length
);
}
},
methods: {
deleteNodes(nodeIds) {
for (const nodeId of this.selectedNodeIds) {
this.deleteNode(nodeId);
}
this.selectedQueueIds = [];
},
deleteNode(id) {
this.graphWithNodes.nodes = this.graphWithNodes.nodes.filter(node => node.id !== id);
},
toggleCompleteSelection() {
if(this.noNodesSelected || this.someNodesSelected) {
this.selectedNodeIds = this.graphWithNodes.nodes.map(node => node.id);
} else {
this.selectedNodeIds = [];
}
}
}
})
If you want to play around I created a codepen for this
https://codepen.io/magicfoobar/pen/RwPBNmV?editors=1010
So the problem I have is that when I click on the header checkbox the function toggleCompleteSelection gets executed twice and I can't figure out why.
Does someone know why the header checkbox is broken and how to fix it?
Thanks in advance
It works if you change the checkbox trigger from @click
to @change
<v-checkbox
:indeterminate="someNodesSelected"
:input-value="allNodesSelected"
@change="toggleCompleteSelection" />
Just add .stop
after the click
and it works.
<v-checkbox :indeterminate="someNodesSelected" :input-value="allNodesSelected" @click.stop="toggleCompleteSelection" />
codepen - https://codepen.io/Pratik__007/pen/MWwBKRL?editors=1010
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With