javascript - Angularjs: Check / Uncheck checkboxes of categories and list items
问题描述
I've list of categories and list items which i want to have check/uncheck feature. Where clicking on category should also check all child checkboxes. I have a list (of privileges in JSON) where some items have same category like below;
I have example code in plunkr - https://next.plnkr.co/edit/au1XPEjj7MuP77gc
I've JSON code like below.
var list = [{
"uuid": "0023",
"title": "AM_FULL_ACCESS",
"displayName": "Application monitoring Full access",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Application Monitoring"
},
{
"uuid": "0025",
"title": "CM_FULL_ACCESS",
"displayName": "Client management Full access",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Client Management"
},
{
"uuid": "0031",
"title": "COMPLIANCE_FULL_ACCESS",
"displayName": "Compliance Full access",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Compliance"
},
{
"uuid": "0054",
"title": "FAILED_APPLICATION_ACCESS",
"displayName": "Failed application access",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Compliance"
},
{
"uuid": "0068",
"title": "FUND_TRANSFER",
"displayName": "Fund Transfer",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Funds"
},
{
"uuid": "0067",
"title": "FUND_LOADING",
"displayName": "Fund Loading",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Funds"
},
{
"uuid": "0066",
"title": "FUND_LOADING_TRANSFER",
"displayName": "Fund Loading and transfer",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Funds"
}
];
To put each list item under specific category I've loop through JSON and filtered it with ng-if directive to show specific list items if has same category.
Here View (HTML Code)
<label>
<input type="checkbox" id="" ng-model="IsAllChecked" ng-change="CheckUncheckAll()">
<span class="ml-1">Application Monitoring</span>
</label>
<ul class="list-unstyled">
<li ng-repeat="pr in privilegesList track by $index" ng-if="pr.category === 'Application Monitoring'">
<label class="control-label">
<input id="pr.title" type="checkbox" ng-model="pr.isActive" ng-change="CheckUncheckHeader()">
<span>{{pr.displayName}}</span>
</label>
</li>
</ul>
<label>
<input type="checkbox" id="" ng-model="IsAllChecked" ng-change="CheckUncheckAll()">
<span class="ml-1">Client Management</span>
</label>
<ul class="list-unstyled">
<li ng-repeat="pr in privilegesList track by $index" ng-if="pr.category === 'Client Management'">
<label class="control-label">
<input id="pr.title" type="checkbox" ng-model="pr.isActive" ng-change="CheckUncheckHeader()">
<span>{{pr.displayName}}</span>
</label>
</li>
</ul>
<label>
<input type="checkbox" id="" ng-model="IsAllChecked" ng-change="CheckUncheckAll()">
<span class="ml-1">Compliance</span>
</label>
<ul class="list-unstyled">
<li ng-repeat="pr in privilegesList track by $index" ng-if="pr.category === 'Compliance'">
<label class="control-label">
<input id="pr.title" type="checkbox" ng-model="pr.isActive" ng-change="CheckUncheckHeader()">
<span>{{pr.displayName}}</span>
</label>
</li>
</ul>
<label>
<input type="checkbox" id="" ng-model="IsAllChecked" ng-change="CheckUncheckAll()">
<span class="ml-1">Funds</span>
</label>
<ul class="list-unstyled">
<li ng-repeat="pr in privilegesList track by $index" ng-if="pr.category === 'Funds'">
<label class="control-label">
<input id="pr.title" type="checkbox" ng-model="pr.isActive" ng-change="CheckUncheckHeader()">
<span>{{pr.displayName}}</span>
</label>
</li>
</ul>
Doing it ng-if seems to work fine but i want to do it with something more better solution (if there is any). Also i want to add Check/Uncheck feature to all categories and their respective child items. So if i check any category all child checkboxes will also be checked. And if any/all item checkbox gets unchecked that parent checkbox should be unchecked.
I've following JS code which seems to serves the check/uncheck all. I'm able to do this for specific category but i want to have script that do it for all categories and its sub checkboxes.
解决方案
也许这个脚本很有用。
angular.module('someApp', [])
.controller('someController', function someController($scope) {
$scope.getCategories = getCategories;
$scope.getPrivilegesByCategory = getPrivilegesByCategory;
$scope.selectCategory = selectCategory;
$scope.checkCategory = checkCategory;
$scope.privileges = getCategories().reduce(
function(acc, category, index) {
acc.push({
category: category,
data: getPrivilegesByCategory(category)
});
return acc;
}, []);
});
angular.bootstrap(
document.body, ['someApp']
);
function getCategories() {
var categories = privilegesService().reduce(
function(acc, privilege) {
if (acc.indexOf(privilege.category) === -1) {
acc.push(privilege.category);
}
return acc;
}, []);
return categories;
}
function getPrivilegesByCategory(category) {
var privileges = privilegesService().filter(
function(privilege) {
return privilege.category === category;
});
return privileges;
}
function selectCategory(item) {
checkCategory(item);
item.data.forEach(function(privilege) {
privilege.isActive = !item.isActive;
});
}
function checkCategory(item) {
var res = item.data.filter(function(privilege) {
return privilege.isActive !== true;
});
item.isActive = res.length === 0;
}
function privilegesService() {
return [{
"uuid": "0023",
"title": "AM_FULL_ACCESS",
"displayName": "Application monitoring Full access",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Application Monitoring"
},
{
"uuid": "0025",
"title": "CM_FULL_ACCESS",
"displayName": "Client management Full access",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Client Management"
},
{
"uuid": "0031",
"title": "COMPLIANCE_FULL_ACCESS",
"displayName": "Compliance Full access",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Compliance"
},
{
"uuid": "0054",
"title": "FAILED_APPLICATION_ACCESS",
"displayName": "Failed application access",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Compliance"
},
{
"uuid": "0068",
"title": "FUND_TRANSFER",
"displayName": "Fund Transfer",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Funds"
},
{
"uuid": "0067",
"title": "FUND_LOADING",
"displayName": "Fund Loading",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Funds"
},
{
"uuid": "0066",
"title": "FUND_LOADING_TRANSFER",
"displayName": "Fund Loading and transfer",
"status": "ACTIVE",
"type": "ADMIN",
"category": "Funds"
}
];
}
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-controller="someController">
<div ng-repeat="item in privileges">
<label class="h5 mb-2">
<input type="checkbox" ng-click="selectCategory(item)" ng-model="item.isActive">
<span class="ml-1" ng-bind="item.category"></span>
</label>
<ul class="list-unstyled ml-4">
<li ng-repeat="pr in item.data track by $index">
<label class="control-label">
<input type="checkbox" ng-model="pr.isActive" ng-change="checkCategory(item)">
<span ng-bind="pr.displayName"></span>
</label>
</li>
</ul>
</div>
</div>
推荐阅读
- python - 如何从 PSUTIL 打印命名元组的内容
- python-3.x - Flask RadioField 不能以 POST 形式工作
- javascript - 有没有办法给名称对象?
- c - 是否可以区分反编译代码和手写代码?
- c++ - 如何重新分配三重指针
- api - 何时使用 RestRequest/RestResponse,何时使用 HttpResuest/HttpResponse?
- python - 未调用 Python 函数。只能打印我的打印语句中的问题
- django - Django 在退出视图或导航到与当前 URL 不同的 URL 时运行函数
- c - 查找数组中的哪些值至少出现 x 次
- d3.js - 在 D3 中可视化来自不同 csv 文件的数据