ngx-tree-select
Version:
Angular component for select with tree items.
454 lines • 17.6 kB
JavaScript
import { Component, forwardRef, Input } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { SelectService } from '../services/select.service';
import { TreeSelectDefaultOptions } from '../models/tree-select-default-options';
import { ExpandMode } from '../models/expand-mode';
// tslint:disable-next-line:no-empty
var /** @type {?} */ noop = function () { };
export var /** @type {?} */ CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
// tslint:disable-next-line:no-forward-ref
useExisting: forwardRef(function () { return TreeSelectComponent; }),
multi: true
};
var TreeSelectComponent = /** @class */ (function () {
/**
* @param {?} svc
* @param {?} defaultOpts
*/
function TreeSelectComponent(svc, defaultOpts) {
var _this = this;
this.svc = svc;
this.defaultOpts = defaultOpts;
this.onTouchedCallback = noop;
this.showMoreLink = false;
this.moreLoaded = false;
this.disabled = false;
this.placeholder = '';
this.filterPlaceholder = 'Type here for filtering items...';
this.allowFilter = true;
this._isOpen = false;
this.onChangeCallback = noop;
this.haveFocus = false;
this.inputFocus = false;
this.clickedOutside = this.clickedOutside.bind(this);
this.svc.modelChanged$.subscribe(function (result) {
_this.onChangeCallback(result);
});
this.maxVisibleItemCount = (defaultOpts.maxVisibleItemCount || 0);
this.allowParentSelection = ((defaultOpts.allowParentSelection === undefined ||
defaultOpts.allowParentSelection === null) ?
true :
defaultOpts.allowParentSelection);
this.allowFilter = ((defaultOpts.allowFilter === undefined || defaultOpts.allowFilter === null) ?
true :
defaultOpts.allowFilter);
this.filterCaseSensitive = ((defaultOpts.filterCaseSensitive === undefined || defaultOpts.filterCaseSensitive === null) ?
false :
defaultOpts.filterCaseSensitive);
this.filterPlaceholder = (defaultOpts.filterPlaceholder || 'Type here for filtering items...');
this.idField = (defaultOpts.idField || 'id');
this.textField = (defaultOpts.textField || 'id');
this.childrenField = (defaultOpts.childrenField || '');
this.expandMode = (defaultOpts.expandMode || ExpandMode.None);
}
Object.defineProperty(TreeSelectComponent.prototype, "items", {
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setItems(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "idField", {
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setConfiguration(function (opt) { return opt.idProperty = value; }, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "textField", {
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setConfiguration(function (opt) { return opt.textProperty = value; }, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "allowParentSelection", {
/**
* @return {?}
*/
get: function () {
return this.svc.Configuration.allowParentSelection;
},
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setConfiguration(function (opt) { return opt.allowParentSelection = value; }, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "restructureWhenChildSameName", {
/**
* @return {?}
*/
get: function () {
return this.svc.Configuration.restructureWhenChildSameName;
},
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setConfiguration(function (opt) { return opt.restructureWhenChildSameName = value; }, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "childrenField", {
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setConfiguration(function (opt) { return opt.childProperty = value; }, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "multiple", {
/**
* @return {?}
*/
get: function () {
return this.svc.Configuration.allowMultiple;
},
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setConfiguration(function (opt) { return opt.allowMultiple = value; }, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "filterCaseSensitive", {
/**
* @return {?}
*/
get: function () {
return this.svc.Configuration.filterCaseSensitive;
},
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setConfiguration(function (opt) { return opt.filterCaseSensitive = value; }, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "expandMode", {
/**
* @return {?}
*/
get: function () {
return this.svc.Configuration.expandMode;
},
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setConfiguration(function (opt) { return opt.expandMode = value; }, true);
this.svc.setExpand();
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "maxVisibleItemCount", {
/**
* @return {?}
*/
get: function () {
return this.svc.Configuration.maxVisibleItemCount;
},
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setConfiguration(function (opt) { return opt.maxVisibleItemCount = value; }, true);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "internalItems", {
/**
* @return {?}
*/
get: function () {
return this.svc.getInternalItems() || [];
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "selection", {
/**
* @return {?}
*/
get: function () {
this.showMoreLink = (this.maxVisibleItemCount > 0 &&
((this.svc.getInternalSelection().length - this.maxVisibleItemCount) > 0));
return this.svc.getInternalSelection();
},
enumerable: true,
configurable: true
});
Object.defineProperty(TreeSelectComponent.prototype, "filter", {
/**
* @return {?}
*/
get: function () {
return this.svc.Configuration.filter;
},
/**
* @param {?} value
* @return {?}
*/
set: function (value) {
this.svc.setConfiguration(function (opt) { return opt.filter = value; }, false);
for (var _i = 0, _a = this.internalItems; _i < _a.length; _i++) {
var item = _a[_i];
this.ProcessMatchFilterTreeItem(item, this.svc.Configuration.filter);
}
this.svc.setExpand();
},
enumerable: true,
configurable: true
});
/**
* @param {?} $event
* @return {?}
*/
TreeSelectComponent.prototype.keyUp = function ($event) { };
/**
* @param {?} $event
* @return {?}
*/
TreeSelectComponent.prototype.toggle = function ($event) {
$event.preventDefault();
this.haveFocus = true;
this.svc.toggleOpen();
};
/**
* @param {?} $event
* @param {?} item
* @return {?}
*/
TreeSelectComponent.prototype.removeItem = function ($event, item) {
$event.stopPropagation();
this.svc.toggleItemSelection(item);
};
Object.defineProperty(TreeSelectComponent.prototype, "isOpen", {
/**
* @return {?}
*/
get: function () {
return this.svc.Configuration.isOpen;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
TreeSelectComponent.prototype.clickedOutside = function () {
if (!this.inputFocus) {
if (!this.haveFocus && this.isOpen || this.haveFocus && !this.isOpen) {
this.onTouched();
}
this.haveFocus = false;
}
};
/**
* @return {?}
*/
TreeSelectComponent.prototype.onTouched = function () {
this.svc.close();
this.onTouchedCallback();
};
/**
* @return {?}
*/
TreeSelectComponent.prototype.setInputFocus = function () {
this.inputFocus = true;
};
/**
* @return {?}
*/
TreeSelectComponent.prototype.setInputFocusOut = function () {
this.inputFocus = false;
};
/**
* Write a new value to the element.
*
* \@memberof TreeSelectComponent
* @param {?} value
* @return {?}
*/
TreeSelectComponent.prototype.writeValue = function (value) {
this.svc.setSelection(value);
};
/**
* Set the function to be called when the control receives a change event.
*
* \@memberof TreeSelectComponent
* @param {?} fn
* @return {?}
*/
TreeSelectComponent.prototype.registerOnChange = function (fn) {
this.onChangeCallback = fn;
};
/**
* Set the function to be called when the control receives a touch event.
*
* \@memberof TreeSelectComponent
* @param {?} fn
* @return {?}
*/
TreeSelectComponent.prototype.registerOnTouched = function (fn) {
this.onTouchedCallback = fn;
};
/**
* This function is called when the control status changes to or from "DISABLED".
* Depending on the value, it will enable or disable the appropriate DOM element.
*
* \@memberof TreeSelectComponent
* @param {?} isDisabled
* @return {?}
*/
TreeSelectComponent.prototype.setDisabledState = function (isDisabled) {
this.disabled = isDisabled;
};
/**
* This finction is called when user click on show more link.
*
* \@memberof TreeSelectComponent
* @param {?} $event
* @return {?}
*/
TreeSelectComponent.prototype.loadMore = function ($event) {
$event.stopPropagation();
this.moreLoaded = !this.moreLoaded;
};
/**
* @param {?} tree
* @param {?} filter
* @return {?}
*/
TreeSelectComponent.prototype.ProcessMatchFilterTreeItem = function (tree, filter) {
var /** @type {?} */ result = false;
if (tree && tree.children && tree.children.length > 0) {
for (var _i = 0, _a = tree.children; _i < _a.length; _i++) {
var child = _a[_i];
result = this.ProcessMatchFilterTreeItem(child, filter) || result;
}
}
tree.matchFilter = this.filterCaseSensitive ?
(tree.id.indexOf(filter) > -1 ||
tree.text.indexOf(filter) > -1 ||
result) :
(tree.id.toLowerCase().indexOf(filter.toLowerCase()) > -1 ||
tree.text.toLowerCase().indexOf(filter.toLowerCase()) > -1 ||
result);
return tree.matchFilter;
};
TreeSelectComponent.decorators = [
{ type: Component, args: [{
selector: 'tree-select',
template: "<div tabindex=\"0\" class=\"dropdown open show\" [off-click]=\"clickedOutside\"> <!-- Control display --> <div [class.disabled]=\"disabled\"> <span tabindex=\"-1\" class=\"btn btn-default btn-secondary form-control\" [class.selected-container-text]=\"!multiple\" [class.selected-container-item]=\"multiple\" (click)=\"toggle($event)\"> <span *ngIf=\"selection.length <= 0\" class=\"ui-select-placeholder text-muted\">{{placeholder}}</span> <span *ngFor=\"let itm of selection; let idx=index\"> <span *ngIf=\"moreLoaded || maxVisibleItemCount == 0 || idx<maxVisibleItemCount\" class=\"pull-left\" [class.selected-item-text]=\"!multiple\" [class.selected-item-item]=\"multiple\" [class.btn]=\"multiple\" [class.btn-default]=\"multiple\" [class.btn-xs]=\"multiple\"> {{itm.text}} <a *ngIf=\"multiple && !disabled\" class=\"close\" (click)=\"removeItem($event, itm)\">x</a> </span> </span> </span> </div> <div class=\"enabled\"> <span class=\"pull-right more-items-icon\" (click)=\"loadMore($event)\" *ngIf=\"showMoreLink\">(...)</span> <i class=\"caret pull-right\" (click)=\"toggle($event)\"></i> </div> <!-- options template --> <ul *ngIf=\"!disabled && isOpen && internalItems && internalItems.length > 0\" class=\"dropdown-menu\" role=\"menu\"> <input name=\"filterText\" *ngIf=\"allowFilter\" type=\"text\" [(ngModel)]=\"filter\" (click)=\"setInputFocus()\" (blur)=\"setInputFocusOut()\" class=\"form-control\" placeholder=\"{{filterPlaceholder}}\" [ngModelOptions]=\"{standalone: true}\" autocomplete=\"off\" /> <li *ngFor=\"let o of internalItems | itemPipe:filter\" role=\"menuitem\"> <tree-select-item [item]=\"o\" [onTouchedCallBack]=\"onTouchedCallback\"></tree-select-item> </li> </ul> </div> ",
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR, SelectService],
styles: [":host.ng-invalid:not(.ng-pristine) span.form-control, :host.ng-invalid:not(.ng-untouched) span.form-control { border-color: #a94442; } .input-group > .dropdown { position: static; } .disabled > span { background-color: #eceeef; cursor: not-allowed; } .disabled .btn { border-color: #ccc; } .enabled > span { cursor: context-menu; } ul { height: auto; list-style-type: none; margin-top: 0; max-height: 200px; overflow-x: hidden; width: 100%; } .selected-container-text { padding-left: 7px; } .selected-container-item { padding-left: 2px; } .selected-item-text { font-size: 14px; margin: 3px; } .selected-item-item { font-size: 14px; margin: 2px; outline: 0; } .more-items-icon { bottom: 23px; height: 10px; opacity: .5; position: absolute; right: 20px; z-index: 100; } .close { font-size: 18px; line-height: .75; margin-left: 5px; padding-top: 3px; position: absolute; z-index: 50; } .caret { height: 10px; margin-top: -2px; position: absolute; right: 10px; top: 50%; } .btn { display: table; padding-right: 20px; } "]
},] },
];
/**
* @nocollapse
*/
TreeSelectComponent.ctorParameters = function () { return [
{ type: SelectService, },
{ type: TreeSelectDefaultOptions, },
]; };
TreeSelectComponent.propDecorators = {
'disabled': [{ type: Input },],
'placeholder': [{ type: Input },],
'filterPlaceholder': [{ type: Input },],
'allowFilter': [{ type: Input },],
'items': [{ type: Input },],
'idField': [{ type: Input },],
'textField': [{ type: Input },],
'allowParentSelection': [{ type: Input },],
'restructureWhenChildSameName': [{ type: Input },],
'childrenField': [{ type: Input },],
'multiple': [{ type: Input },],
'filterCaseSensitive': [{ type: Input },],
'expandMode': [{ type: Input },],
'maxVisibleItemCount': [{ type: Input },],
};
return TreeSelectComponent;
}());
export { TreeSelectComponent };
function TreeSelectComponent_tsickle_Closure_declarations() {
/** @type {?} */
TreeSelectComponent.decorators;
/**
* @nocollapse
* @type {?}
*/
TreeSelectComponent.ctorParameters;
/** @type {?} */
TreeSelectComponent.propDecorators;
/** @type {?} */
TreeSelectComponent.prototype.onTouchedCallback;
/** @type {?} */
TreeSelectComponent.prototype.showMoreLink;
/** @type {?} */
TreeSelectComponent.prototype.moreLoaded;
/** @type {?} */
TreeSelectComponent.prototype.disabled;
/** @type {?} */
TreeSelectComponent.prototype.placeholder;
/** @type {?} */
TreeSelectComponent.prototype.filterPlaceholder;
/** @type {?} */
TreeSelectComponent.prototype.allowFilter;
/** @type {?} */
TreeSelectComponent.prototype._isOpen;
/** @type {?} */
TreeSelectComponent.prototype.onChangeCallback;
/** @type {?} */
TreeSelectComponent.prototype.haveFocus;
/** @type {?} */
TreeSelectComponent.prototype.inputFocus;
/** @type {?} */
TreeSelectComponent.prototype.svc;
/** @type {?} */
TreeSelectComponent.prototype.defaultOpts;
}
//# sourceMappingURL=tree-select.component.js.map