最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - v-list-item-group select alldeselect all items at once - Stack Overflow

programmeradmin0浏览0评论

I want to use Vuetify's v-list-item-group ponent 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
                }]
            },
        }
    },
    puted: {
        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

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

I want to use Vuetify's v-list-item-group ponent 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
                }]
            },
        }
    },
    puted: {
        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

Share Improve this question asked Mar 19, 2020 at 15:50 Question3rQuestion3r 3,87229 gold badges123 silver badges244 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 2

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

I'm not sure that you need to run toggleCompleteSelection directly from the checkbox.

I would achieve the "select all" functionality with a Watcher, see https://codepen.io/joffff/pen/06cd75ea651660d13d4ddc288b8448d7?editors=1010

发布评论

评论列表(0)

  1. 暂无评论