いずれかひとつが必須のチェックボックス群
概要
「複数あるチェックボックスのうち、最低ひとつを選んでください。」みたいなのよくやりますよね?
探し方が悪かったのか、もっといいものがあるのに頑張って実装してしまいました。
(;-;)
悲しいので何かの参考代わりに置いておきます。
もっといいもの
こちらのほうが、機能充実。見た目もよいです。
http://plnkr.co/edit/FWsQVP7yWqnFf2uE1uXv?p=preview
コードの屍
一応使い方
<input type="checkbox" checkbox-group="enqBring" name="enqBring" >Search engine
<input type="checkbox" checkbox-group="enqBring">SNS
<input type="checkbox" checkbox-group="enqBring">Email newsletter
ソースコード
angular-checkbox-group.js
/*
* (C) 2014
* 最低ひとつのチェックをrequireする
* <p>
* usage:
* <pre>
* <input type="checkbox" name="opt" checkbox-group="optgroup">
* <input type="checkbox" checkbox-group="optgroup">
* <input type="checkbox" checkbox-group="optgorup">
* </pre>
*/
angular.module('checkbox-group', []).directive('checkboxGroup', [
'$parse', '$log',
function ($parse, $log) {
$log.debug('initializing checkboxGroup directive.');
var linkFn = function (scope, element, attrs, ctrl) {
$log.debug('checkboxGroup linkFn called.');
var representCtrlGetter = $parse(attrs.checkboxGroup + 'RepresentCtrl');
var representCtrlSetter = representCtrlGetter.assign;
var getter = $parse(attrs.checkboxGroup);
var setter = getter.assign;
var count = getter(scope.$parent);
if (typeof count === 'undefined') {
count = 0;
setter(scope.$parent, count);
$log.debug('initialized number of checked boxes to 0.');
}
/* save a represent control of checkboxes group */
if (ctrl.$name) {
$log.debug('saving a represent control.');
if (typeof representCtrlGetter(scope.$parent) !== 'undefined') {
throw 'only one checkbox can have NAME attribute.';
}
representCtrlSetter(scope.$parent, ctrl);
}
ctrl.$validators.requiredCheckbox = function (modelValue, viewValue) {
$log.debug('checkboxGroup validator called.');
var count = getter(scope.$parent);
if (viewValue === true) {
count += 1;
} else if (count > 0 && viewValue === false) {
count -= 1;
}
setter(scope.$parent, count);
$log.debug('number of checked boxes is: ' + count);
representCtrlGetter(scope.$parent).$setValidity('requiredCheckbox', (count > 0));
return (count > 0);
};
};
return {
restrict: 'A',
require: 'ngModel',
scope: true,
link: linkFn
};
}]);