Skip to content

Instantly share code, notes, and snippets.

@aitoroses
Created September 16, 2014 18:56
Show Gist options
  • Save aitoroses/b07e13d02d07143c12bd to your computer and use it in GitHub Desktop.
Save aitoroses/b07e13d02d07143c12bd to your computer and use it in GitHub Desktop.
A directive to pipe multiple checkbox values into the same property.
/**
* @author Aitor Osés Martín
* @description Directive for controlling a
* set of checkboxes inside a single property
* @url http://jsfiddle.net/murray900/Lz6qbkf0/13/
*/
var app = angular.module('main', []);
app.controller('outerCtrl', function ($scope) {
// initial value of the directive
$scope.result = "choice 1 | choice 2";
// set of checkboxes
$scope.checkboxes = [{
value: 'choice 1',
text: 'choice 1'
},{
value: 'choice 2',
text: 'choice 2'
},{
value: 'choice 3',
text: 'choice 3'
}];
});
/**
* Directive implementation
*/
app.controller('MultiplePipedSelectionCtrl', MultiplePipedSelectionCtrl);
function MultiplePipedSelectionCtrl($scope) {
function split() {
if ($scope.ngModel === undefined) return;
return $scope.ngModel.split('|').map(function (c) {
return c.trim();
});
}
function join(arr) {
$scope.ngModel = arr.map(function (c) {
return c;
}).join('|').trim();
return $scope.ngModel;
}
this.$scope = $scope;
$scope.getSelected = function () {
return split();
};
$scope.isValueActive = function (value) {
return split().indexOf(value) != -1;
};
$scope.addSelected = function (newVal) {
var values = split();
if (values.indexOf(newVal) != -1) return;
if (values.length === 0 || values[0] === "") {
values[0] = newVal;
} else {
values.push(newVal);
}
$scope.ngModel = values.join('|');
return newVal;
};
$scope.removeSelected = function (newVal) {
var values = split();
var idx = values.indexOf(newVal.trim());
if (idx == -1) {
return;
} else {
values.splice(idx, 1);
return join(values);
}
};
/*
* Helpers and data
*/
$scope.getModel = function () {
return $scope.ngModel;
};
}
app.directive('multipleCheckbox', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
ngModel: '='
},
controller: 'MultiplePipedSelectionCtrl',
template: '<div class="checkboxes" ng-transclude></div>'
};
});
app.directive('checkbox', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
checkbox: '=data'
},
require: '^multipleCheckbox',
template: '<div class="checkbox">' +
'<label>' +
'<input type="checkbox" value="{{checkbox.value}}" ng-model="model" ng-checked="isChecked()" ng-click="click()">' +
'{{checkbox.text}}' +
'</label>' +
'</div>',
link: function (scope, element, attrs, parent) {
scope.parent = parent;
var $input = document.querySelector('input', element);
// initial state
scope.isChecked = function () {
scope.model = parent.$scope.isValueActive(scope.checkbox.value);
return scope.model;
};
scope.click = function () {
var c = scope.checkbox;
if (!scope.model) {
parent.$scope.addSelected(c.value);
} else {
parent.$scope.removeSelected(c.value);
}
};
}
};
});
/**
* Application bootstrap
*/
angular.element(document).ready(function () {
angular.bootstrap(document, ['main']);
});
<div ng-controller="outerCtrl">
<!-- Display the ngModel property -->
<pre>{{result}}</pre>
<!-- Directive Usage -->
<multiple-checkbox ng-model="result">
<checkbox ng-repeat="checkbox in checkboxes" data="checkbox"></checkbox>
</multiple-checkbox>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment