Image

build-a-gmail-clone-with-vue-3

4 min read
Last update: December 19, 2021

‘Select All’ Checkbox

For the starting code for this lesson, switch to branch: https://github.com/Code-Pop/build-gmail-clone-with-vue-3/tree/video-13-start

In a previous lesson, we put our email selection state in a composable. Now, we can start using this to create new features.

We’ll be creating a Bulk Action Bar, which will contain a “select all” checkbox, and then we’ll have several buttons that will trigger actions on all selected emails. In this lesson, we’ll be making the “select all” checkbox.

Our first order of business will be to create the BulkActionBar component and decide where to put it. The “select all” checkbox will need the array of emails shown on the screen, so it should go somewhere it can access that. MailTableis the component where we fetch that data, so let’s put BulkActionBar at the top and feed in the emails as a prop.

<BulkActionBar :emails="unarchivedEmails" />

We’ll define the emails prop and bring in the composable, and then we’ll put in text saying the number of emails and the number of selected emails, so that we know everything’s connected right.

Now let’s make our checkbox, and make it reflect the current state. If no emails are selected, the checkbox is unselected. If all emails are selected, the checkbox is selected. If some emails are selected, then we’ll show a partial selection - a lighter shade of blue-grey.

To do this, we’ll need to compare our list of selected emails to the complete list of emails displayed, so we’ll pass that in to the Bulk Action Bar.

Then we’ll created several computed properties in the setup function, and use that to set the :checked property and the partial-check class.

These computed properties could also be done in the computed object, if you wanted to use the Options API. That might be slightly more elegant in this case, but I wanted to include the Composition API method of doing computed properties at least once in this course.

<template>
    <div>
        <input type="checkbox" :checked="allEmailsSelected" :class="[someEmailsSelected ? 'partial-check' : '']">
    </div>
</template>

<script>
    import {
        useEmailSelection
    } from '../composition/useEmailSelection';
    import {
        computed
    } from 'vue';

    export default {
        setup(props) {
            let emailSelection = useEmailSelection();
            let numberSelected = computed(() => emailSelection.emails.size)
            let numberEmails = props.emails.length
            let allEmailsSelected = computed(() => numberSelected.value == numberEmails)
            let partialSelection = computed(() => {
                return numberSelected.value > 0 && numberSelected < numberEmails
            })

            return {
                someEmailsSelected,
                allEmailsSelected
            }
        },
        props: {
            emails: {
                type: Array,
                required: true
            }
        }
    }
</script>

Select emails and the Select All box should reflect how many are selected.

Now, let’s make it so checking and unchecking the Select All box changes the set of selected emails.

<input type="checkbox" :checked="allAreSelected" :class="[partialSelection ? 'partial-check' : '']" @click="bulkSelect">
setup(props){
...

let bulkSelect = function(){
if(allEmailsSelected.value) {
emailSelection.clear();
} else {
emailSelection.addMultiple(props.emails)
}
}
...
}

We’re calling two new methods on the emailSelection module. The intent should be fairly clear from the naming, but important to note is that with addMultiple we’re adding all the currently displayed emails - including the ones that are already on the Set. That’s one benefit of using a Set.

const emails = reactive(emailSet)
const toggle = (id) => {
if(emails.has(id)) {
emails.delete(id)
} else {
emails.add(id);
}
}
const clear = () => {
emails.clear();
}
const addMultiple = (newEmails) => {
newEmails.forEach(email => {
emails.add(email)
})
}
return {
emails,
toggle,
addMultiple,
clear
}

Now we’ve got the “Select All” checkbox working properly.

In the next lesson, we’ll be adding Bulk Action Buttons to the top bar, so we can mark all the selected items read, unread, or archived.

For the ending code for this lesson, switch to branch: https://github.com/Code-Pop/build-gmail-clone-with-vue-3/tree/video-13-end

Jeffrey teaches an 8-week beginning Vue course with guaranteed results. Built on top of the VueMastery curriculum, with extra hands-on assignments and personal attention. You can find it here.