UNPKG

ng2-completer

Version:

ng2 autocomplete/typeahead component

1,784 lines (1,772 loc) 73.9 kB
/** * @license ng2-completer * MIT license */ import { __extends } from 'tslib'; import { Subject, Observable, timer } from 'rxjs'; import { EventEmitter, Injectable, Directive, Output, ElementRef, Host, HostListener, NgZone, Input, ChangeDetectorRef, TemplateRef, ViewContainerRef, Renderer, Component, ViewChild, forwardRef, NgModule } from '@angular/core'; import { catchError, map, take } from 'rxjs/operators'; import { HttpClient } from '@angular/common/http'; import { NgModel, FormControl, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import { CommonModule } from '@angular/common'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @type {?} */ var MAX_CHARS = 524288; /** @type {?} */ var MIN_SEARCH_LENGTH = 3; /** @type {?} */ var PAUSE = 10; /** @type {?} */ var TEXT_SEARCHING = "Searching..."; /** @type {?} */ var TEXT_NO_RESULTS = "No results found"; /** @type {?} */ var CLEAR_TIMEOUT = 50; /** * @param {?} value * @return {?} */ function isNil(value) { return typeof value === "undefined" || value === null; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @abstract */ var /** * @abstract */ CompleterBaseData = /** @class */ (function (_super) { __extends(CompleterBaseData, _super); function CompleterBaseData() { var _this = _super.call(this) || this; _this._searchFields = null; _this._titleField = null; _this._descriptionField = undefined; _this._imageField = undefined; return _this; } /** * @return {?} */ CompleterBaseData.prototype.cancel = /** * @return {?} */ function () { return; }; /** * @param {?} searchFields * @return {?} */ CompleterBaseData.prototype.searchFields = /** * @param {?} searchFields * @return {?} */ function (searchFields) { this._searchFields = searchFields; return this; }; /** * @param {?} titleField * @return {?} */ CompleterBaseData.prototype.titleField = /** * @param {?} titleField * @return {?} */ function (titleField) { this._titleField = titleField; return this; }; /** * @param {?} descriptionField * @return {?} */ CompleterBaseData.prototype.descriptionField = /** * @param {?} descriptionField * @return {?} */ function (descriptionField) { this._descriptionField = descriptionField; return this; }; /** * @param {?} imageField * @return {?} */ CompleterBaseData.prototype.imageField = /** * @param {?} imageField * @return {?} */ function (imageField) { this._imageField = imageField; return this; }; /** * @param {?} data * @return {?} */ CompleterBaseData.prototype.convertToItem = /** * @param {?} data * @return {?} */ function (data) { /** @type {?} */ var image = null; /** @type {?} */ var formattedText; /** @type {?} */ var formattedDesc = null; if (this._titleField) { formattedText = this.extractTitle(data); } else { formattedText = data; } if (typeof formattedText !== "string") { formattedText = JSON.stringify(formattedText); } if (this._descriptionField) { formattedDesc = this.extractValue(data, this._descriptionField); } if (this._imageField) { image = this.extractValue(data, this._imageField); } if (isNil(formattedText)) { return null; } return /** @type {?} */ ({ description: formattedDesc, image: image, originalObject: data, title: formattedText }); }; /** * @param {?} data * @param {?} term * @return {?} */ CompleterBaseData.prototype.extractMatches = /** * @param {?} data * @param {?} term * @return {?} */ function (data, term) { var _this = this; /** @type {?} */ var matches = []; /** @type {?} */ var searchFields = this._searchFields ? this._searchFields.split(",") : null; if (this._searchFields !== null && this._searchFields !== undefined && term !== "") { matches = data.filter(function (item) { /** @type {?} */ var values = searchFields ? _this.extractBySearchFields(searchFields, item) : [item]; return values.some(function (value) { return value .toString() .toLowerCase() .indexOf(term.toString().toLowerCase()) >= 0; }); }); } else { matches = data; } return matches; }; /** * @param {?} item * @return {?} */ CompleterBaseData.prototype.extractTitle = /** * @param {?} item * @return {?} */ function (item) { var _this = this; // split title fields and run extractValue for each and join with ' ' if (!this._titleField) { return ""; } return this._titleField.split(",") .map(function (field) { return _this.extractValue(item, field); }) .reduce(function (acc, titlePart) { return acc ? acc + " " + titlePart : titlePart; }); }; /** * @param {?} obj * @param {?} key * @return {?} */ CompleterBaseData.prototype.extractValue = /** * @param {?} obj * @param {?} key * @return {?} */ function (obj, key) { /** @type {?} */ var keys; /** @type {?} */ var result; if (key) { keys = key.split("."); result = obj; for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { key = keys_1[_i]; if (result) { result = result[key]; } } } else { result = obj; } return result; }; /** * @param {?} matches * @return {?} */ CompleterBaseData.prototype.processResults = /** * @param {?} matches * @return {?} */ function (matches) { /** @type {?} */ var i; /** @type {?} */ var results = []; if (matches && matches.length > 0) { for (i = 0; i < matches.length; i++) { /** @type {?} */ var item = this.convertToItem(matches[i]); if (item) { results.push(item); } } } return results; }; /** * @param {?} searchFields * @param {?} item * @return {?} */ CompleterBaseData.prototype.extractBySearchFields = /** * @param {?} searchFields * @param {?} item * @return {?} */ function (searchFields, item) { var _this = this; return searchFields .map(function (searchField) { return _this.extractValue(item, searchField); }).filter(function (value) { return !!value; }); }; return CompleterBaseData; }(Subject)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var LocalData = /** @class */ (function (_super) { __extends(LocalData, _super); function LocalData() { var _this = _super.call(this) || this; _this.dataSourceChange = new EventEmitter(); _this._data = []; _this.savedTerm = null; return _this; } /** * @param {?} data * @return {?} */ LocalData.prototype.data = /** * @param {?} data * @return {?} */ function (data) { var _this = this; if (data instanceof Observable) { /** @type {?} */ var data$ = /** @type {?} */ (data); data$ .pipe(catchError(function () { return []; })) .subscribe(function (res) { _this._data = res; if (_this.savedTerm) { _this.search(_this.savedTerm); } _this.dataSourceChange.emit(); }); } else { this._data = data; } this.dataSourceChange.emit(); return this; }; /** * @param {?} term * @return {?} */ LocalData.prototype.search = /** * @param {?} term * @return {?} */ function (term) { if (!this._data) { this.savedTerm = term; } else { this.savedTerm = null; /** @type {?} */ var matches = this.extractMatches(this._data, term); this.next(this.processResults(matches)); } }; /** * @param {?} data * @return {?} */ LocalData.prototype.convertToItem = /** * @param {?} data * @return {?} */ function (data) { return _super.prototype.convertToItem.call(this, data); }; return LocalData; }(CompleterBaseData)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var RemoteData = /** @class */ (function (_super) { __extends(RemoteData, _super); function RemoteData(http) { var _this = _super.call(this) || this; _this.http = http; _this.dataSourceChange = new EventEmitter(); _this._remoteUrl = null; _this.remoteSearch = null; _this._urlFormater = null; _this._dataField = null; return _this; } /** * @param {?} remoteUrl * @return {?} */ RemoteData.prototype.remoteUrl = /** * @param {?} remoteUrl * @return {?} */ function (remoteUrl) { this._remoteUrl = remoteUrl; this.dataSourceChange.emit(); return this; }; /** * @param {?} urlFormater * @return {?} */ RemoteData.prototype.urlFormater = /** * @param {?} urlFormater * @return {?} */ function (urlFormater) { this._urlFormater = urlFormater; }; /** * @param {?} dataField * @return {?} */ RemoteData.prototype.dataField = /** * @param {?} dataField * @return {?} */ function (dataField) { this._dataField = dataField; }; /** * @param {?} requestOptions * @return {?} */ RemoteData.prototype.requestOptions = /** * @param {?} requestOptions * @return {?} */ function (requestOptions) { this._requestOptions = requestOptions; }; /** * @param {?} term * @return {?} */ RemoteData.prototype.search = /** * @param {?} term * @return {?} */ function (term) { var _this = this; this.cancel(); /** @type {?} */ var url = ""; if (this._urlFormater) { url = this._urlFormater(term); } else { url = this._remoteUrl + encodeURIComponent(term); } this.remoteSearch = this.http .get(url, Object.assign({}, this._requestOptions)) .pipe(map(function (data) { /** @type {?} */ var matches = _this.extractValue(data, _this._dataField); return _this.extractMatches(matches, term); }), catchError(function () { return []; })) .subscribe(function (matches) { /** @type {?} */ var results = _this.processResults(matches); _this.next(results); }); }; /** * @return {?} */ RemoteData.prototype.cancel = /** * @return {?} */ function () { if (this.remoteSearch) { this.remoteSearch.unsubscribe(); } }; /** * @param {?} data * @return {?} */ RemoteData.prototype.convertToItem = /** * @param {?} data * @return {?} */ function (data) { return _super.prototype.convertToItem.call(this, data); }; return RemoteData; }(CompleterBaseData)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var LocalDataFactory = /** @class */ (function () { function LocalDataFactory() { } /** * @return {?} */ LocalDataFactory.prototype.create = /** * @return {?} */ function () { return new LocalData(); }; LocalDataFactory.decorators = [ { type: Injectable }, ]; return LocalDataFactory; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var RemoteDataFactory = /** @class */ (function () { function RemoteDataFactory(http) { this.http = http; } /** * @return {?} */ RemoteDataFactory.prototype.create = /** * @return {?} */ function () { return new RemoteData(this.http); }; RemoteDataFactory.decorators = [ { type: Injectable }, ]; /** @nocollapse */ RemoteDataFactory.ctorParameters = function () { return [ { type: HttpClient } ]; }; return RemoteDataFactory; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var CompleterService = /** @class */ (function () { function CompleterService(localDataFactory, remoteDataFactory // Using any instead of () => LocalData because of AoT errors ) { this.localDataFactory = localDataFactory; this.remoteDataFactory = remoteDataFactory; } /** * @param {?} data * @param {?=} searchFields * @param {?=} titleField * @return {?} */ CompleterService.prototype.local = /** * @param {?} data * @param {?=} searchFields * @param {?=} titleField * @return {?} */ function (data, searchFields, titleField) { if (searchFields === void 0) { searchFields = ""; } if (titleField === void 0) { titleField = ""; } /** @type {?} */ var localData = this.localDataFactory.create(); return localData .data(data) .searchFields(searchFields) .titleField(titleField); }; /** * @param {?} url * @param {?=} searchFields * @param {?=} titleField * @return {?} */ CompleterService.prototype.remote = /** * @param {?} url * @param {?=} searchFields * @param {?=} titleField * @return {?} */ function (url, searchFields, titleField) { if (searchFields === void 0) { searchFields = ""; } if (titleField === void 0) { titleField = ""; } /** @type {?} */ var remoteData = this.remoteDataFactory.create(); return remoteData .remoteUrl(url) .searchFields(searchFields) .titleField(titleField); }; CompleterService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ CompleterService.ctorParameters = function () { return [ { type: LocalDataFactory }, { type: RemoteDataFactory } ]; }; return CompleterService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var CtrCompleter = /** @class */ (function () { function CtrCompleter() { this.selected = new EventEmitter(); this.highlighted = new EventEmitter(); this.opened = new EventEmitter(); this.dataSourceChange = new EventEmitter(); this.list = null; this.dropdown = null; this._hasHighlighted = false; this._hasSelected = false; this._cancelBlur = false; this._isOpen = false; this._autoHighlightIndex = null; } /** * @param {?} list * @return {?} */ CtrCompleter.prototype.registerList = /** * @param {?} list * @return {?} */ function (list) { this.list = list; }; /** * @param {?} dropdown * @return {?} */ CtrCompleter.prototype.registerDropdown = /** * @param {?} dropdown * @return {?} */ function (dropdown) { this.dropdown = dropdown; }; /** * @param {?} item * @return {?} */ CtrCompleter.prototype.onHighlighted = /** * @param {?} item * @return {?} */ function (item) { this.highlighted.emit(item); this._hasHighlighted = !!item; }; /** * @param {?} item * @param {?=} clearList * @return {?} */ CtrCompleter.prototype.onSelected = /** * @param {?} item * @param {?=} clearList * @return {?} */ function (item, clearList) { if (clearList === void 0) { clearList = true; } this.selected.emit(item); if (item) { this._hasSelected = true; } if (clearList) { this.clear(); } }; /** * @return {?} */ CtrCompleter.prototype.onDataSourceChange = /** * @return {?} */ function () { if (this.hasSelected) { this.selected.emit(null); this._hasSelected = false; } this.dataSourceChange.emit(); }; /** * @param {?} term * @return {?} */ CtrCompleter.prototype.search = /** * @param {?} term * @return {?} */ function (term) { if (this._hasSelected) { this.selected.emit(null); this._hasSelected = false; } if (this.list) { this.list.search(term); } }; /** * @return {?} */ CtrCompleter.prototype.clear = /** * @return {?} */ function () { this._hasHighlighted = false; this.isOpen = false; if (this.dropdown) { this.dropdown.clear(); } if (this.list) { this.list.clear(); } }; /** * @return {?} */ CtrCompleter.prototype.selectCurrent = /** * @return {?} */ function () { if (this.dropdown) { this.dropdown.selectCurrent(); } }; /** * @return {?} */ CtrCompleter.prototype.nextRow = /** * @return {?} */ function () { if (this.dropdown) { this.dropdown.nextRow(); } }; /** * @return {?} */ CtrCompleter.prototype.prevRow = /** * @return {?} */ function () { if (this.dropdown) { this.dropdown.prevRow(); } }; /** * @return {?} */ CtrCompleter.prototype.hasHighlighted = /** * @return {?} */ function () { return this._hasHighlighted; }; /** * @param {?} cancel * @return {?} */ CtrCompleter.prototype.cancelBlur = /** * @param {?} cancel * @return {?} */ function (cancel) { this._cancelBlur = cancel; }; /** * @return {?} */ CtrCompleter.prototype.isCancelBlur = /** * @return {?} */ function () { return this._cancelBlur; }; /** * @return {?} */ CtrCompleter.prototype.open = /** * @return {?} */ function () { if (!this._isOpen && !!this.list) { this.isOpen = true; this.list.open(); } }; Object.defineProperty(CtrCompleter.prototype, "isOpen", { get: /** * @return {?} */ function () { return this._isOpen; }, set: /** * @param {?} open * @return {?} */ function (open) { this._isOpen = open; this.opened.emit(this._isOpen); if (this.list) { this.list.isOpen(open); } }, enumerable: true, configurable: true }); Object.defineProperty(CtrCompleter.prototype, "autoHighlightIndex", { get: /** * @return {?} */ function () { return this._autoHighlightIndex; }, set: /** * @param {?} index * @return {?} */ function (index) { this._autoHighlightIndex = index; if (this.dropdown) { this.dropdown.highlightRow(this._autoHighlightIndex); } }, enumerable: true, configurable: true }); Object.defineProperty(CtrCompleter.prototype, "hasSelected", { get: /** * @return {?} */ function () { return this._hasSelected; }, enumerable: true, configurable: true }); CtrCompleter.decorators = [ { type: Directive, args: [{ selector: "[ctrCompleter]", },] }, ]; CtrCompleter.propDecorators = { selected: [{ type: Output }], highlighted: [{ type: Output }], opened: [{ type: Output }], dataSourceChange: [{ type: Output }] }; return CtrCompleter; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var CtrRowItem = /** @class */ (function () { function CtrRowItem(row, index) { this.row = row; this.index = index; } return CtrRowItem; }()); var CtrDropdown = /** @class */ (function () { function CtrDropdown(completer, el, zone) { this.completer = completer; this.el = el; this.zone = zone; this.rows = []; this.isScrollOn = false; this._rowMouseDown = false; this.completer.registerDropdown(this); } /** * @return {?} */ CtrDropdown.prototype.ngOnDestroy = /** * @return {?} */ function () { this.completer.registerDropdown(null); }; /** * @return {?} */ CtrDropdown.prototype.ngAfterViewInit = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var css = getComputedStyle(this.el.nativeElement); /** @type {?} */ var autoHighlightIndex = this.completer.autoHighlightIndex; this.isScrollOn = !!css.maxHeight && css.overflowY === "auto"; if (autoHighlightIndex) { this.zone.run(function () { _this.highlightRow(autoHighlightIndex); }); } }; /** * @param {?} event * @return {?} */ CtrDropdown.prototype.onMouseDown = /** * @param {?} event * @return {?} */ function (event) { var _this = this; // Support for canceling blur on IE (issue #158) if (!this._rowMouseDown) { this.completer.cancelBlur(true); this.zone.run(function () { _this.completer.cancelBlur(false); }); } else { this._rowMouseDown = false; } }; /** * @param {?} row * @return {?} */ CtrDropdown.prototype.registerRow = /** * @param {?} row * @return {?} */ function (row) { /** @type {?} */ var arrIndex = this.rows.findIndex(function (_row) { return _row.index === row.index; }); if (arrIndex >= 0) { this.rows[arrIndex] = row; } else { this.rows.push(row); } }; /** * @param {?} rowIndex * @return {?} */ CtrDropdown.prototype.unregisterRow = /** * @param {?} rowIndex * @return {?} */ function (rowIndex) { /** @type {?} */ var arrIndex = this.rows.findIndex(function (_row) { return _row.index === rowIndex; }); this.rows.splice(arrIndex, 1); if (this.currHighlighted && rowIndex === this.currHighlighted.index) { this.highlightRow(null); } }; /** * @param {?} index * @return {?} */ CtrDropdown.prototype.highlightRow = /** * @param {?} index * @return {?} */ function (index) { /** @type {?} */ var highlighted = this.rows.find(function (row) { return row.index === index; }); if (isNil(index) || /** @type {?} */ ((index)) < 0) { if (this.currHighlighted) { this.currHighlighted.row.setHighlighted(false); } this.currHighlighted = undefined; this.completer.onHighlighted(null); return; } if (!highlighted) { return; } if (this.currHighlighted) { this.currHighlighted.row.setHighlighted(false); } this.currHighlighted = highlighted; this.currHighlighted.row.setHighlighted(true); this.completer.onHighlighted(this.currHighlighted.row.getDataItem()); if (this.isScrollOn && this.currHighlighted) { /** @type {?} */ var rowTop = this.dropdownRowTop(); if (!rowTop) { return; } if (rowTop < 0) { this.dropdownScrollTopTo(rowTop - 1); } else { /** @type {?} */ var row = this.currHighlighted.row.getNativeElement(); if (this.dropdownHeight() < row.getBoundingClientRect().bottom) { this.dropdownScrollTopTo(this.dropdownRowOffsetHeight(row)); if (this.el.nativeElement.getBoundingClientRect().bottom - this.dropdownRowOffsetHeight(row) < row.getBoundingClientRect().top) { this.dropdownScrollTopTo(row.getBoundingClientRect().top - (this.el.nativeElement.getBoundingClientRect().top + parseInt(/** @type {?} */ (getComputedStyle(this.el.nativeElement).paddingTop), 10))); } } } } }; /** * @return {?} */ CtrDropdown.prototype.clear = /** * @return {?} */ function () { this.rows = []; }; /** * @param {?} item * @return {?} */ CtrDropdown.prototype.onSelected = /** * @param {?} item * @return {?} */ function (item) { this.completer.onSelected(item); }; /** * @return {?} */ CtrDropdown.prototype.rowMouseDown = /** * @return {?} */ function () { this._rowMouseDown = true; }; /** * @return {?} */ CtrDropdown.prototype.selectCurrent = /** * @return {?} */ function () { if (!!this.currHighlighted && !!this.currHighlighted.row) { this.onSelected(this.currHighlighted.row.getDataItem()); } else if (this.rows.length > 0) { this.onSelected(this.rows[0].row.getDataItem()); } }; /** * @return {?} */ CtrDropdown.prototype.nextRow = /** * @return {?} */ function () { /** @type {?} */ var nextRowIndex = 0; if (this.currHighlighted) { nextRowIndex = this.currHighlighted.index + 1; } this.highlightRow(nextRowIndex); }; /** * @return {?} */ CtrDropdown.prototype.prevRow = /** * @return {?} */ function () { /** @type {?} */ var nextRowIndex = -1; if (this.currHighlighted) { nextRowIndex = this.currHighlighted.index - 1; } this.highlightRow(nextRowIndex); }; /** * @param {?} offset * @return {?} */ CtrDropdown.prototype.dropdownScrollTopTo = /** * @param {?} offset * @return {?} */ function (offset) { this.el.nativeElement.scrollTop = this.el.nativeElement.scrollTop + offset; }; /** * @return {?} */ CtrDropdown.prototype.dropdownRowTop = /** * @return {?} */ function () { if (!this.currHighlighted) { return; } return this.currHighlighted.row.getNativeElement().getBoundingClientRect().top - (this.el.nativeElement.getBoundingClientRect().top + parseInt(/** @type {?} */ (getComputedStyle(this.el.nativeElement).paddingTop), 10)); }; /** * @return {?} */ CtrDropdown.prototype.dropdownHeight = /** * @return {?} */ function () { return this.el.nativeElement.getBoundingClientRect().top + parseInt(/** @type {?} */ (getComputedStyle(this.el.nativeElement).maxHeight), 10); }; /** * @param {?} row * @return {?} */ CtrDropdown.prototype.dropdownRowOffsetHeight = /** * @param {?} row * @return {?} */ function (row) { /** @type {?} */ var css = getComputedStyle(row.parentElement); return row.parentElement.offsetHeight + parseInt(/** @type {?} */ (css.marginTop), 10) + parseInt(/** @type {?} */ (css.marginBottom), 10); }; CtrDropdown.decorators = [ { type: Directive, args: [{ selector: "[ctrDropdown]", },] }, ]; /** @nocollapse */ CtrDropdown.ctorParameters = function () { return [ { type: CtrCompleter, decorators: [{ type: Host }] }, { type: ElementRef }, { type: NgZone } ]; }; CtrDropdown.propDecorators = { onMouseDown: [{ type: HostListener, args: ["mousedown", ["$event"],] }] }; return CtrDropdown; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @type {?} */ var KEY_DW = 40; /** @type {?} */ var KEY_RT = 39; /** @type {?} */ var KEY_UP = 38; /** @type {?} */ var KEY_LF = 37; /** @type {?} */ var KEY_ES = 27; /** @type {?} */ var KEY_EN = 13; /** @type {?} */ var KEY_TAB = 9; /** @type {?} */ var KEY_BK = 8; /** @type {?} */ var KEY_SH = 16; /** @type {?} */ var KEY_CL = 20; /** @type {?} */ var KEY_F1 = 112; /** @type {?} */ var KEY_F12 = 123; var CtrInput = /** @class */ (function () { function CtrInput(completer, ngModel, el) { var _this = this; this.completer = completer; this.ngModel = ngModel; this.el = el; this.clearSelected = false; this.clearUnselected = false; this.overrideSuggested = false; this.fillHighlighted = true; this.openOnFocus = false; this.openOnClick = false; this.selectOnClick = false; this.selectOnFocus = false; this.ngModelChange = new EventEmitter(); this._searchStr = ""; this._displayStr = ""; this.blurTimer = null; this.completer.selected.subscribe(function (item) { if (!item) { return; } if (_this.clearSelected) { _this.searchStr = ""; } else { _this.searchStr = item.title; } _this.ngModelChange.emit(_this.searchStr); }); this.completer.highlighted.subscribe(function (item) { if (_this.fillHighlighted) { if (item) { _this._displayStr = item.title; _this.ngModelChange.emit(item.title); } else { _this._displayStr = _this.searchStr; _this.ngModelChange.emit(_this.searchStr); } } }); this.completer.dataSourceChange.subscribe(function () { _this.completer.search(_this.searchStr); }); if (this.ngModel.valueChanges) { this.ngModel.valueChanges.subscribe(function (value) { if (!isNil(value) && _this._displayStr !== value) { if (_this.searchStr !== value) { _this.completer.search(value); } _this.searchStr = value; } }); } } /** * @param {?} event * @return {?} */ CtrInput.prototype.keyupHandler = /** * @param {?} event * @return {?} */ function (event) { if (event.keyCode === KEY_LF || event.keyCode === KEY_RT || event.keyCode === KEY_TAB) { // do nothing return; } if (event.keyCode === KEY_UP || event.keyCode === KEY_EN) { event.preventDefault(); } else if (event.keyCode === KEY_DW) { event.preventDefault(); this.completer.search(this.searchStr); } else if (event.keyCode === KEY_ES) { if (this.completer.isOpen) { this.restoreSearchValue(); this.completer.clear(); event.stopPropagation(); event.preventDefault(); } } }; /** * @param {?} event * @return {?} */ CtrInput.prototype.pasteHandler = /** * @param {?} event * @return {?} */ function (event) { this.completer.open(); }; /** * @param {?} event * @return {?} */ CtrInput.prototype.keydownHandler = /** * @param {?} event * @return {?} */ function (event) { /** @type {?} */ var keyCode = event.keyCode || event.which; if (keyCode === KEY_EN) { if (this.completer.hasHighlighted()) { event.preventDefault(); } this.handleSelection(); } else if (keyCode === KEY_DW) { event.preventDefault(); this.completer.open(); this.completer.nextRow(); } else if (keyCode === KEY_UP) { event.preventDefault(); this.completer.prevRow(); } else if (keyCode === KEY_TAB) { this.handleSelection(); } else if (keyCode === KEY_BK) { this.completer.open(); } else if (keyCode === KEY_ES) { // This is very specific to IE10/11 #272 // without this, IE clears the input text event.preventDefault(); if (this.completer.isOpen) { event.stopPropagation(); } } else { if (keyCode !== 0 && keyCode !== KEY_SH && keyCode !== KEY_CL && (keyCode <= KEY_F1 || keyCode >= KEY_F12) && !event.ctrlKey && !event.metaKey && !event.altKey) { this.completer.open(); } } }; /** * @param {?} event * @return {?} */ CtrInput.prototype.onBlur = /** * @param {?} event * @return {?} */ function (event) { var _this = this; // Check if we need to cancel Blur for IE if (this.completer.isCancelBlur()) { setTimeout(function () { // get the focus back // get the focus back _this.el.nativeElement.focus(); }, 0); return; } if (this.completer.isOpen) { this.blurTimer = timer(200).pipe(take(1)).subscribe(function () { return _this.doBlur(); }); } }; /** * @return {?} */ CtrInput.prototype.onfocus = /** * @return {?} */ function () { if (this.blurTimer) { this.blurTimer.unsubscribe(); this.blurTimer = null; } if (this.selectOnFocus) { this.el.nativeElement.select(); } if (this.openOnFocus) { this.completer.open(); } }; /** * @param {?} event * @return {?} */ CtrInput.prototype.onClick = /** * @param {?} event * @return {?} */ function (event) { if (this.selectOnClick) { this.el.nativeElement.select(); } if (this.openOnClick) { if (this.completer.isOpen) { this.completer.clear(); } else { this.completer.open(); } } }; Object.defineProperty(CtrInput.prototype, "searchStr", { get: /** * @return {?} */ function () { return this._searchStr; }, set: /** * @param {?} term * @return {?} */ function (term) { this._searchStr = term; this._displayStr = term; }, enumerable: true, configurable: true }); /** * @return {?} */ CtrInput.prototype.handleSelection = /** * @return {?} */ function () { if (this.completer.hasHighlighted()) { this._searchStr = ""; this.completer.selectCurrent(); } else if (this.overrideSuggested) { this.completer.onSelected({ title: this.searchStr, originalObject: null }); } else { if (this.clearUnselected && !this.completer.hasSelected) { this.searchStr = ""; this.ngModelChange.emit(this.searchStr); } this.completer.clear(); } }; /** * @return {?} */ CtrInput.prototype.restoreSearchValue = /** * @return {?} */ function () { if (this.fillHighlighted) { if (this._displayStr != this.searchStr) { this._displayStr = this.searchStr; this.ngModelChange.emit(this.searchStr); } } }; /** * @return {?} */ CtrInput.prototype.doBlur = /** * @return {?} */ function () { if (this.blurTimer) { this.blurTimer.unsubscribe(); this.blurTimer = null; } if (this.overrideSuggested) { this.completer.onSelected({ title: this.searchStr, originalObject: null }); } else { if (this.clearUnselected && !this.completer.hasSelected) { this.searchStr = ""; this.ngModelChange.emit(this.searchStr); } else { this.restoreSearchValue(); } } this.completer.clear(); }; CtrInput.decorators = [ { type: Directive, args: [{ selector: "[ctrInput]", },] }, ]; /** @nocollapse */ CtrInput.ctorParameters = function () { return [ { type: CtrCompleter, decorators: [{ type: Host }] }, { type: NgModel }, { type: ElementRef } ]; }; CtrInput.propDecorators = { clearSelected: [{ type: Input, args: ["clearSelected",] }], clearUnselected: [{ type: Input, args: ["clearUnselected",] }], overrideSuggested: [{ type: Input, args: ["overrideSuggested",] }], fillHighlighted: [{ type: Input, args: ["fillHighlighted",] }], openOnFocus: [{ type: Input, args: ["openOnFocus",] }], openOnClick: [{ type: Input, args: ["openOnClick",] }], selectOnClick: [{ type: Input, args: ["selectOnClick",] }], selectOnFocus: [{ type: Input, args: ["selectOnFocus",] }], ngModelChange: [{ type: Output }], keyupHandler: [{ type: HostListener, args: ["keyup", ["$event"],] }], pasteHandler: [{ type: HostListener, args: ["paste", ["$event"],] }], keydownHandler: [{ type: HostListener, args: ["keydown", ["$event"],] }], onBlur: [{ type: HostListener, args: ["blur", ["$event"],] }], onfocus: [{ type: HostListener, args: ["focus", [],] }], onClick: [{ type: HostListener, args: ["click", ["$event"],] }] }; return CtrInput; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var CtrListContext = /** @class */ (function () { function CtrListContext(results, searching, searchInitialized, isOpen) { this.results = results; this.searching = searching; this.searchInitialized = searchInitialized; this.isOpen = isOpen; } return CtrListContext; }()); var CtrList = /** @class */ (function () { function CtrList(completer, templateRef, viewContainer, cd, zone) { this.completer = completer; this.templateRef = templateRef; this.viewContainer = viewContainer; this.cd = cd; this.zone = zone; this.ctrListMinSearchLength = MIN_SEARCH_LENGTH; this.ctrListPause = PAUSE; this.ctrListAutoMatch = false; this.ctrListAutoHighlight = false; this.ctrListDisplaySearching = true; this._dataService = null; this.term = null; this.searchTimer = null; this.clearTimer = null; this.ctx = new CtrListContext([], false, false, false); this._initialValue = null; this.viewRef = null; } /** * @return {?} */ CtrList.prototype.ngOnInit = /** * @return {?} */ function () { this.completer.registerList(this); this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef, new CtrListContext([], false, false, false)); }; Object.defineProperty(CtrList.prototype, "dataService", { set: /** * @param {?} newService * @return {?} */ function (newService) { this._dataService = newService; this.dataServiceSubscribe(); }, enumerable: true, configurable: true }); Object.defineProperty(CtrList.prototype, "initialValue", { set: /** * @param {?} value * @return {?} */ function (value) { var _this = this; if (this._dataService && typeof this._dataService.convertToItem === "function") { this.zone.run(function () { /** @type {?} */ var initialItem = _this._dataService && /** @type {?} */ ((_this._dataService.convertToItem))(value); if (initialItem) { _this.completer.onSelected(initialItem, false); } }); } else if (!this._dataService) { this._initialValue = value; } }, enumerable: true, configurable: true }); /** * @param {?} term * @return {?} */ CtrList.prototype.search = /** * @param {?} term * @return {?} */ function (term) { var _this = this; if (!isNil(term) && term.length >= this.ctrListMinSearchLength && this.term !== term) { if (this.searchTimer) { this.searchTimer.unsubscribe(); this.searchTimer = null; } if (!this.ctx.searching) { if (this.ctrListDisplaySearching) { this.ctx.results = []; } this.ctx.searching = true; this.ctx.searchInitialized = true; this.refreshTemplate(); } if (this.clearTimer) { this.clearTimer.unsubscribe(); } this.searchTimer = timer(this.ctrListPause).pipe(take(1)).subscribe(function () { _this.searchTimerComplete(term); }); } else if (!isNil(term) && term.length < this.ctrListMinSearchLength) { this.clear(); this.term = ""; } }; /** * @return {?} */ CtrList.prototype.clear = /** * @return {?} */ function () { var _this = this; if (this.searchTimer) { this.searchTimer.unsubscribe(); } this.clearTimer = timer(CLEAR_TIMEOUT).pipe(take(1)).subscribe(function () { _this._clear(); }); }; /** * @return {?} */ CtrList.prototype.open = /** * @return {?} */ function () { if (!this.ctx.searchInitialized) { this.search(""); } this.refreshTemplate(); }; /** * @param {?} open * @return {?} */ CtrList.prototype.isOpen = /** * @param {?} open * @return {?} */ function (open) { this.ctx.isOpen = open; }; /** * @return {?} */ CtrList.prototype._clear = /** * @return {?} */ function () { if (this.searchTimer) { this.searchTimer.unsubscribe(); this.searchTimer = null; } if (this.dataService) { this.dataService.cancel(); } this.viewContainer.clear(); this.viewRef = null; }; /** * @param {?} term * @return {?} */ CtrList.prototype.searchTimerComplete = /** * @param {?} term * @return {?} */ function (term) { // Begin the search if (isNil(term) || term.length < this.ctrListMinSearchLength) { this.ctx.searching = false; return; } this.term = term; if (this._dataService) { this._dataService.search(term); } }; /** * @return {?} */ CtrList.prototype.refreshTemplate = /** * @return {?} */ function () { // create the template if it doesn't exist if (!this.viewRef) { this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef, this.ctx); } else if (!this.viewRef.destroyed) { /** @type {?} */ (( // refresh the template this.viewRef)).context.isOpen = this.ctx.isOpen; /** @type {?} */ ((this.viewRef)).context.results = this.ctx.results; /** @type {?} */ ((this.viewRef)).context.searching = this.ctx.searching; /** @type {?} */ ((this.viewRef)).context.searchInitialized = this.ctx.searchInitialized; this.viewRef.detectChanges(); } this.cd.markForCheck(); }; /** * @return {?} */ CtrList.prototype.getBestMatchIndex = /** * @return {?} */ function () { var _this = this; if (!this.ctx.results || !this.term) { return null; } /** @type {?} */ var bestMatch = this.ctx.results.findIndex(function (item) { return item.title.toLowerCase() === /** @type {?} */ ((_this.term)).toLocaleLowerCase(); }); // If not try to find the first item that starts with the term if (bestMatch < 0) { bestMatch = this.ctx.results.findIndex(function (item) { return item.title.toLowerCase().startsWith(/** @type {?} */ ((_this.term)).toLocaleLowerCase()); }); } // If not try to find the first item that includes the term if (bestMatch < 0) { bestMatch = this.ctx.results.findIndex(function (item) { return item.title.toLowerCase().includes(/** @type {?} */ ((_this.term)).toLocaleLowerCase()); }); } return bestMatch < 0 ? null : bestMatch; }; /** * @return {?} */ CtrList.prototype.dataServiceSubscribe = /** * @return {?} */ function () { var _this = this; if (this._dataService) { this._dataService .subscribe(function (results) { _this.ctx.searchInitialized = true; _this.ctx.searching = false; _this.ctx.results = results; if (_this.ctrListAutoMatch && results && results.length === 1 && results[0].title && !isNil(_this.term) && results[0].title.toLocaleLowerCase() === /** @type {?} */ ((_this.term)).toLocaleLowerCase()) { // Do automatch // Do automatch _this.completer.onSelected(results[0]); return; } _this.refreshTemplate(); if (_this.ctrListAutoHighlight) { _this.completer.autoHighlightIndex = _this.getBestMatchIndex(); } }, function (error) { console.error(error); console.error("Unexpected error in dataService: errors should be handled by the dataService Observable"); return []; }); if (this._dataService.dataSourceChange) { this._dataService.dataSourceChange.subscribe(function () { _this.term = null; _this.ctx.searchInitialized = false; _this.ctx.searching = false; _this.ctx.results = []; _this.refreshTemplate(); _this.completer.onDataSourceChange(); }); } } }; CtrList.decorators = [ { type: Directive, args: [{ selector: "[ctrList]", },] }, ]; /** @nocollapse */ CtrList.ctorParameters = function () { return [ { type: CtrCompleter, decorators: [{ type: Host }] }, { type: TemplateRef }, { type: ViewContainerRef }, { type: ChangeDetectorRef }, { type: NgZone } ]; }; CtrList.propDecorators = { ctrListMinSearchLength: [{ type: Input }], ctrListPause: [{ type: Input }], ctrListAutoMatch: [{ type: Input }], ctrListAutoHighlight: [{ type: Input }], ctrListDisplaySearching: [{ type: Input }], dataService: [{ type: Input, args: ["ctrList",] }], initialValue: [{ type: Input, args: ["ctrListInitialValue",] }] }; return CtrList; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var CtrRow = /** @class */ (function () { function CtrRow(el, renderer, dropdown) { this.el = el; this.renderer =