primeng
Version:
[](https://opensource.org/licenses/MIT) [](https://badge.fury.io/js/primeng) [ || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var UITreeNode_1;
import { NgModule, Component, Input, AfterContentInit, OnDestroy, Output, EventEmitter, OnInit, ContentChildren, QueryList, TemplateRef, Inject, ElementRef, forwardRef, ChangeDetectionStrategy } from '@angular/core';
import { Optional } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from 'primeng/api';
import { PrimeTemplate } from 'primeng/api';
import { TreeDragDropService } from 'primeng/api';
import { ObjectUtils } from 'primeng/utils';
import { DomHandler } from 'primeng/dom';
let UITreeNode = UITreeNode_1 = class UITreeNode {
constructor(tree) {
this.tree = tree;
}
ngOnInit() {
this.node.parent = this.parentNode;
if (this.parentNode) {
this.tree.syncNodeOption(this.node, this.tree.value, 'parent', this.tree.getNodeWithKey(this.parentNode.key, this.tree.value));
}
}
getIcon() {
let icon;
if (this.node.icon)
icon = this.node.icon;
else
icon = this.node.expanded && this.node.children && this.node.children.length ? this.node.expandedIcon : this.node.collapsedIcon;
return UITreeNode_1.ICON_CLASS + ' ' + icon;
}
isLeaf() {
return this.tree.isNodeLeaf(this.node);
}
toggle(event) {
if (this.node.expanded)
this.collapse(event);
else
this.expand(event);
}
expand(event) {
this.node.expanded = true;
this.tree.onNodeExpand.emit({ originalEvent: event, node: this.node });
}
collapse(event) {
this.node.expanded = false;
this.tree.onNodeCollapse.emit({ originalEvent: event, node: this.node });
}
onNodeClick(event) {
this.tree.onNodeClick(event, this.node);
}
onNodeKeydown(event) {
if (event.which === 13) {
this.tree.onNodeClick(event, this.node);
}
}
onNodeTouchEnd() {
this.tree.onNodeTouchEnd();
}
onNodeRightClick(event) {
this.tree.onNodeRightClick(event, this.node);
}
isSelected() {
return this.tree.isSelected(this.node);
}
onDropPoint(event, position) {
event.preventDefault();
let dragNode = this.tree.dragNode;
let dragNodeIndex = this.tree.dragNodeIndex;
let dragNodeScope = this.tree.dragNodeScope;
let isValidDropPointIndex = this.tree.dragNodeTree === this.tree ? (position === 1 || dragNodeIndex !== this.index - 1) : true;
if (this.tree.allowDrop(dragNode, this.node, dragNodeScope) && isValidDropPointIndex) {
if (this.tree.validateDrop) {
this.tree.onNodeDrop.emit({
originalEvent: event,
dragNode: dragNode,
dropNode: this.node,
dropIndex: this.index,
accept: () => {
this.processPointDrop(dragNode, dragNodeIndex, position);
}
});
}
else {
this.processPointDrop(dragNode, dragNodeIndex, position);
this.tree.onNodeDrop.emit({
originalEvent: event,
dragNode: dragNode,
dropNode: this.node,
dropIndex: this.index
});
}
}
this.draghoverPrev = false;
this.draghoverNext = false;
}
processPointDrop(dragNode, dragNodeIndex, position) {
let newNodeList = this.node.parent ? this.node.parent.children : this.tree.value;
this.tree.dragNodeSubNodes.splice(dragNodeIndex, 1);
let dropIndex = this.index;
if (position < 0) {
dropIndex = (this.tree.dragNodeSubNodes === newNodeList) ? ((this.tree.dragNodeIndex > this.index) ? this.index : this.index - 1) : this.index;
newNodeList.splice(dropIndex, 0, dragNode);
}
else {
dropIndex = newNodeList.length;
newNodeList.push(dragNode);
}
this.tree.dragDropService.stopDrag({
node: dragNode,
subNodes: this.node.parent ? this.node.parent.children : this.tree.value,
index: dragNodeIndex
});
}
onDropPointDragOver(event) {
event.dataTransfer.dropEffect = 'move';
event.preventDefault();
}
onDropPointDragEnter(event, position) {
if (this.tree.allowDrop(this.tree.dragNode, this.node, this.tree.dragNodeScope)) {
if (position < 0)
this.draghoverPrev = true;
else
this.draghoverNext = true;
}
}
onDropPointDragLeave(event) {
this.draghoverPrev = false;
this.draghoverNext = false;
}
onDragStart(event) {
if (this.tree.draggableNodes && this.node.draggable !== false) {
event.dataTransfer.setData("text", "data");
this.tree.dragDropService.startDrag({
tree: this,
node: this.node,
subNodes: this.node.parent ? this.node.parent.children : this.tree.value,
index: this.index,
scope: this.tree.draggableScope
});
}
else {
event.preventDefault();
}
}
onDragStop(event) {
this.tree.dragDropService.stopDrag({
node: this.node,
subNodes: this.node.parent ? this.node.parent.children : this.tree.value,
index: this.index
});
}
onDropNodeDragOver(event) {
event.dataTransfer.dropEffect = 'move';
if (this.tree.droppableNodes) {
event.preventDefault();
event.stopPropagation();
}
}
onDropNode(event) {
if (this.tree.droppableNodes && this.node.droppable !== false) {
event.preventDefault();
event.stopPropagation();
let dragNode = this.tree.dragNode;
if (this.tree.allowDrop(dragNode, this.node, this.tree.dragNodeScope)) {
if (this.tree.validateDrop) {
this.tree.onNodeDrop.emit({
originalEvent: event,
dragNode: dragNode,
dropNode: this.node,
index: this.index,
accept: () => {
this.processNodeDrop(dragNode);
}
});
}
else {
this.processNodeDrop(dragNode);
this.tree.onNodeDrop.emit({
originalEvent: event,
dragNode: dragNode,
dropNode: this.node,
index: this.index
});
}
}
}
this.draghoverNode = false;
}
processNodeDrop(dragNode) {
let dragNodeIndex = this.tree.dragNodeIndex;
this.tree.dragNodeSubNodes.splice(dragNodeIndex, 1);
if (this.node.children)
this.node.children.push(dragNode);
else
this.node.children = [dragNode];
this.tree.dragDropService.stopDrag({
node: dragNode,
subNodes: this.node.parent ? this.node.parent.children : this.tree.value,
index: this.tree.dragNodeIndex
});
}
onDropNodeDragEnter(event) {
if (this.tree.droppableNodes && this.node.droppable !== false && this.tree.allowDrop(this.tree.dragNode, this.node, this.tree.dragNodeScope)) {
this.draghoverNode = true;
}
}
onDropNodeDragLeave(event) {
if (this.tree.droppableNodes) {
let rect = event.currentTarget.getBoundingClientRect();
if (event.x > rect.left + rect.width || event.x < rect.left || event.y >= Math.floor(rect.top + rect.height) || event.y < rect.top) {
this.draghoverNode = false;
}
}
}
onKeyDown(event) {
const nodeElement = event.target.parentElement.parentElement;
if (nodeElement.nodeName !== 'P-TREENODE') {
return;
}
switch (event.which) {
//down arrow
case 40:
const listElement = (this.tree.droppableNodes) ? nodeElement.children[1].children[1] : nodeElement.children[0].children[1];
if (listElement && listElement.children.length > 0) {
this.focusNode(listElement.children[0]);
}
else {
const nextNodeElement = nodeElement.nextElementSibling;
if (nextNodeElement) {
this.focusNode(nextNodeElement);
}
else {
let nextSiblingAncestor = this.findNextSiblingOfAncestor(nodeElement);
if (nextSiblingAncestor) {
this.focusNode(nextSiblingAncestor);
}
}
}
event.preventDefault();
break;
//up arrow
case 38:
if (nodeElement.previousElementSibling) {
this.focusNode(this.findLastVisibleDescendant(nodeElement.previousElementSibling));
}
else {
let parentNodeElement = this.getParentNodeElement(nodeElement);
if (parentNodeElement) {
this.focusNode(parentNodeElement);
}
}
event.preventDefault();
break;
//right arrow
case 39:
if (!this.node.expanded) {
this.expand(event);
}
event.preventDefault();
break;
//left arrow
case 37:
if (this.node.expanded) {
this.collapse(event);
}
else {
let parentNodeElement = this.getParentNodeElement(nodeElement);
if (parentNodeElement) {
this.focusNode(parentNodeElement);
}
}
event.preventDefault();
break;
//enter
case 13:
this.tree.onNodeClick(event, this.node);
event.preventDefault();
break;
default:
//no op
break;
}
}
findNextSiblingOfAncestor(nodeElement) {
let parentNodeElement = this.getParentNodeElement(nodeElement);
if (parentNodeElement) {
if (parentNodeElement.nextElementSibling)
return parentNodeElement.nextElementSibling;
else
return this.findNextSiblingOfAncestor(parentNodeElement);
}
else {
return null;
}
}
findLastVisibleDescendant(nodeElement) {
const childrenListElement = nodeElement.children[0].children[1];
if (childrenListElement && childrenListElement.children.length > 0) {
const lastChildElement = childrenListElement.children[childrenListElement.children.length - 1];
return this.findLastVisibleDescendant(lastChildElement);
}
else {
return nodeElement;
}
}
getParentNodeElement(nodeElement) {
const parentNodeElement = nodeElement.parentElement.parentElement.parentElement;
return parentNodeElement.tagName === 'P-TREENODE' ? parentNodeElement : null;
}
focusNode(element) {
if (this.tree.droppableNodes)
element.children[1].children[0].focus();
else
element.children[0].children[0].focus();
}
};
UITreeNode.ICON_CLASS = 'ui-treenode-icon ';
UITreeNode.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [forwardRef(() => Tree),] }] }
];
__decorate([
Input()
], UITreeNode.prototype, "node", void 0);
__decorate([
Input()
], UITreeNode.prototype, "parentNode", void 0);
__decorate([
Input()
], UITreeNode.prototype, "root", void 0);
__decorate([
Input()
], UITreeNode.prototype, "index", void 0);
__decorate([
Input()
], UITreeNode.prototype, "firstChild", void 0);
__decorate([
Input()
], UITreeNode.prototype, "lastChild", void 0);
UITreeNode = UITreeNode_1 = __decorate([
Component({
selector: 'p-treeNode',
template: `
<ng-template [ngIf]="node">
<li *ngIf="tree.droppableNodes" class="ui-treenode-droppoint" [ngClass]="{'ui-treenode-droppoint-active ui-state-highlight':draghoverPrev}"
(drop)="onDropPoint($event,-1)" (dragover)="onDropPointDragOver($event)" (dragenter)="onDropPointDragEnter($event,-1)" (dragleave)="onDropPointDragLeave($event)"></li>
<li *ngIf="!tree.horizontal" role="treeitem" [ngClass]="['ui-treenode',node.styleClass||'', isLeaf() ? 'ui-treenode-leaf': '']">
<div class="ui-treenode-content" (click)="onNodeClick($event)" (contextmenu)="onNodeRightClick($event)" (touchend)="onNodeTouchEnd()"
(drop)="onDropNode($event)" (dragover)="onDropNodeDragOver($event)" (dragenter)="onDropNodeDragEnter($event)" (dragleave)="onDropNodeDragLeave($event)"
[draggable]="tree.draggableNodes" (dragstart)="onDragStart($event)" (dragend)="onDragStop($event)" [attr.tabindex]="0"
[ngClass]="{'ui-treenode-selectable':tree.selectionMode && node.selectable !== false,'ui-treenode-dragover':draghoverNode, 'ui-treenode-content-selected':isSelected()}"
(keydown)="onKeyDown($event)" [attr.aria-posinset]="this.index + 1" [attr.aria-expanded]="this.node.expanded" [attr.aria-selected]="isSelected()" [attr.aria-label]="node.label">
<span class="ui-tree-toggler pi pi-fw ui-unselectable-text" [ngClass]="{'pi-caret-right':!node.expanded,'pi-caret-down':node.expanded}"
(click)="toggle($event)"></span
><div class="ui-chkbox" *ngIf="tree.selectionMode == 'checkbox'" [attr.aria-checked]="isSelected()"><div class="ui-chkbox-box ui-widget ui-corner-all ui-state-default" [ngClass]="{'ui-state-disabled': node.selectable === false}">
<span class="ui-chkbox-icon ui-clickable pi"
[ngClass]="{'pi-check':isSelected(),'pi-minus':node.partialSelected}"></span></div></div
><span [class]="getIcon()" *ngIf="node.icon||node.expandedIcon||node.collapsedIcon"></span
><span class="ui-treenode-label ui-corner-all"
[ngClass]="{'ui-state-highlight':isSelected()}">
<span *ngIf="!tree.getTemplateForNode(node)">{{node.label}}</span>
<span *ngIf="tree.getTemplateForNode(node)">
<ng-container *ngTemplateOutlet="tree.getTemplateForNode(node); context: {$implicit: node}"></ng-container>
</span>
</span>
</div>
<ul class="ui-treenode-children" style="display: none;" *ngIf="node.children && node.expanded" [style.display]="node.expanded ? 'block' : 'none'" role="group">
<p-treeNode *ngFor="let childNode of node.children;let firstChild=first;let lastChild=last; let index=index; trackBy: tree.nodeTrackBy" [node]="childNode" [parentNode]="node"
[firstChild]="firstChild" [lastChild]="lastChild" [index]="index"></p-treeNode>
</ul>
</li>
<li *ngIf="tree.droppableNodes&&lastChild" class="ui-treenode-droppoint" [ngClass]="{'ui-treenode-droppoint-active ui-state-highlight':draghoverNext}"
(drop)="onDropPoint($event,1)" (dragover)="onDropPointDragOver($event)" (dragenter)="onDropPointDragEnter($event,1)" (dragleave)="onDropPointDragLeave($event)"></li>
<table *ngIf="tree.horizontal" [class]="node.styleClass">
<tbody>
<tr>
<td class="ui-treenode-connector" *ngIf="!root">
<table class="ui-treenode-connector-table">
<tbody>
<tr>
<td [ngClass]="{'ui-treenode-connector-line':!firstChild}"></td>
</tr>
<tr>
<td [ngClass]="{'ui-treenode-connector-line':!lastChild}"></td>
</tr>
</tbody>
</table>
</td>
<td class="ui-treenode" [ngClass]="{'ui-treenode-collapsed':!node.expanded}">
<div class="ui-treenode-content ui-state-default ui-corner-all" tabindex="0"
[ngClass]="{'ui-treenode-selectable':tree.selectionMode,'ui-state-highlight':isSelected()}" (click)="onNodeClick($event)" (contextmenu)="onNodeRightClick($event)"
(touchend)="onNodeTouchEnd()" (keydown)="onNodeKeydown($event)">
<span class="ui-tree-toggler pi pi-fw ui-unselectable-text" [ngClass]="{'pi-plus':!node.expanded,'pi-minus':node.expanded}" *ngIf="!isLeaf()"
(click)="toggle($event)"></span
><span [class]="getIcon()" *ngIf="node.icon||node.expandedIcon||node.collapsedIcon"></span
><span class="ui-treenode-label ui-corner-all">
<span *ngIf="!tree.getTemplateForNode(node)">{{node.label}}</span>
<span *ngIf="tree.getTemplateForNode(node)">
<ng-container *ngTemplateOutlet="tree.getTemplateForNode(node); context: {$implicit: node}"></ng-container>
</span>
</span>
</div>
</td>
<td class="ui-treenode-children-container" *ngIf="node.children && node.expanded" [style.display]="node.expanded ? 'table-cell' : 'none'">
<div class="ui-treenode-children">
<p-treeNode *ngFor="let childNode of node.children;let firstChild=first;let lastChild=last; trackBy: tree.nodeTrackBy" [node]="childNode"
[firstChild]="firstChild" [lastChild]="lastChild"></p-treeNode>
</div>
</td>
</tr>
</tbody>
</table>
</ng-template>
`
}),
__param(0, Inject(forwardRef(() => Tree)))
], UITreeNode);
export { UITreeNode };
let Tree = class Tree {
constructor(el, dragDropService) {
this.el = el;
this.dragDropService = dragDropService;
this.selectionChange = new EventEmitter();
this.onNodeSelect = new EventEmitter();
this.onNodeUnselect = new EventEmitter();
this.onNodeExpand = new EventEmitter();
this.onNodeCollapse = new EventEmitter();
this.onNodeContextMenuSelect = new EventEmitter();
this.onNodeDrop = new EventEmitter();
this.layout = 'vertical';
this.metaKeySelection = true;
this.propagateSelectionUp = true;
this.propagateSelectionDown = true;
this.loadingIcon = 'pi pi-spinner';
this.emptyMessage = 'No records found';
this.filterBy = 'label';
this.filterMode = 'lenient';
this.nodeTrackBy = (index, item) => item;
}
ngOnInit() {
if (this.droppableNodes) {
this.dragStartSubscription = this.dragDropService.dragStart$.subscribe(event => {
this.dragNodeTree = event.tree;
this.dragNode = event.node;
this.dragNodeSubNodes = event.subNodes;
this.dragNodeIndex = event.index;
this.dragNodeScope = event.scope;
});
this.dragStopSubscription = this.dragDropService.dragStop$.subscribe(event => {
this.dragNodeTree = null;
this.dragNode = null;
this.dragNodeSubNodes = null;
this.dragNodeIndex = null;
this.dragNodeScope = null;
this.dragHover = false;
});
}
}
get horizontal() {
return this.layout == 'horizontal';
}
ngAfterContentInit() {
if (this.templates.length) {
this.templateMap = {};
}
this.templates.forEach((item) => {
this.templateMap[item.name] = item.template;
});
}
onNodeClick(event, node) {
let eventTarget = event.target;
if (DomHandler.hasClass(eventTarget, 'ui-tree-toggler')) {
return;
}
else if (this.selectionMode) {
if (node.selectable === false) {
return;
}
if (this.hasFilteredNodes()) {
node = this.getNodeWithKey(node.key, this.value);
if (!node) {
return;
}
}
let index = this.findIndexInSelection(node);
let selected = (index >= 0);
if (this.isCheckboxSelectionMode()) {
if (selected) {
if (this.propagateSelectionDown)
this.propagateDown(node, false);
else
this.selection = this.selection.filter((val, i) => i != index);
if (this.propagateSelectionUp && node.parent) {
this.propagateUp(node.parent, false);
}
this.selectionChange.emit(this.selection);
this.onNodeUnselect.emit({ originalEvent: event, node: node });
}
else {
if (this.propagateSelectionDown)
this.propagateDown(node, true);
else
this.selection = [...this.selection || [], node];
if (this.propagateSelectionUp && node.parent) {
this.propagateUp(node.parent, true);
}
this.selectionChange.emit(this.selection);
this.onNodeSelect.emit({ originalEvent: event, node: node });
}
}
else {
let metaSelection = this.nodeTouched ? false : this.metaKeySelection;
if (metaSelection) {
let metaKey = (event.metaKey || event.ctrlKey);
if (selected && metaKey) {
if (this.isSingleSelectionMode()) {
this.selectionChange.emit(null);
}
else {
this.selection = this.selection.filter((val, i) => i != index);
this.selectionChange.emit(this.selection);
}
this.onNodeUnselect.emit({ originalEvent: event, node: node });
}
else {
if (this.isSingleSelectionMode()) {
this.selectionChange.emit(node);
}
else if (this.isMultipleSelectionMode()) {
this.selection = (!metaKey) ? [] : this.selection || [];
this.selection = [...this.selection, node];
this.selectionChange.emit(this.selection);
}
this.onNodeSelect.emit({ originalEvent: event, node: node });
}
}
else {
if (this.isSingleSelectionMode()) {
if (selected) {
this.selection = null;
this.onNodeUnselect.emit({ originalEvent: event, node: node });
}
else {
this.selection = node;
this.onNodeSelect.emit({ originalEvent: event, node: node });
}
}
else {
if (selected) {
this.selection = this.selection.filter((val, i) => i != index);
this.onNodeUnselect.emit({ originalEvent: event, node: node });
}
else {
this.selection = [...this.selection || [], node];
this.onNodeSelect.emit({ originalEvent: event, node: node });
}
}
this.selectionChange.emit(this.selection);
}
}
}
this.nodeTouched = false;
}
onNodeTouchEnd() {
this.nodeTouched = true;
}
onNodeRightClick(event, node) {
if (this.contextMenu) {
let eventTarget = event.target;
if (eventTarget.className && eventTarget.className.indexOf('ui-tree-toggler') === 0) {
return;
}
else {
let index = this.findIndexInSelection(node);
let selected = (index >= 0);
if (!selected) {
if (this.isSingleSelectionMode())
this.selectionChange.emit(node);
else
this.selectionChange.emit([node]);
}
this.contextMenu.show(event);
this.onNodeContextMenuSelect.emit({ originalEvent: event, node: node });
}
}
}
findIndexInSelection(node) {
let index = -1;
if (this.selectionMode && this.selection) {
if (this.isSingleSelectionMode()) {
let areNodesEqual = (this.selection.key && this.selection.key === node.key) || this.selection == node;
index = areNodesEqual ? 0 : -1;
}
else {
for (let i = 0; i < this.selection.length; i++) {
let selectedNode = this.selection[i];
let areNodesEqual = (selectedNode.key && selectedNode.key === node.key) || selectedNode == node;
if (areNodesEqual) {
index = i;
break;
}
}
}
}
return index;
}
syncNodeOption(node, parentNodes, option, value) {
// to synchronize the node option between the filtered nodes and the original nodes(this.value)
const _node = this.hasFilteredNodes() ? this.getNodeWithKey(node.key, parentNodes) : null;
if (_node) {
_node[option] = value || node[option];
}
}
hasFilteredNodes() {
return this.filter && this.filteredNodes && this.filteredNodes.length;
}
getNodeWithKey(key, nodes) {
for (let node of nodes) {
if (node.key === key) {
return node;
}
if (node.children) {
let matchedNode = this.getNodeWithKey(key, node.children);
if (matchedNode) {
return matchedNode;
}
}
}
}
propagateUp(node, select) {
if (node.children && node.children.length) {
let selectedCount = 0;
let childPartialSelected = false;
for (let child of node.children) {
if (this.isSelected(child)) {
selectedCount++;
}
else if (child.partialSelected) {
childPartialSelected = true;
}
}
if (select && selectedCount == node.children.length) {
this.selection = [...this.selection || [], node];
node.partialSelected = false;
}
else {
if (!select) {
let index = this.findIndexInSelection(node);
if (index >= 0) {
this.selection = this.selection.filter((val, i) => i != index);
}
}
if (childPartialSelected || selectedCount > 0 && selectedCount != node.children.length)
node.partialSelected = true;
else
node.partialSelected = false;
}
this.syncNodeOption(node, this.filteredNodes, 'partialSelected');
}
let parent = node.parent;
if (parent) {
this.propagateUp(parent, select);
}
}
propagateDown(node, select) {
let index = this.findIndexInSelection(node);
if (select && index == -1) {
this.selection = [...this.selection || [], node];
}
else if (!select && index > -1) {
this.selection = this.selection.filter((val, i) => i != index);
}
node.partialSelected = false;
this.syncNodeOption(node, this.filteredNodes, 'partialSelected');
if (node.children && node.children.length) {
for (let child of node.children) {
this.propagateDown(child, select);
}
}
}
isSelected(node) {
return this.findIndexInSelection(node) != -1;
}
isSingleSelectionMode() {
return this.selectionMode && this.selectionMode == 'single';
}
isMultipleSelectionMode() {
return this.selectionMode && this.selectionMode == 'multiple';
}
isCheckboxSelectionMode() {
return this.selectionMode && this.selectionMode == 'checkbox';
}
isNodeLeaf(node) {
return node.leaf == false ? false : !(node.children && node.children.length);
}
getRootNode() {
return this.filteredNodes ? this.filteredNodes : this.value;
}
getTemplateForNode(node) {
if (this.templateMap)
return node.type ? this.templateMap[node.type] : this.templateMap['default'];
else
return null;
}
onDragOver(event) {
if (this.droppableNodes && (!this.value || this.value.length === 0)) {
event.dataTransfer.dropEffect = 'move';
event.preventDefault();
}
}
onDrop(event) {
if (this.droppableNodes && (!this.value || this.value.length === 0)) {
event.preventDefault();
let dragNode = this.dragNode;
if (this.allowDrop(dragNode, null, this.dragNodeScope)) {
let dragNodeIndex = this.dragNodeIndex;
this.dragNodeSubNodes.splice(dragNodeIndex, 1);
this.value = this.value || [];
this.value.push(dragNode);
this.dragDropService.stopDrag({
node: dragNode
});
}
}
}
onDragEnter(event) {
if (this.droppableNodes && this.allowDrop(this.dragNode, null, this.dragNodeScope)) {
this.dragHover = true;
}
}
onDragLeave(event) {
if (this.droppableNodes) {
let rect = event.currentTarget.getBoundingClientRect();
if (event.x > rect.left + rect.width || event.x < rect.left || event.y > rect.top + rect.height || event.y < rect.top) {
this.dragHover = false;
}
}
}
allowDrop(dragNode, dropNode, dragNodeScope) {
if (!dragNode) {
//prevent random html elements to be dragged
return false;
}
else if (this.isValidDragScope(dragNodeScope)) {
let allow = true;
if (dropNode) {
if (dragNode === dropNode) {
allow = false;
}
else {
let parent = dropNode.parent;
while (parent != null) {
if (parent === dragNode) {
allow = false;
break;
}
parent = parent.parent;
}
}
}
return allow;
}
else {
return false;
}
}
isValidDragScope(dragScope) {
let dropScope = this.droppableScope;
if (dropScope) {
if (typeof dropScope === 'string') {
if (typeof dragScope === 'string')
return dropScope === dragScope;
else if (dragScope instanceof Array)
return dragScope.indexOf(dropScope) != -1;
}
else if (dropScope instanceof Array) {
if (typeof dragScope === 'string') {
return dropScope.indexOf(dragScope) != -1;
}
else if (dragScope instanceof Array) {
for (let s of dropScope) {
for (let ds of dragScope) {
if (s === ds) {
return true;
}
}
}
}
}
return false;
}
else {
return true;
}
}
onFilter(event) {
let filterValue = event.target.value;
if (filterValue === '') {
this.filteredNodes = null;
}
else {
this.filteredNodes = [];
const searchFields = this.filterBy.split(',');
const filterText = ObjectUtils.removeAccents(filterValue).toLowerCase();
const isStrictMode = this.filterMode === 'strict';
for (let node of this.value) {
let copyNode = Object.assign({}, node);
let paramsWithoutNode = { searchFields, filterText, isStrictMode };
if ((isStrictMode && (this.findFilteredNodes(copyNode, paramsWithoutNode) || this.isFilterMatched(copyNode, paramsWithoutNode))) ||
(!isStrictMode && (this.isFilterMatched(copyNode, paramsWithoutNode) || this.findFilteredNodes(copyNode, paramsWithoutNode)))) {
this.filteredNodes.push(copyNode);
}
}
}
}
findFilteredNodes(node, paramsWithoutNode) {
if (node) {
let matched = false;
if (node.children) {
let childNodes = [...node.children];
node.children = [];
for (let childNode of childNodes) {
let copyChildNode = Object.assign({}, childNode);
if (this.isFilterMatched(copyChildNode, paramsWithoutNode)) {
matched = true;
node.children.push(copyChildNode);
}
}
}
if (matched) {
node.expanded = true;
return true;
}
}
}
isFilterMatched(node, { searchFields, filterText, isStrictMode }) {
let matched = false;
for (let field of searchFields) {
let fieldValue = ObjectUtils.removeAccents(String(ObjectUtils.resolveFieldData(node, field))).toLowerCase();
if (fieldValue.indexOf(filterText) > -1) {
matched = true;
}
}
if (!matched || (isStrictMode && !this.isNodeLeaf(node))) {
matched = this.findFilteredNodes(node, { searchFields, filterText, isStrictMode }) || matched;
}
return matched;
}
getBlockableElement() {
return this.el.nativeElement.children[0];
}
ngOnDestroy() {
if (this.dragStartSubscription) {
this.dragStartSubscription.unsubscribe();
}
if (this.dragStopSubscription) {
this.dragStopSubscription.unsubscribe();
}
}
};
Tree.ctorParameters = () => [
{ type: ElementRef },
{ type: TreeDragDropService, decorators: [{ type: Optional }] }
];
__decorate([
Input()
], Tree.prototype, "value", void 0);
__decorate([
Input()
], Tree.prototype, "selectionMode", void 0);
__decorate([
Input()
], Tree.prototype, "selection", void 0);
__decorate([
Output()
], Tree.prototype, "selectionChange", void 0);
__decorate([
Output()
], Tree.prototype, "onNodeSelect", void 0);
__decorate([
Output()
], Tree.prototype, "onNodeUnselect", void 0);
__decorate([
Output()
], Tree.prototype, "onNodeExpand", void 0);
__decorate([
Output()
], Tree.prototype, "onNodeCollapse", void 0);
__decorate([
Output()
], Tree.prototype, "onNodeContextMenuSelect", void 0);
__decorate([
Output()
], Tree.prototype, "onNodeDrop", void 0);
__decorate([
Input()
], Tree.prototype, "style", void 0);
__decorate([
Input()
], Tree.prototype, "styleClass", void 0);
__decorate([
Input()
], Tree.prototype, "contextMenu", void 0);
__decorate([
Input()
], Tree.prototype, "layout", void 0);
__decorate([
Input()
], Tree.prototype, "draggableScope", void 0);
__decorate([
Input()
], Tree.prototype, "droppableScope", void 0);
__decorate([
Input()
], Tree.prototype, "draggableNodes", void 0);
__decorate([
Input()
], Tree.prototype, "droppableNodes", void 0);
__decorate([
Input()
], Tree.prototype, "metaKeySelection", void 0);
__decorate([
Input()
], Tree.prototype, "propagateSelectionUp", void 0);
__decorate([
Input()
], Tree.prototype, "propagateSelectionDown", void 0);
__decorate([
Input()
], Tree.prototype, "loading", void 0);
__decorate([
Input()
], Tree.prototype, "loadingIcon", void 0);
__decorate([
Input()
], Tree.prototype, "emptyMessage", void 0);
__decorate([
Input()
], Tree.prototype, "ariaLabel", void 0);
__decorate([
Input()
], Tree.prototype, "ariaLabelledBy", void 0);
__decorate([
Input()
], Tree.prototype, "validateDrop", void 0);
__decorate([
Input()
], Tree.prototype, "filter", void 0);
__decorate([
Input()
], Tree.prototype, "filterBy", void 0);
__decorate([
Input()
], Tree.prototype, "filterMode", void 0);
__decorate([
Input()
], Tree.prototype, "filterPlaceholder", void 0);
__decorate([
Input()
], Tree.prototype, "nodeTrackBy", void 0);
__decorate([
ContentChildren(PrimeTemplate)
], Tree.prototype, "templates", void 0);
Tree = __decorate([
Component({
selector: 'p-tree',
template: `
<div [ngClass]="{'ui-tree ui-widget ui-widget-content ui-corner-all':true,'ui-tree-selectable':selectionMode,'ui-treenode-dragover':dragHover,'ui-tree-loading': loading}" [ngStyle]="style" [class]="styleClass" *ngIf="!horizontal"
(drop)="onDrop($event)" (dragover)="onDragOver($event)" (dragenter)="onDragEnter($event)" (dragleave)="onDragLeave($event)">
<div class="ui-tree-loading-mask ui-widget-overlay" *ngIf="loading"></div>
<div class="ui-tree-loading-content" *ngIf="loading">
<i [class]="'ui-tree-loading-icon pi-spin ' + loadingIcon"></i>
</div>
<div *ngIf="filter" class="ui-tree-filter-container">
<input #filter type="text" autocomplete="off" class="ui-tree-filter ui-inputtext ui-widget ui-state-default ui-corner-all" [attr.placeholder]="filterPlaceholder"
(keydown.enter)="$event.preventDefault()" (input)="onFilter($event)">
<span class="ui-tree-filter-icon pi pi-search"></span>
</div>
<ul class="ui-tree-container" *ngIf="getRootNode()" role="tree" [attr.aria-label]="ariaLabel" [attr.aria-labelledby]="ariaLabelledBy">
<p-treeNode *ngFor="let node of getRootNode(); let firstChild=first;let lastChild=last; let index=index; trackBy: nodeTrackBy" [node]="node"
[firstChild]="firstChild" [lastChild]="lastChild" [index]="index"></p-treeNode>
</ul>
<div class="ui-tree-empty-message" *ngIf="!loading && (value == null || value.length === 0)">{{emptyMessage}}</div>
</div>
<div [ngClass]="{'ui-tree ui-tree-horizontal ui-widget ui-widget-content ui-corner-all':true,'ui-tree-selectable':selectionMode}" [ngStyle]="style" [class]="styleClass" *ngIf="horizontal">
<div class="ui-tree-loading ui-widget-overlay" *ngIf="loading"></div>
<div class="ui-tree-loading-content" *ngIf="loading">
<i [class]="'ui-tree-loading-icon pi-spin ' + loadingIcon"></i>
</div>
<table *ngIf="value&&value[0]">
<p-treeNode [node]="value[0]" [root]="true"></p-treeNode>
</table>
<div class="ui-tree-empty-message" *ngIf="!loading && (value == null || value.length === 0)">{{emptyMessage}}</div>
</div>
`,
changeDetection: ChangeDetectionStrategy.Default
}),
__param(1, Optional())
], Tree);
export { Tree };
let TreeModule = class TreeModule {
};
TreeModule = __decorate([
NgModule({
imports: [CommonModule],
exports: [Tree, SharedModule],
declarations: [Tree, UITreeNode]
})
], TreeModule);
export { TreeModule };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL3ByaW1lbmcvdHJlZS8iLCJzb3VyY2VzIjpbInRyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLE9BQU8sRUFBQyxRQUFRLEVBQUMsU0FBUyxFQUFDLEtBQUssRUFBQyxnQkFBZ0IsRUFBQyxTQUFTLEVBQUMsTUFBTSxFQUFDLFlBQVksRUFBQyxNQUFNLEVBQ2xGLGVBQWUsRUFBQyxTQUFTLEVBQUMsV0FBVyxFQUFDLE1BQU0sRUFBQyxVQUFVLEVBQUMsVUFBVSxFQUFDLHVCQUF1QixFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3JILE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDdkMsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBRTdDLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxhQUFhLENBQUM7QUFDekMsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLGFBQWEsQ0FBQztBQUMxQyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSxhQUFhLENBQUM7QUFHaEQsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMxQyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sYUFBYSxDQUFDO0FBNkV2QyxJQUFhLFVBQVUsa0JBQXZCLE1BQWEsVUFBVTtJQWtCbkIsWUFBNEMsSUFBSTtRQUM1QyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQVksQ0FBQztJQUM3QixDQUFDO0lBUUQsUUFBUTtRQUNKLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7UUFFbkMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2pCLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJ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