ng2-completer
Version:
ng2 autocomplete/typeahead component
1,784 lines (1,772 loc) • 73.9 kB
JavaScript
/**
* @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 =