AngularJS directive for jquery iCheck

25 May 2016

Most of the fancier websites requires stylish input controls to align with its overall design flow. There are many ways of doing it through the JavaScript + images to achieve the look and feel. But having a input control without a proper accessibility options like focusing the controls through keyboard keys, or enabling screen readers to recognize the proper options is a great blunder. So selecting a proper cross browser plugin with accessibility is a must.

One such beautiful jQuery based plugin is iCheck, been famous for a long time with all accessibility support. It supports CSS based display customization. You can read more about it in the project site. Its dependency on jQuery helps the plugin to solve many of the cross browser related compatibility issues.

Recently, with many applications moving towards SPA web frameworks like Angular. Adapting the same solution without re-inventing the wheel is required. With a huge number of events exposed by the plugin, it is damn simple to write a directive for it. Take a look at below angular directive I have come across in the web written for jQuery iCheck.

angular.module("app")
.directive('icheck', function ($timeout, $parse) {
    return {
        require: 'ngModel',
        link: function ($scope, element, $attrs, ngModel) {
            return $timeout(function () {
                var value;
                value = $attrs['value'];

                $scope.$watch($attrs['ngModel'], function (newValue) {
                    $(element).iCheck('update');
                });

                $scope.$watch($attrs['ngDisabled'], function (newValue) {
                    $(element).iCheck(newValue ? 'disable' : 'enable');
                    $(element).iCheck('update');
                })

                return $(element).iCheck({
                    checkboxClass: 'icheckbox_square-blue',
                    radioClass: 'iradio_square-blue'

                }).on('ifChanged', function (event) {
                    if ($(element).attr('type') === 'checkbox' && $attrs['ngModel']) {
                        $scope.$apply(function () {
                            return ngModel.$setViewValue(event.target.checked);
                        })
                    }
                }).on('ifClicked', function (event) {
                    if ($(element).attr('type') === 'radio' && $attrs['ngModel']) {
                        return $scope.$apply(function () {
                            //set up for radio buttons to be de-selectable
                            if (ngModel.$viewValue != value)
                                return ngModel.$setViewValue(value);
                            else
                                ngModel.$setViewValue(null);
                            ngModel.$render();
                            return
                        });
                    }
                });
            });
        }
    };
});