I'm trying to build a custom checkbox directive (to be able to style it as I like) not using <input type="checkbox">. It should work as one would expect; updating the model should update the view, clicking the box should update the model, it should listen to the required directive (validation should work).
I currently have the following directive, working exactly as intended:
'use strict';
angular.module('directives.checkbox', [])
.directive('checkbox', [function () {
return {
restrict: 'A',
require: 'ngModel',
replace: true,
template: '<span class="checkbox"></span>',
link: function (scope, elem, attrs, ctrl) {
elem.bind('click', function () {
scope.$apply(function () {
elem.toggleClass('checked');
ctrl.$setViewValue(elem.hasClass('checked'));
});
});
ctrl.$render = function () {
if (!elem.hasClass('checked') && ctrl.$viewValue) {
elem.addClass('checked');
} else if (elem.hasClass('checked') && !ctrl.$viewValue) {
elem.removeClass('checked');
}
};
}
}
}]);
It's just a <span> with a CSS class checkbox and another CSS class checked for the checked state. However, it does not seem very angular-like (or best practice) to use jQuery to toggle the class and update the view like I do. I would rather use the ng-class and ng-click directives, but that implies I need to use an isolated scope (to avoid scope state clashes when using multiple checkboxes on the same page). For some reason, the isolated scope makes angular stop calling $render() on ctrl.
Does anyone know if this is the correct way, or if there's a more angular-like approach which would still solve the requirements I have?