I have a need to show a list of check boxes on my site listing products and other items. The checklist-model attribute directive works well for this because I can bind it to a list of items that relates to the items selected.
All this works fine when I simply use this code in my angular controller. However, I have several list boxes that need to be displayed the same way with the same "select all" and "select none" buttons for each list. I don't want to repeat this code and layout so I've created my own directive for the entire list.
The problem is when I use my own directive it doesn't bind correctly back to my data, the select all only works once, and the select none doesn't work at all.
I suspect it has something to do with how I'm passing the scope around, and the two directives are not working well together.
Why does this not work inside a directive?
Here is a jsfiddle: https://jsfiddle.net/fande455/m9qhnr9c/7/
HTML
<section ng-app="myApp" ng-controller="couponEditController">
<script type="text/ng-template" id="checkboxlist.template.html">
<div>
<div class="form-input form-list">
<label ng-repeat="item in valuelist | orderBy:value">
<input type="checkbox" checklist-model="model" checklist-value="item" /> {{item[value]}}
<br />
</label>
</div>
<button class="btn btn-default" style="float:left; margin-bottom: 5px;margin-left: 10px;margin-right:10px" ng-click="selectNone()">Select None</button>
<button class="btn btn-default" style="float:left; margin-bottom: 5px;" ng-click="selectAll()">Select All</button>
<div class="cleared"></div>
</div>
</script>
<div>
<checkboxlist model="coupon.Products" value="Name" valuelist="productsList"></checkboxlist>
</div>
</section>
JS
var myApp = angular.module('myApp', ['checklist-model']);
myApp.directive('checkboxlist', [function() {
return {
restrict: 'E',
templateUrl: 'checkboxlist.template.html',
controller: 'checkboxlistController',
scope: {
model: "=",
value: "@",
valuelist: "="
},
require: '^checklist-model'
}
}]);
myApp.controller('checkboxlistController', ['$scope', function($scope) {
$scope.selectAll = function() {
$scope.model = angular.copy($scope.valuelist);
};
$scope.selectNone = function() {
$scope.model = [];
};
}]);
myApp.controller('couponEditController', ['$scope', function($scope) {
$scope.coupon =
{"Id": 1,
"Name": "My Coupon",
"Products": []
}
;
$scope.productsList = [{
"Id": 1,
"Name": "Product 1"
}, {
"Id": 2,
"Name": "Product 2"
}];
}]);
From documentation:
Instead of doing checklistModelList = [] it is better to do checklistModelList.splice(0, checklistModelList.length)
In your code you should do
$scope.selectAll = function() {
$scope.selectNone();
$scope.model.push.apply($scope.model, $scope.valuelist);
};
$scope.selectNone = function() {
$scope.model.length = 0;
};
Here's the updated fiddle: https://jsfiddle.net/m9qhnr9c/9/
The idea is not to replace the array with a new one, but modify only its elements.