HTML does not support tri-state checkboxes by default. There is an indeterminate attribute to indicate that the value is undefined but there is no way to set a checkbox back to indeterminate through the user interface once it has been checked or unchecked. The attribute can only be changed with JavaScript.
Current State in HTML and JavaScript
The following screenshot shows how the three states of a checkbox are visualized in Internet Explorer 11. Other browsers visualize the states slightly different.
This is how the HTML for the tree checkboxes looks like:
As the indeterminate state cannot be set in HTML, it has to be set in the window.onload function with JavaScript and it cannot be set back to indeterminate by a user once it has lost the indeterminate state.
Building the AngularJS TriStateCheckBox Directive
The directive offers two properties to bind against: isThreeState and isChecked. The CheckBoxScopeDeclaration class specifies these properties.
The $scope of the directive of type ICheckBoxScope holds the current values for these two properties. Additionally it offers a function updateState, which is used in the template of the directive to update the isChecked property whenever the checkbox is clicked.
The linking function of the directive finds the HTMLInputElement for the checkbox. This is required as the indeterminate state of the checkbox can only be set from JavaScript. So it is not possible to do this via data binding. Additionally, it defines the updateState function and adds a $watch listener for the isChecked property. Whenever the value is set to null or undefined and the isThreeState property is set to true, the checkbox is set back to indeterminate state.
How to Use the Directive in HTML
The goal for the directive built with AngularJS and TypeScript was to:
be able to set all three states directly in HTML without the need for JavaScript
allow data binding in AngularJS
The first HTML snippet shows how the directive can be used to set the values in HTML:
The next snippet shows how data binding works. For each state there is a property in the controller: myBooleanValue1, myBooleanValue2 and myBooleanValue3. Each is bound to a checkbox to change the value and a span tag to display the current value.
The controller for the view contains the tree boolean values:
Here is the result for the view and the controller:
Limitations
The indeterminate state of the checkbox is not displayed correctly in Safari. There is no visual difference between an unchecked checkbox and an indeterminate checkbox. To make it work in Safari too, you can replace the checkbox visualization of the browser with your own. There is a simple and nice implementation at http://w3facility.org/question/custom-html-checkbox-symbols-with-keyboard-navigation-support/.
Its Techorama in Belgium again. This time I speak about async programming with JavaScript and TypeScript. In this blog post I would like to share my sample code and the recording of the session.
Today, I will do a session about TypeScript at a //Build2017 Recap event at Microsoft Vienna. In this blog post I share my samples and important links.
I regularly do trainings and workshops about web development with TypeScript and Angular. This week, I worked with a group of developers who have a non-web development background. They asked me to summarize the most important readings for learning about modern web development. Their problem isn't a lack of information. The amount of information on the internet is overwhelming and they asked for the really important resources. Here is my best-of-list.
Time Cockpit Newsletter
Thanks for your registration! You are almost finished. We need to confirm your email address. To complete the subscription process, please click the link in the email we just sent you.