Multi-select dropdowns in AngularJS is a popular control. Let’s do ahead a step and create something more advanced, yet so simple.
Ever had an Aha! moment while using the Gmail multi-select checkbox tool? The one with dropdown options. Remember? The control which lets you select/un-select all the emails in a list and performs some action on them.
Well, below is an image for you if you are still wondering what am I talking about.
That tool has always come handy to me. It’s one of those moments when you realize how UX plays such an important part in any web app’s life.
If you use Kendo widgets- check out how to customize your Kendo multi-select control with ease in AngularJS.
Our aim is to build a reusable component which lets us perform an action on a batch of items together. Let’s call it
As we need to be able to plop it anywhere in the app, we have to make sure that the interface of our component is simple enough and that we don’t tightly couple our
multi-checker component with any of the views.
Let’s dive in.
First, let’s mock a list in the controller as
$scope.items = . The collection contains objects which have two properties-
selected flag keeps track of whether or not a certain item is selected.
That’s it for the controller.
Now, let’s move on to our
In our directive, we are two-way binding the
items to our isolate scope. This is done for a specific reason.
Two-way binding the items allow our view to update the state of our
multi-checker control. Plus, it also allows our
multi-checker control to update the selected state of each item.
multi-checker directive template will look something like this:
I am using angular bootstrap’s dropdown control. Two options under the dropdown are ‘All’ and ‘None’ which selects all the items and un-selects them, respectively.
I have used three font-awesome icons to show three different states of our control.
- All the items are checked -
- Some of the items are checked -
- None of the items are checked -
In fact, those icons are button themselves. So, you can click those items to toggle between the states.
Now let’s go to the core logic of this directive.
Just a side note: I am using lodash library to do all the utility tasks. If you are not familiar with
lodash, please visit my post on 5 very powerful lodash function you should know to see its awesomeness.
The below function unselects all of the
items. I am traversing through each item and setting its
selected property to null. Which changes the state of our
multi-checker control as well as the list.
The below function selects all of the items. Similar to our
selectNone() method, I am traversing each item and setting its
selected property to
The above two functions took care of the behavior of our directive.
But, what if the user checks or unchecks the items themselves by clicking on the checkbox? Our
multi-checker control needs to keep track of these updates as well.
To do this we keep a watch on our collection.
true flag in our collection keeps a deep watch on the collection. Which means, it will get fired not only when an item is added or removed from the collection, but also when a property of some item is changed.
By the way, if you haven’t checked out our post on watching the variables in AngularJS, this is a good time for that.
So, whenever the
selected state of any of our item changes, this watcher will be fired.
Now, let’s see the logic in our watcher function
Firstly, we don’t care when there are no items. So we just return.
But, if we have items we first filter the
selected items and then check the length of this filtered collection.
If there are no such filtered items, it means none of the items is selected. So we set the state of our
multi-checker control to
If the length of the filtered collection matches the length of our items-collection, it means all of the items are checked. So, we set the state of our
multi-checker control to
And if the length is somewhere in between zero to all, it means only some of items are checked. So, we set the state of our
multi-checker control to
That’s it. This is how we keep track of all the three state. And in our directive, we also know which items are actually selected and which are not.
So, you can leverage this directive to perform any task you desire. Just like Google does. You can mark items are as
un-read. You can move the selected items to a certain folder. And lots more.
This was a super simple implementation of Gmail-like multi-checker/multi-select control in AngularJS and UI-Bootstrap.
We learned how to create a wrapper component. You can leverage that component to perform any task you that might like. You can select all, some or none of of the items using the dropdown or the list itself.
If you want to get started with Kendo UI or want to learn how to customize them, here is something interesting for you.
Please let me know if you need more clarification on any part of the implementation. Also, do suggest how we can improve this control to do some awesome things.