UNPKG

ngx-treeview

Version:

An Angular treeview component with checkbox

239 lines 13.3 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); import { Component, Input, Output, EventEmitter, TemplateRef } from '@angular/core'; import { isNil, includes } from 'lodash'; import { TreeviewI18n } from './treeview-i18n'; import { TreeviewItem } from './treeview-item'; import { TreeviewConfig } from './treeview-config'; import { TreeviewEventParser } from './treeview-event-parser'; import { TreeviewHelper } from './treeview-helper'; var FilterTreeviewItem = /** @class */ (function (_super) { __extends(FilterTreeviewItem, _super); function FilterTreeviewItem(item) { var _this = _super.call(this, { text: item.text, value: item.value, disabled: item.disabled, checked: item.checked, collapsed: item.collapsed, children: item.children }) || this; _this.refItem = item; return _this; } FilterTreeviewItem.prototype.updateRefChecked = function () { this.children.forEach(function (child) { if (child instanceof FilterTreeviewItem) { child.updateRefChecked(); } }); var refChecked = this.checked; if (refChecked) { for (var _i = 0, _a = this.refItem.children; _i < _a.length; _i++) { var refChild = _a[_i]; if (!refChild.checked) { refChecked = false; break; } } } this.refItem.checked = refChecked; }; return FilterTreeviewItem; }(TreeviewItem)); var TreeviewComponent = /** @class */ (function () { function TreeviewComponent(i18n, defaultConfig, eventParser) { this.i18n = i18n; this.defaultConfig = defaultConfig; this.eventParser = eventParser; this.selectedChange = new EventEmitter(); this.filterChange = new EventEmitter(); this.filterText = ''; this.config = this.defaultConfig; this.allItem = new TreeviewItem({ text: 'All', value: undefined }); this.createHeaderTemplateContext(); } Object.defineProperty(TreeviewComponent.prototype, "hasFilterItems", { get: function () { return !isNil(this.filterItems) && this.filterItems.length > 0; }, enumerable: true, configurable: true }); Object.defineProperty(TreeviewComponent.prototype, "maxHeight", { get: function () { return "" + this.config.maxHeight; }, enumerable: true, configurable: true }); TreeviewComponent.prototype.ngOnChanges = function (changes) { var itemsSimpleChange = changes['items']; if (!isNil(itemsSimpleChange)) { if (!isNil(this.items)) { this.updateFilterItems(); this.updateCollapsedOfAll(); this.raiseSelectedChange(); } } this.createHeaderTemplateContext(); }; TreeviewComponent.prototype.onAllCollapseExpand = function () { var _this = this; this.allItem.collapsed = !this.allItem.collapsed; this.filterItems.forEach(function (item) { return item.setCollapsedRecursive(_this.allItem.collapsed); }); }; TreeviewComponent.prototype.onFilterTextChange = function (text) { this.filterText = text; this.filterChange.emit(text); this.updateFilterItems(); }; TreeviewComponent.prototype.onAllCheckedChange = function () { var checked = this.allItem.checked; this.filterItems.forEach(function (item) { item.setCheckedRecursive(checked); if (item instanceof FilterTreeviewItem) { item.updateRefChecked(); } }); this.raiseSelectedChange(); }; TreeviewComponent.prototype.onItemCheckedChange = function (item, checked) { if (item instanceof FilterTreeviewItem) { item.updateRefChecked(); } this.updateCheckedOfAll(); this.raiseSelectedChange(); }; TreeviewComponent.prototype.raiseSelectedChange = function () { this.generateSelection(); var values = this.eventParser.getSelectedChange(this); this.selectedChange.emit(values); }; TreeviewComponent.prototype.createHeaderTemplateContext = function () { var _this = this; this.headerTemplateContext = { config: this.config, item: this.allItem, onCheckedChange: function () { return _this.onAllCheckedChange(); }, onCollapseExpand: function () { return _this.onAllCollapseExpand(); }, onFilterTextChange: function (text) { return _this.onFilterTextChange(text); } }; }; TreeviewComponent.prototype.generateSelection = function () { var checkedItems = []; var uncheckedItems = []; if (!isNil(this.items)) { var selection = TreeviewHelper.concatSelection(this.items, checkedItems, uncheckedItems); checkedItems = selection.checked; uncheckedItems = selection.unchecked; } this.selection = { checkedItems: checkedItems, uncheckedItems: uncheckedItems }; }; TreeviewComponent.prototype.updateFilterItems = function () { var _this = this; if (this.filterText !== '') { var filterItems_1 = []; var filterText_1 = this.filterText.toLowerCase(); this.items.forEach(function (item) { var newItem = _this.filterItem(item, filterText_1); if (!isNil(newItem)) { filterItems_1.push(newItem); } }); this.filterItems = filterItems_1; } else { this.filterItems = this.items; } this.updateCheckedOfAll(); }; TreeviewComponent.prototype.filterItem = function (item, filterText) { var _this = this; var isMatch = includes(item.text.toLowerCase(), filterText); if (isMatch) { return item; } else { if (!isNil(item.children)) { var children_1 = []; item.children.forEach(function (child) { var newChild = _this.filterItem(child, filterText); if (!isNil(newChild)) { children_1.push(newChild); } }); if (children_1.length > 0) { var newItem = new FilterTreeviewItem(item); newItem.collapsed = false; newItem.children = children_1; return newItem; } } } return undefined; }; TreeviewComponent.prototype.updateCheckedOfAll = function () { var itemChecked = null; for (var _i = 0, _a = this.filterItems; _i < _a.length; _i++) { var filterItem = _a[_i]; if (itemChecked === null) { itemChecked = filterItem.checked; } else if (itemChecked !== filterItem.checked) { itemChecked = undefined; break; } } if (itemChecked === null) { itemChecked = false; } this.allItem.checked = itemChecked; }; TreeviewComponent.prototype.updateCollapsedOfAll = function () { var hasItemExpanded = false; for (var _i = 0, _a = this.filterItems; _i < _a.length; _i++) { var filterItem = _a[_i]; if (!filterItem.collapsed) { hasItemExpanded = true; break; } } this.allItem.collapsed = !hasItemExpanded; }; TreeviewComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-treeview', template: "\n <ng-template #defaultItemTemplate let-item=\"item\" let-onCollapseExpand=\"onCollapseExpand\" let-onCheckedChange=\"onCheckedChange\">\n <div class=\"form-inline row-item\">\n <i *ngIf=\"item.children\" (click)=\"onCollapseExpand()\" aria-hidden=\"true\" class=\"fa\" [class.fa-caret-right]=\"item.collapsed\"\n [class.fa-caret-down]=\"!item.collapsed\"></i>\n <div class=\"form-check\">\n <input type=\"checkbox\" class=\"form-check-input\" [(ngModel)]=\"item.checked\" (ngModelChange)=\"onCheckedChange()\"\n [disabled]=\"item.disabled\" [indeterminate]=\"item.indeterminate\" />\n <label class=\"form-check-label\" (click)=\"item.checked = !item.checked; onCheckedChange()\">\n {{item.text}}\n </label>\n </div>\n </div>\n </ng-template>\n <ng-template #defaultHeaderTemplate let-config=\"config\" let-item=\"item\" let-onCollapseExpand=\"onCollapseExpand\"\n let-onCheckedChange=\"onCheckedChange\" let-onFilterTextChange=\"onFilterTextChange\">\n <div *ngIf=\"config.hasFilter\" class=\"row row-filter\">\n <div class=\"col-12\">\n <input class=\"form-control\" type=\"text\" [placeholder]=\"i18n.getFilterPlaceholder()\" [(ngModel)]=\"filterText\"\n (ngModelChange)=\"onFilterTextChange($event)\" />\n </div>\n </div>\n <div *ngIf=\"hasFilterItems\">\n <div *ngIf=\"config.hasAllCheckBox || config.hasCollapseExpand\" class=\"row row-all\">\n <div class=\"col-12\">\n <div class=\"form-check form-check-inline\" *ngIf=\"config.hasAllCheckBox\">\n <input type=\"checkbox\" class=\"form-check-input\" [(ngModel)]=\"item.checked\" (ngModelChange)=\"onCheckedChange()\"\n [indeterminate]=\"item.indeterminate\" />\n <label class=\"form-check-label\" (click)=\"item.checked = !item.checked; onCheckedChange()\">\n {{i18n.getAllCheckboxText()}}\n </label>\n </div>\n <label *ngIf=\"config.hasCollapseExpand\" class=\"pull-right form-check-label\" (click)=\"onCollapseExpand()\">\n <i [title]=\"i18n.getTooltipCollapseExpandText(item.collapsed)\" aria-hidden=\"true\" class=\"fa\"\n [class.fa-expand]=\"item.collapsed\" [class.fa-compress]=\"!item.collapsed\"></i>\n </label>\n </div>\n </div>\n <div *ngIf=\"config.hasDivider\" class=\"dropdown-divider\"></div>\n </div>\n </ng-template>\n <div class=\"treeview-header\">\n <ng-template [ngTemplateOutlet]=\"headerTemplate || defaultHeaderTemplate\" [ngTemplateOutletContext]=\"headerTemplateContext\">\n </ng-template>\n </div>\n <div [ngSwitch]=\"hasFilterItems\">\n <div *ngSwitchCase=\"true\" class=\"treeview-container\" [style.max-height.px]=\"maxHeight\">\n <ngx-treeview-item *ngFor=\"let item of filterItems\" [config]=\"config\" [item]=\"item\" [template]=\"itemTemplate || defaultItemTemplate\"\n (checkedChange)=\"onItemCheckedChange(item, $event)\">\n </ngx-treeview-item>\n </div>\n <div *ngSwitchCase=\"false\" class=\"treeview-text\">\n {{i18n.getFilterNoItemsFoundText()}}\n </div>\n </div>\n ", styles: ["\n :host /deep/ .treeview-header .row-filter {\n margin-bottom: .5rem;\n }\n\n :host /deep/ .treeview-header .row-all .fa {\n cursor: pointer;\n }\n\n :host /deep/ .treeview-container .row-item {\n margin-bottom: .3rem;\n flex-wrap: nowrap;\n }\n\n :host /deep/ .treeview-container .row-item .fa {\n width: .8rem;\n cursor: pointer;\n margin-right: .3rem;\n }\n\n .treeview-container {\n overflow-y: auto;\n padding-right: .3rem;\n }\n\n .treeview-text {\n padding: .3rem 0;\n white-space: nowrap;\n }\n "] },] }, ]; /** @nocollapse */ TreeviewComponent.ctorParameters = function () { return [ { type: TreeviewI18n }, { type: TreeviewConfig }, { type: TreeviewEventParser } ]; }; TreeviewComponent.propDecorators = { headerTemplate: [{ type: Input }], itemTemplate: [{ type: Input }], items: [{ type: Input }], config: [{ type: Input }], selectedChange: [{ type: Output }], filterChange: [{ type: Output }] }; return TreeviewComponent; }()); export { TreeviewComponent }; //# sourceMappingURL=treeview.component.js.map