Creating AngularJS Directive 'Three-state-checkbox'
16 Jun 2016
Pre-story
Yesterday at work, I’ve received a task, which I should had done today (and I actually did).
Simple task to filter table by logical value in one column.
So I had 3 values to filter by: null
, true
and false
(not filtered, published, unpublished).
I’ve thought what would be the best visual solution for that…
I knew, that I don’t want to create three-option select
, like that:
(what is actually the fastest solution of that issue) .
But I’ve decided to make three-state checkbox. I wanted it to be clean and semantic solution, so I’ve also decided to create open-source package with AngularJS directory of three-state-checkbox.
Preparing your project for public usage
Init your project with npm and if you are registered at npmjs you can publish it to node package manager.
Read more how to publish your package.
We use both bower and npm at our project. But our gulp is configured to automatically insert bower dependencies to index.html while id building.
Also if you are publishing your first package you don’t have to register at bower, and documentation is more understandable:
Creating package with bower
* What is the difference between bower and npm?
Creating AngularJS Directive
If you want to export your directive for others or to use it in a multiple projects, you should create separate Angular Module with that directive.
Ok now we have our angular module and directive initialized.
So to use it in another project, you need to add this JavaScript file to index.html and add "threeStateCheckbox"
module to dependencies of your app module.
In my directive ngModel
is required so usage of it should look like this:
app.js :
index.html :
Ok. But directive is showing nothing now.
If you are creating simple element directive (like checkbox, input, etc ), you should better not create template for your directive, but use element, by which your directive was initialized in html file.
Modify your element and then do $compile(element)(scope);
.
So as you can see, I’ve added ng-click
and class
attributes and removed three-state-checkbox
, because my directive is configured with restrict: "A"
, which means it can be linked only by attribute.
Ok now we need to change ngModel
, when someone will click on the “checkbox”.
4-th attribute of link
function is Collection of required directives, or is a single directive, if only one directive is required.
As ngModel
is the only directive required by three-state-checkbox I can reach the ngModel
object from link function attributes.
We will use 2 methods and 1 parameter of ngModel
object:
$setViewValue()
- to set value tongModel
$render()
- to renderngModel
and trigger event forng-change
$modelValue
- current value ofngModel
Ok. Now three-state-checkbox directive is working properly, changing ngModel and triggering ngChange event.
I’ve also added options
parameter to directive, and ng-class
attribute to element, to change class when state is changed.
So my stable version v 1.1.0 looks like this:
I’ve created animations for changing states and Internet Explorer doesn’t support all styles for css pseudo-elements, so I had to create template with spans.
Versioning
Use Git tags to support versioning of your project. Read more about Git Tagging
GitHub repository
Three-state checkbox - GitHub repository
I also need help to extend this directive, so if you want to contribute, I will be very thankful.
Here are some issues on GitHub: Fix ‘em
Demo
You can try demo here: Three-state checkbox DEMO