Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

v-list-item-group select all / deselect all items at once

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

like image 578
Question3r Avatar asked Mar 19 '20 15:03

Question3r


Video Answer


2 Answers

It works if you change the checkbox trigger from @click to @change

<v-checkbox 
:indeterminate="someNodesSelected" 
:input-value="allNodesSelected"  
@change="toggleCompleteSelection" />

like image 184
ellisdod Avatar answered Oct 12 '22 14:10

ellisdod


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

like image 2
Patel Pratik Avatar answered Oct 12 '22 13:10

Patel Pratik