Implementation of select all function of uniapp multi selection box

In fact, the built-in checkbox and checkbox group in the uniapp are good, but there are two problems:

  1. Cannot rely on its events to select all
  2. The style is fixed and difficult to modify

The reasons why they could not achieve full election were:
When I dynamically modify the checked field of the checkbox, the status on the interface can change in real time, but the change event of the checkbox group cannot be triggered. This means that you cannot rely on the checkbox group to manage the selected items.

That is to say: I click Select all, and it looks like select all on the interface. Then I cancel one of the options, and the change event is triggered, but the selected list it feeds back to me is wrong. It won't work.

So I came up with a scheme to realize select all and select multiple boxes.

Realization idea

In view of the above problems, I can give up the checkbox group. Then, I give up the checkbox by the way, because I prefer the circle style of radio.

First, simulate and generate some data to facilitate display. The key point of data is to have a field selected, and others do whatever they want:

<script setup lang="ts">
    import { reactive } from "vue";
    // The simulated data object should be responsive
    let data = reactive([] as { id: number; text: string; selected: boolean }[]);
    // Generate data
    for (let i = 0; i < 20; i++) {
        data.push({
            id: i + 5,
            text: "title" + i,
            selected: false,
        });
    }
</script>

Then we need to have an object to store the selected data information, using map:

    // Store the selected content. Because the list is frequently added and deleted, map is selected instead of array, and key corresponds to the subscript of data. As for what to store, it's entirely up to you
    let selected = reactive(new Map<number, number>());

Then we have to have a click time to select data or deselect:

    // Click the event in the option box, and the parameter is the subscript of the data
    function checkbox(index: number) {
        // Click again in the selected state to cancel the selection
        if (data[index].selected) {
            data[index].selected = false;
            selected.delete(index); // Then delete the corresponding key
        }
        // Click when not selected
        else {
            data[index].selected = true;
            selected.set(index, data[index].id);
        }
    }

Then, we have to have a click event of select all:

    // Select all and deselect events
    function allSelect() {
        // If you have selected all, it is the reverse selection. If you select all, it means that the length is the same
        if (selected.size === data.length) {
            selected.clear(); // Clear all
            data.forEach((element) => {
                element.selected = false; // Just don't choose all of them
            });
        }
        // In the state of not selecting all
        else {
            data.forEach((element, index) => {
                // Because the possible parts have been selected, you must first judge whether they exist or not before adding them
                if (!selected.has(index)) {
                    selected.set(index, element.id); // key is the corresponding subscript index, while value can be customized
                    element.selected = true; // Set as selected
                }
            });
        }
    }

In fact, the above two click events are very basic judgment, addition and deletion data. So far, all functions are available. Let's see how to write on the page:

<template>
    <!-- It's a multiple choice list -->
    <view v-for="(item, index) in data">
        <label style="margin-left: 50px">
            <radio :value="String(index)" :checked="item.selected" @click="checkbox(index)" />{{ item.text }}
        </label>
    </view>
    <!-- Select all button -->
    <label> <radio value="1" :checked="selected.size === data.length" @click="allSelect" />Select all</label>
</template>

In fact, there are two groups of radio s, one is to display data circularly, and the other is to select all button.

Connected complete code:

<template>
    <!-- It's a multiple choice list -->
    <view v-for="(item, index) in data">
        <label style="margin-left: 50px">
            <radio :value="String(index)" :checked="item.selected" @click="checkbox(index)" />{{ item.text }}
        </label>
    </view>
    <!-- Select all button -->
    <label> <radio value="1" :checked="selected.size === data.length" @click="allSelect" />Select all</label>
</template>
<script setup lang="ts">
    import { reactive } from "vue";

    // The simulated data object should be responsive
    let data = reactive([] as { id: number; text: string; selected: boolean }[]);
    // Generate data
    for (let i = 0; i < 20; i++) {
        data.push({
            id: i + 5,
            text: "title" + i,
            selected: false,
        });
    }

    // Store the selected content. Because the list is frequently added and deleted, map is selected instead of array, and key corresponds to the subscript of data. As for what to store, it's entirely up to you
    let selected = reactive(new Map<number, number>());

    // Select all and deselect events
    function allSelect() {
        // If you have selected all, it is the reverse selection. If you select all, it means that the length is the same
        if (selected.size === data.length) {
            selected.clear(); // Clear all
            data.forEach((element) => {
                element.selected = false; // Just don't choose all of them
            });
        }
        // In the state of not selecting all
        else {
            data.forEach((element, index) => {
                // Because the possible parts have been selected, you must first judge whether they exist or not before adding them
                if (!selected.has(index)) {
                    selected.set(index, element.id); // key is the corresponding subscript index, while value can be customized
                    element.selected = true; // Set as selected
                }
            });
        }
    }

    // Click the event in the option box, and the parameter is the subscript of the data
    function checkbox(index: number) {
        // Click again in the selected state to cancel the selection
        if (data[index].selected) {
            data[index].selected = false;
            selected.delete(index); // Then delete the corresponding key
        }
        // Click when not selected
        else {
            data[index].selected = true;
            selected.set(index, data[index].id);
        }
    }
</script>
<style></style>

It seems that there are many codes, but they are actually very basic logical judgments.

The final effect is as follows:
Select all:

Multiple choices:

Invert all:

Tags: Front-end Vue uniapp

Posted by wpt394 on Sat, 16 Apr 2022 22:10:57 +0930