@neocomplexx/ngx-neo-completer-mat
Version:
1,897 lines • 78.5 kB
JavaScript
import { EventEmitter, ɵɵdefineDirective, ɵsetClassMetadata, Directive, Output, ɵɵelementStart, ɵɵtext, ɵɵelementEnd, ɵɵnextContext, ɵɵproperty, ɵɵadvance, ɵɵtextInterpolate, ɵɵdefineComponent, ɵɵtemplate, ɵɵpureFunction2, Component, Input, ɵɵdirectiveInject, ElementRef, ɵɵlistener, Host, HostListener, TemplateRef, ViewContainerRef, ChangeDetectorRef, Renderer2, ɵɵdefineInjectable, Injectable, ɵɵinject, ɵɵelement, ɵɵpropertyInterpolate, ɵɵsanitizeUrl, ɵɵpureFunction1, ɵɵgetCurrentView, ɵɵrestoreView, ɵɵreference, forwardRef, ɵɵstaticViewQuery, ɵɵqueryRefresh, ɵɵloadQuery, ɵɵProvidersFeature, ɵɵclassProp, ɵɵattribute, ViewChild, ɵɵdefineNgModule, ɵɵdefineInjector, ɵɵsetNgModuleScope, NgModule } from '@angular/core';
import { NgClass, NgForOf, NgIf, CommonModule } from '@angular/common';
import { NgModel, NG_VALUE_ACCESSOR, FormControl, Validators, DefaultValueAccessor, RequiredValidator, NgControlStatus, MaxLengthValidator, FormControlDirective, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { timer, Subject, Observable } from 'rxjs';
import { take, catchError, map } from 'rxjs/operators';
import { MatFormField, MatLabel } from '@angular/material/form-field';
import { MatInput, MatInputModule } from '@angular/material/input';
import { MatChipList, MatChip, MatChipRemove, MatChipsModule } from '@angular/material/chips';
import { MatIcon, MatIconModule } from '@angular/material/icon';
// tslint:disable-next-line:directive-class-suffix
class CtrCompleter {
constructor() {
this.selected = new EventEmitter();
this.highlighted = new EventEmitter();
this.opened = new EventEmitter();
this.dataSourceChange = new EventEmitter();
this._hasHighlighted = false;
this._hasSelected = false;
this._cancelBlur = false;
this._isOpen = false;
}
registerList(list) {
this.list = list;
}
registerDropdown(dropdown) {
this.dropdown = dropdown;
}
onHighlighted(item) {
this.highlighted.emit(item);
this._hasHighlighted = !!item;
}
onSelected(item, clearList = true) {
this.selected.emit(item);
if (item) {
this._hasSelected = true;
}
if (clearList) {
this.clear();
}
}
onDataSourceChange() {
if (this.hasSelected) {
this.selected.emit(null);
this._hasSelected = false;
}
this.dataSourceChange.emit();
}
search(term) {
if (this._hasSelected) {
this.selected.emit(null);
this._hasSelected = false;
}
if (this.list) {
this.list.search(term);
}
}
clear() {
this._hasHighlighted = false;
this.isOpen = false;
if (this.dropdown) {
this.dropdown.clear();
}
if (this.list) {
this.list.clear();
}
}
selectCurrent() {
if (this.dropdown) {
this.dropdown.selectCurrent();
}
}
nextRow() {
if (this.dropdown) {
this.dropdown.nextRow();
}
}
prevRow() {
if (this.dropdown) {
this.dropdown.prevRow();
}
}
hasHighlighted() {
return this._hasHighlighted;
}
cancelBlur(cancel) {
this._cancelBlur = cancel;
}
isCancelBlur() {
return this._cancelBlur;
}
open() {
if (!this._isOpen) {
this.isOpen = true;
this.list.open();
}
}
get isOpen() {
return this._isOpen;
}
set isOpen(open) {
this._isOpen = open;
this.opened.emit(this._isOpen);
if (this.list) {
this.list.isOpen(open);
}
}
get autoHighlightIndex() {
return this._autoHighlightIndex;
}
set autoHighlightIndex(index) {
this._autoHighlightIndex = index;
if (this.dropdown) {
this.dropdown.highlightRow(this._autoHighlightIndex);
}
}
get hasSelected() {
return this._hasSelected;
}
}
CtrCompleter.ɵfac = function CtrCompleter_Factory(t) { return new (t || CtrCompleter)(); };
CtrCompleter.ɵdir = ɵɵdefineDirective({ type: CtrCompleter, selectors: [["", "ctrCompleter", ""]], outputs: { selected: "selected", highlighted: "highlighted", opened: "opened", dataSourceChange: "dataSourceChange" } });
/*@__PURE__*/ (function () { ɵsetClassMetadata(CtrCompleter, [{
type: Directive,
args: [{
// tslint:disable-next-line:directive-selector
selector: '[ctrCompleter]',
}]
}], null, { selected: [{
type: Output
}], highlighted: [{
type: Output
}], opened: [{
type: Output
}], dataSourceChange: [{
type: Output
}] }); })();
function CompleterListItemCmp_span_1_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "span", 2);
ɵɵtext(1);
ɵɵelementEnd();
} if (rf & 2) {
const part_r1 = ctx.$implicit;
const ctx_r0 = ɵɵnextContext();
ɵɵproperty("ngClass", part_r1.isMatch ? ctx_r0.matchClass : null);
ɵɵadvance(1);
ɵɵtextInterpolate(part_r1.text);
} }
const _c0 = function (a0, a1) { return { "completer-title": a0, "completer-description": a1 }; };
'use strict';
// tslint:disable-next-line:component-class-suffix
class CompleterListItemCmp {
constructor() {
this.parts = [];
}
ngOnInit() {
if (!this.searchStr) {
this.parts.push({ isMatch: false, text: this.text });
return;
}
const matchStr = this.text.toLowerCase();
let matchPos = matchStr.indexOf(this.searchStr.toLowerCase());
let startIndex = 0;
while (matchPos >= 0) {
const matchText = this.text.slice(matchPos, matchPos + this.searchStr.length);
if (matchPos === 0) {
this.parts.push({ isMatch: true, text: matchText });
startIndex += this.searchStr.length;
}
else if (matchPos > 0) {
const matchPart = this.text.slice(startIndex, matchPos);
this.parts.push({ isMatch: false, text: matchPart });
this.parts.push({ isMatch: true, text: matchText });
startIndex += this.searchStr.length + matchPart.length;
}
matchPos = matchStr.indexOf(this.searchStr.toLowerCase(), startIndex);
}
if (startIndex < this.text.length) {
this.parts.push({ isMatch: false, text: this.text.slice(startIndex, this.text.length) });
}
}
}
CompleterListItemCmp.ɵfac = function CompleterListItemCmp_Factory(t) { return new (t || CompleterListItemCmp)(); };
CompleterListItemCmp.ɵcmp = ɵɵdefineComponent({ type: CompleterListItemCmp, selectors: [["completer-list-item"]], inputs: { text: "text", searchStr: "searchStr", matchClass: "matchClass", type: "type" }, decls: 2, vars: 5, consts: [[1, "completer-list-item-holder", 3, "ngClass"], ["class", "completer-list-item", 3, "ngClass", 4, "ngFor", "ngForOf"], [1, "completer-list-item", 3, "ngClass"]], template: function CompleterListItemCmp_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "span", 0);
ɵɵtemplate(1, CompleterListItemCmp_span_1_Template, 2, 2, "span", 1);
ɵɵelementEnd();
} if (rf & 2) {
ɵɵproperty("ngClass", ɵɵpureFunction2(2, _c0, ctx.type === "title", ctx.type === "description"));
ɵɵadvance(1);
ɵɵproperty("ngForOf", ctx.parts);
} }, directives: [NgClass, NgForOf], encapsulation: 2 });
/*@__PURE__*/ (function () { ɵsetClassMetadata(CompleterListItemCmp, [{
type: Component,
args: [{
// tslint:disable-next-line:component-selector
selector: 'completer-list-item',
// tslint:disable-next-line:max-line-length
template: `<span class="completer-list-item-holder" [ngClass]="{'completer-title': type === 'title', 'completer-description': type === 'description'}" >
<span class="completer-list-item" *ngFor="let part of parts" [ngClass]="part.isMatch ? matchClass : null">{{part.text}}</span>
</span>`
}]
}], null, { text: [{
type: Input
}], searchStr: [{
type: Input
}], matchClass: [{
type: Input
}], type: [{
type: Input
}] }); })();
const MAX_CHARS = 524288; // the default max length per the html maxlength attribute
const MIN_SEARCH_LENGTH = 3;
const PAUSE = 10;
const TEXT_SEARCHING = 'Searching...';
const TEXT_NO_RESULTS = 'No results found';
const CLEAR_TIMEOUT = 50;
function isNil(value) {
return typeof value === 'undefined' || value === null;
}
class CtrRowItem {
constructor(row, index) {
this.row = row;
this.index = index;
}
}
// tslint:disable-next-line:directive-class-suffix
class CtrDropdown {
constructor(completer, el) {
this.completer = completer;
this.el = el;
this.rows = [];
this._rowMouseDown = false;
this.completer.registerDropdown(this);
}
ngOnDestroy() {
this.completer.registerDropdown(null);
}
ngAfterViewInit() {
const css = getComputedStyle(this.el.nativeElement);
const autoHighlightIndex = this.completer.autoHighlightIndex;
this.isScrollOn = !!css.maxHeight && css.overflowY === 'auto';
if (autoHighlightIndex) {
setTimeout(() => {
this.highlightRow(autoHighlightIndex);
}, 0);
}
}
onMouseDown(event) {
// Support for canceling blur on IE (issue #158)
if (!this._rowMouseDown) {
this.completer.cancelBlur(true);
setTimeout(() => {
this.completer.cancelBlur(false);
}, 0);
}
else {
this._rowMouseDown = false;
}
}
registerRow(row) {
const arrIndex = this.rows.findIndex(_row => _row.index === row.index);
if (arrIndex >= 0) {
this.rows[arrIndex] = row;
}
else {
this.rows.push(row);
}
}
unregisterRow(rowIndex) {
const arrIndex = this.rows.findIndex(_row => _row.index === rowIndex);
this.rows.splice(arrIndex, 1);
if (this.currHighlighted && rowIndex === this.currHighlighted.index) {
this.highlightRow(null);
}
}
highlightRow(index) {
const highlighted = this.rows.find(row => row.index === index);
// tslint:disable-next-line:no-non-null-assertion
if (isNil(index) || 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) {
const rowTop = this.dropdownRowTop();
if (!rowTop) {
return;
}
if (rowTop < 0) {
this.dropdownScrollTopTo(rowTop - 1);
}
else {
const 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(getComputedStyle(this.el.nativeElement).paddingTop, 10)));
}
}
}
}
}
clear() {
this.rows = [];
}
onSelected(item) {
this.completer.onSelected(item);
}
rowMouseDown() {
this._rowMouseDown = true;
}
selectCurrent() {
if (this.currHighlighted) {
this.onSelected(this.currHighlighted.row.getDataItem());
}
else if (this.rows.length > 0) {
this.onSelected(this.rows[0].row.getDataItem());
}
}
nextRow() {
let nextRowIndex = 0;
if (this.currHighlighted) {
nextRowIndex = this.currHighlighted.index + 1;
}
this.highlightRow(nextRowIndex);
}
prevRow() {
let nextRowIndex = -1;
if (this.currHighlighted) {
nextRowIndex = this.currHighlighted.index - 1;
}
this.highlightRow(nextRowIndex);
}
dropdownScrollTopTo(offset) {
this.el.nativeElement.scrollTop = this.el.nativeElement.scrollTop + offset;
}
dropdownRowTop() {
if (!this.currHighlighted) {
return;
}
return this.currHighlighted.row.getNativeElement().getBoundingClientRect().top -
(this.el.nativeElement.getBoundingClientRect().top +
parseInt(getComputedStyle(this.el.nativeElement).paddingTop, 10));
}
dropdownHeight() {
return this.el.nativeElement.getBoundingClientRect().top +
parseInt(getComputedStyle(this.el.nativeElement).maxHeight, 10);
}
dropdownRowOffsetHeight(row) {
const css = getComputedStyle(row.parentElement);
return row.parentElement.offsetHeight +
parseInt(css.marginTop, 10) + parseInt(css.marginBottom, 10);
}
}
CtrDropdown.ɵfac = function CtrDropdown_Factory(t) { return new (t || CtrDropdown)(ɵɵdirectiveInject(CtrCompleter, 1), ɵɵdirectiveInject(ElementRef)); };
CtrDropdown.ɵdir = ɵɵdefineDirective({ type: CtrDropdown, selectors: [["", "ctrDropdown", ""]], hostBindings: function CtrDropdown_HostBindings(rf, ctx) { if (rf & 1) {
ɵɵlistener("mousedown", function CtrDropdown_mousedown_HostBindingHandler($event) { return ctx.onMouseDown($event); });
} } });
/*@__PURE__*/ (function () { ɵsetClassMetadata(CtrDropdown, [{
type: Directive,
args: [{
// tslint:disable-next-line:directive-selector
selector: '[ctrDropdown]',
}]
}], function () { return [{ type: CtrCompleter, decorators: [{
type: Host
}] }, { type: ElementRef }]; }, { onMouseDown: [{
type: HostListener,
args: ['mousedown', ['$event']]
}] }); })();
// keyboard events
const KEY_DW = 40;
const KEY_RT = 39;
const KEY_UP = 38;
const KEY_LF = 37;
const KEY_ES = 27;
const KEY_EN = 13;
const KEY_TAB = 9;
const KEY_BK = 8;
const KEY_SH = 16;
const KEY_CL = 20;
const KEY_F1 = 112;
const KEY_F12 = 123;
// tslint:disable-next-line:directive-class-suffix
class CtrInput {
constructor(completer, ngModel, el) {
this.completer = completer;
this.ngModel = ngModel;
this.el = el;
// tslint:disable:no-input-rename
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.autoSelectOnEnter = true;
this.ngModelChange = new EventEmitter();
this._searchStr = '';
this._displayStr = '';
this.blurTimer = null;
this.completer.selected.subscribe((item) => {
if (!item) {
return;
}
if (this.clearSelected) {
this.searchStr = '';
}
else {
this.searchStr = item.title;
}
this.ngModelChange.emit(this.searchStr);
});
this.completer.highlighted.subscribe((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(() => {
this.completer.search(this.searchStr);
});
if (this.ngModel.valueChanges) {
this.ngModel.valueChanges.subscribe(value => {
if (!isNil(value) && this._displayStr !== value) {
if (this.searchStr !== value) {
this.completer.search(value);
}
this.searchStr = value;
}
});
}
}
keyupHandler(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();
}
}
}
pasteHandler(event) {
this.completer.open();
}
keydownHandler(event) {
const keyCode = event.keyCode || event.which;
if (keyCode === KEY_EN) {
if (this.completer.hasHighlighted()) {
event.preventDefault();
}
else {
if (this.autoSelectOnEnter) {
event.preventDefault();
this.completer.open();
this.completer.nextRow();
}
}
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();
}
}
}
onBlur(event) {
// Check if we need to cancel Blur for IE
if (this.completer.isCancelBlur()) {
setTimeout(() => {
// get the focus back
this.el.nativeElement.focus();
}, 0);
return;
}
if (this.completer.isOpen) {
this.blurTimer = timer(200).pipe(take(1)).subscribe(() => this.doBlur());
}
}
onfocus() {
if (this.blurTimer) {
this.blurTimer.unsubscribe();
this.blurTimer = null;
}
if (this.selectOnFocus) {
this.el.nativeElement.select();
}
if (this.openOnFocus) {
this.completer.open();
}
}
onClick(event) {
if (this.selectOnClick) {
this.el.nativeElement.select();
}
if (this.openOnClick) {
if (this.completer.isOpen) {
this.completer.clear();
}
else {
this.completer.open();
}
}
}
get searchStr() {
return this._searchStr;
}
set searchStr(term) {
this._searchStr = term;
this._displayStr = term;
}
handleSelection() {
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();
}
}
restoreSearchValue() {
if (this.fillHighlighted) {
if (this._displayStr !== this.searchStr) {
this._displayStr = this.searchStr;
this.ngModelChange.emit(this.searchStr);
}
}
}
doBlur() {
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.ɵfac = function CtrInput_Factory(t) { return new (t || CtrInput)(ɵɵdirectiveInject(CtrCompleter, 1), ɵɵdirectiveInject(NgModel), ɵɵdirectiveInject(ElementRef)); };
CtrInput.ɵdir = ɵɵdefineDirective({ type: CtrInput, selectors: [["", "ctrInput", ""]], hostBindings: function CtrInput_HostBindings(rf, ctx) { if (rf & 1) {
ɵɵlistener("keyup", function CtrInput_keyup_HostBindingHandler($event) { return ctx.keyupHandler($event); })("paste", function CtrInput_paste_HostBindingHandler($event) { return ctx.pasteHandler($event); })("keydown", function CtrInput_keydown_HostBindingHandler($event) { return ctx.keydownHandler($event); })("blur", function CtrInput_blur_HostBindingHandler($event) { return ctx.onBlur($event); })("focus", function CtrInput_focus_HostBindingHandler() { return ctx.onfocus(); })("click", function CtrInput_click_HostBindingHandler($event) { return ctx.onClick($event); });
} }, inputs: { clearSelected: "clearSelected", clearUnselected: "clearUnselected", overrideSuggested: "overrideSuggested", fillHighlighted: "fillHighlighted", openOnFocus: "openOnFocus", openOnClick: "openOnClick", selectOnClick: "selectOnClick", selectOnFocus: "selectOnFocus", autoSelectOnEnter: "autoSelectOnEnter" }, outputs: { ngModelChange: "ngModelChange" } });
/*@__PURE__*/ (function () { ɵsetClassMetadata(CtrInput, [{
type: Directive,
args: [{
// tslint:disable-next-line:directive-selector
selector: '[ctrInput]',
}]
}], function () { return [{ type: CtrCompleter, decorators: [{
type: Host
}] }, { type: NgModel }, { type: ElementRef }]; }, { 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']
}], autoSelectOnEnter: [{
type: Input,
args: ['autoSelectOnEnter']
}], 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']]
}] }); })();
class CtrListContext {
constructor(results, searching, searchInitialized, isOpen) {
this.results = results;
this.searching = searching;
this.searchInitialized = searchInitialized;
this.isOpen = isOpen;
}
}
// tslint:disable:no-non-null-assertion
// tslint:disable-next-line:directive-class-suffix
class CtrList {
constructor(completer, templateRef, viewContainer, cd) {
this.completer = completer;
this.templateRef = templateRef;
this.viewContainer = viewContainer;
this.cd = cd;
this.ctrListMinSearchLength = MIN_SEARCH_LENGTH;
this.ctrListPause = PAUSE;
this.ctrListAutoMatch = false;
this.ctrListAutoHighlight = false;
this.ctrListDisplaySearching = true;
// private results: CompleterItem[] = [];
this.term = null;
// private searching = false;
this.searchTimer = null;
this.clearTimer = null;
this.ctx = new CtrListContext([], false, false, false);
this._initialValue = null;
this.viewRef = null;
}
ngOnInit() {
this.completer.registerList(this);
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef, new CtrListContext([], false, false, false));
}
set dataService(newService) {
this._dataService = newService;
this.dataServiceSubscribe();
}
set initialValue(value) {
if (this._dataService && typeof this._dataService.convertToItem === 'function') {
setTimeout(() => {
if (value) {
const initialItem = this._dataService.convertToItem(value);
if (initialItem) {
this.completer.onSelected(initialItem, false);
}
}
});
}
else if (!this._dataService) {
this._initialValue = value;
}
}
search(term) {
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(() => {
this.searchTimerComplete(term);
});
}
else if (!isNil(term) && term.length < this.ctrListMinSearchLength) {
this.clear();
this.term = '';
}
}
clear() {
if (this.searchTimer) {
this.searchTimer.unsubscribe();
}
this.clearTimer = timer(CLEAR_TIMEOUT).pipe(take(1)).subscribe(() => {
this._clear();
});
}
open() {
if (!this.ctx.searchInitialized) {
this.search('');
}
this.refreshTemplate();
}
isOpen(open) {
this.ctx.isOpen = open;
}
_clear() {
if (this.searchTimer) {
this.searchTimer.unsubscribe();
this.searchTimer = null;
}
if (this.dataService) {
this.dataService.cancel();
}
this.viewContainer.clear();
this.viewRef = null;
}
searchTimerComplete(term) {
// Begin the search
if (isNil(term) || term.length < this.ctrListMinSearchLength) {
this.ctx.searching = false;
return;
}
this.term = term;
this._dataService.search(term);
}
refreshTemplate() {
// 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) {
// refresh the template
this.viewRef.context.isOpen = this.ctx.isOpen;
this.viewRef.context.results = this.ctx.results;
this.viewRef.context.searching = this.ctx.searching;
this.viewRef.context.searchInitialized = this.ctx.searchInitialized;
this.viewRef.detectChanges();
}
this.cd.markForCheck();
}
getBestMatchIndex() {
if (!this.ctx.results || !this.term) {
return null;
}
// First try to find the exact term
let bestMatch = this.ctx.results.findIndex(item => item.title.toLowerCase() === this.term.toLocaleLowerCase());
// If not try to find the first item that starts with the term
if (bestMatch < 0) {
bestMatch = this.ctx.results.findIndex(item => item.title.toLowerCase().startsWith(this.term.toLocaleLowerCase()));
}
// If not try to find the first item that includes the term
if (bestMatch < 0) {
bestMatch = this.ctx.results.findIndex(item => item.title.toLowerCase().includes(this.term.toLocaleLowerCase()));
}
return bestMatch < 0 ? null : bestMatch;
}
dataServiceSubscribe() {
if (this._dataService) {
this._dataService.pipe(catchError(err => {
console.error(err);
console.error('Unexpected error in dataService: errors should be handled by the dataService Observable');
return [];
}))
.subscribe(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() === this.term.toLocaleLowerCase()) {
// Do automatch
this.completer.onSelected(results[0]);
return;
}
if (this._initialValue) {
this.initialValue = this._initialValue;
this._initialValue = null;
}
this.refreshTemplate();
if (this.ctrListAutoHighlight) {
this.completer.autoHighlightIndex = this.getBestMatchIndex();
}
});
if (this._dataService.dataSourceChange) {
this._dataService.dataSourceChange.subscribe(() => {
this.term = null;
this.ctx.searchInitialized = false;
this.ctx.searching = false;
this.ctx.results = [];
this.refreshTemplate();
this.completer.onDataSourceChange();
});
}
}
}
}
CtrList.ɵfac = function CtrList_Factory(t) { return new (t || CtrList)(ɵɵdirectiveInject(CtrCompleter, 1), ɵɵdirectiveInject(TemplateRef), ɵɵdirectiveInject(ViewContainerRef), ɵɵdirectiveInject(ChangeDetectorRef)); };
CtrList.ɵdir = ɵɵdefineDirective({ type: CtrList, selectors: [["", "ctrList", ""]], inputs: { ctrListMinSearchLength: "ctrListMinSearchLength", ctrListPause: "ctrListPause", ctrListAutoMatch: "ctrListAutoMatch", ctrListAutoHighlight: "ctrListAutoHighlight", ctrListDisplaySearching: "ctrListDisplaySearching", dataService: ["ctrList", "dataService"], initialValue: ["ctrListInitialValue", "initialValue"] } });
/*@__PURE__*/ (function () { ɵsetClassMetadata(CtrList, [{
type: Directive,
args: [{
// tslint:disable-next-line:directive-selector
selector: '[ctrList]',
}]
}], function () { return [{ type: CtrCompleter, decorators: [{
type: Host
}] }, { type: TemplateRef }, { type: ViewContainerRef }, { type: ChangeDetectorRef }]; }, { 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']
}] }); })();
class CtrRow {
constructor(el, renderer, dropdown) {
this.el = el;
this.renderer = renderer;
this.dropdown = dropdown;
this.selected = false;
}
ngOnDestroy() {
if (this._rowIndex) {
this.dropdown.unregisterRow(this._rowIndex);
}
}
set ctrRow(index) {
this._rowIndex = index;
this.dropdown.registerRow(new CtrRowItem(this, this._rowIndex));
}
set dataItem(item) {
this._item = item;
}
onClick(event) {
this.dropdown.onSelected(this._item);
}
onMouseEnter(event) {
this.dropdown.highlightRow(this._rowIndex);
}
onMouseDown(event) {
this.dropdown.rowMouseDown();
}
setHighlighted(selected) {
this.selected = selected;
const highlightClass = 'completer-selected-row';
this.selected ? this.renderer.addClass(this.el.nativeElement, highlightClass) : this.renderer.removeClass(this.el.nativeElement, highlightClass);
}
getNativeElement() {
return this.el.nativeElement;
}
getDataItem() {
return this._item;
}
}
CtrRow.ɵfac = function CtrRow_Factory(t) { return new (t || CtrRow)(ɵɵdirectiveInject(ElementRef), ɵɵdirectiveInject(Renderer2), ɵɵdirectiveInject(CtrDropdown, 1)); };
CtrRow.ɵdir = ɵɵdefineDirective({ type: CtrRow, selectors: [["", "ctrRow", ""]], hostBindings: function CtrRow_HostBindings(rf, ctx) { if (rf & 1) {
ɵɵlistener("click", function CtrRow_click_HostBindingHandler($event) { return ctx.onClick($event); })("mouseenter", function CtrRow_mouseenter_HostBindingHandler($event) { return ctx.onMouseEnter($event); })("mousedown", function CtrRow_mousedown_HostBindingHandler($event) { return ctx.onMouseDown($event); });
} }, inputs: { ctrRow: "ctrRow", dataItem: "dataItem" } });
/*@__PURE__*/ (function () { ɵsetClassMetadata(CtrRow, [{
type: Directive,
args: [{
selector: '[ctrRow]',
}]
}], function () { return [{ type: ElementRef }, { type: Renderer2 }, { type: CtrDropdown, decorators: [{
type: Host
}] }]; }, { ctrRow: [{
type: Input
}], dataItem: [{
type: Input
}], onClick: [{
type: HostListener,
args: ['click', ['$event']]
}], onMouseEnter: [{
type: HostListener,
args: ['mouseenter', ['$event']]
}], onMouseDown: [{
type: HostListener,
args: ['mousedown', ['$event']]
}] }); })();
class CompleterBaseData extends Subject {
constructor() {
super();
}
cancel() {
return;
}
searchFields(searchFields) {
this._searchFields = searchFields;
return this;
}
titleField(titleField) {
this._titleField = titleField;
return this;
}
descriptionField(descriptionField) {
this._descriptionField = descriptionField;
return this;
}
imageField(imageField) {
this._imageField = imageField;
return this;
}
convertToItem(data) {
let image = null;
let formattedText;
let 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 {
description: formattedDesc,
image,
originalObject: data,
title: formattedText
};
}
extractMatches(data, term) {
let matches = [];
const searchFields = this._searchFields ? this._searchFields.split(',') : null;
if (this._searchFields !== null && this._searchFields !== undefined && term !== '') {
matches = data.filter((item) => {
const values = searchFields ? this.extractBySearchFields(searchFields, item) : [item];
return values.some((value) => value
.toString()
.toLowerCase()
.indexOf(term.toString().toLowerCase()) >= 0);
});
}
else {
matches = data;
}
return matches;
}
extractTitle(item) {
// split title fields and run extractValue for each and join with ' '
if (!this._titleField) {
return '';
}
return this._titleField.split(',')
.map((field) => {
return this.extractValue(item, field);
})
.reduce((acc, titlePart) => acc ? `${acc} ${titlePart}` : titlePart);
}
extractValue(obj, key) {
let keys;
let result;
if (key) {
keys = key.split('.');
result = obj;
for (key of keys) {
if (result) {
result = result[key];
}
}
}
else {
result = obj;
}
return result;
}
processResults(matches) {
let i;
const results = [];
if (matches && matches.length > 0) {
for (i = 0; i < matches.length; i++) {
const item = this.convertToItem(matches[i]);
if (item) {
results.push(item);
}
}
}
return results;
}
extractBySearchFields(searchFields, item) {
return searchFields
.map((searchField) => this.extractValue(item, searchField)).filter((value) => !!value);
}
}
class LocalData extends CompleterBaseData {
constructor() {
super();
this.dataSourceChange = new EventEmitter();
}
data(data) {
if (data instanceof Observable) {
const data$ = data;
data$
.pipe(catchError(() => []))
.subscribe((res) => {
this._data = res;
if (this.savedTerm) {
this.search(this.savedTerm);
}
this.dataSourceChange.emit();
});
}
else {
this._data = data;
}
this.dataSourceChange.emit();
return this;
}
search(term) {
if (!this._data) {
this.savedTerm = term;
}
else {
this.savedTerm = null;
const matches = this.extractMatches(this._data, term);
this.next(this.processResults(matches));
}
}
convertToItem(data) {
return super.convertToItem(data);
}
}
class LocalDataFactory {
constructor() { }
create() {
return new LocalData();
}
}
LocalDataFactory.ɵfac = function LocalDataFactory_Factory(t) { return new (t || LocalDataFactory)(); };
LocalDataFactory.ɵprov = ɵɵdefineInjectable({ token: LocalDataFactory, factory: LocalDataFactory.ɵfac });
/*@__PURE__*/ (function () { ɵsetClassMetadata(LocalDataFactory, [{
type: Injectable
}], function () { return []; }, null); })();
class RemoteData extends CompleterBaseData {
constructor(http) {
super();
this.http = http;
this.dataSourceChange = new EventEmitter();
this._urlFormater = null;
this._dataField = null;
}
remoteUrl(remoteUrl) {
this._remoteUrl = remoteUrl;
this.dataSourceChange.emit();
return this;
}
urlFormater(urlFormater) {
this._urlFormater = urlFormater;
}
dataField(dataField) {
this._dataField = dataField;
}
requestOptions(requestOptions) {
this._requestOptions = requestOptions;
}
search(term) {
this.cancel();
// let params = {};
let 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((data) => {
const matches = this.extractValue(data, this._dataField);
return this.extractMatches(matches, term);
}), catchError(() => []))
.subscribe((matches) => {
const results = this.processResults(matches);
this.next(results);
});
}
cancel() {
if (this.remoteSearch) {
this.remoteSearch.unsubscribe();
}
}
convertToItem(data) {
return super.convertToItem(data);
}
}
class RemoteDataFactory {
constructor(http) {
this.http = http;
}
create() {
return new RemoteData(this.http);
}
}
RemoteDataFactory.ɵfac = function RemoteDataFactory_Factory(t) { return new (t || RemoteDataFactory)(ɵɵinject(HttpClient)); };
RemoteDataFactory.ɵprov = ɵɵdefineInjectable({ token: RemoteDataFactory, factory: RemoteDataFactory.ɵfac });
/*@__PURE__*/ (function () { ɵsetClassMetadata(RemoteDataFactory, [{
type: Injectable
}], function () { return [{ type: HttpClient }]; }, null); })();
class CompleterService {
constructor(localDataFactory, // Using any instead of () => LocalData because of AoT errors
remoteDataFactory // Using any instead of () => LocalData because of AoT errors
) {
this.localDataFactory = localDataFactory;
this.remoteDataFactory = remoteDataFactory;
}
local(data, searchFields = '', titleField = '') {
const localData = this.localDataFactory.create();
return localData
.data(data)
.searchFields(searchFields)
.titleField(titleField);
}
remote(url, searchFields = '', titleField = '') {
const remoteData = this.remoteDataFactory.create();
return remoteData
.remoteUrl(url)
.searchFields(searchFields)
.titleField(titleField);
}
}
CompleterService.ɵfac = function CompleterService_Factory(t) { return new (t || CompleterService)(ɵɵinject(LocalDataFactory), ɵɵinject(RemoteDataFactory)); };
CompleterService.ɵprov = ɵɵdefineInjectable({ token: CompleterService, factory: CompleterService.ɵfac });
/*@__PURE__*/ (function () { ɵsetClassMetadata(CompleterService, [{
type: Injectable
}], function () { return [{ type: LocalDataFactory }, { type: RemoteDataFactory }]; }, null); })();
const _c0$1 = ["ctrInput"];
function CompleterCmp_mat_label_1_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "mat-label");
ɵɵtext(1);
ɵɵelementEnd();
} if (rf & 2) {
const ctx_r0 = ɵɵnextContext();
ɵɵadvance(1);
ɵɵtextInterpolate(ctx_r0.placeholder);
} }
function CompleterCmp_div_7_div_1_div_1_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "div", 15);
ɵɵtext(1);
ɵɵelementEnd();
} if (rf & 2) {
const ctx_r10 = ɵɵnextContext(3);
ɵɵadvance(1);
ɵɵtextInterpolate(ctx_r10._textSearching);
} }
function CompleterCmp_div_7_div_1_div_2_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "div", 16);
ɵɵtext(1);
ɵɵelementEnd();
} if (rf & 2) {
const ctx_r11 = ɵɵnextContext(3);
ɵɵadvance(1);
ɵɵtextInterpolate(ctx_r11._textNoResults);
} }
function CompleterCmp_div_7_div_1_div_3_div_2_img_1_Template(rf, ctx) { if (rf & 1) {
ɵɵelement(0, "img", 26);
} if (rf & 2) {
const item_r13 = ɵɵnextContext(2).$implicit;
ɵɵpropertyInterpolate("src", item_r13.image, ɵɵsanitizeUrl);
} }
function CompleterCmp_div_7_div_1_div_3_div_2_div_2_Template(rf, ctx) { if (rf & 1) {
ɵɵelement(0, "div", 27);
} }
function CompleterCmp_div_7_div_1_div_3_div_2_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "div", 23);
ɵɵtemplate(1, CompleterCmp_div_7_div_1_div_3_div_2_img_1_Template, 1, 1, "img", 24);
ɵɵtemplate(2, CompleterCmp_div_7_div_1_div_3_div_2_div_2_Template, 1, 0, "div", 25);
ɵɵelementEnd();
} if (rf & 2) {
const item_r13 = ɵɵnextContext().$implicit;
ɵɵadvance(1);
ɵɵproperty("ngIf", item_r13.image != "");
ɵɵadvance(1);
ɵɵproperty("ngIf", item_r13.image === "");
} }
function CompleterCmp_div_7_div_1_div_3_completer_list_item_5_Template(rf, ctx) { if (rf & 1) {
ɵɵelement(0, "completer-list-item", 28);
} if (rf & 2) {
const item_r13 = ɵɵnextContext().$implicit;
const ctx_r16 = ɵɵnextContext(3);
ɵɵproperty("text", item_r13.description)("matchClass", ctx_r16.matchClass)("searchStr", ctx_r16.searchStr)("type", "description");
} }
const _c1 = function (a0) { return { "completer-item-text-image": a0 }; };
function CompleterCmp_div_7_div_1_div_3_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "div", 17);
ɵɵelementStart(1, "div", 18);
ɵɵtemplate(2, CompleterCmp_div_7_div_1_div_3_div_2_Template, 3, 2, "div", 19);
ɵɵelementStart(3, "div", 20);
ɵɵelement(4, "completer-list-item", 21);
ɵɵtemplate(5, CompleterCmp_div_7_div_1_div_3_completer_list_item_5_Template, 1, 4, "completer-list-item", 22);
ɵɵelementEnd();
ɵɵelementEnd();
ɵɵelementEnd();
} if (rf & 2) {
const item_r13 = ctx.$implicit;
const rowIndex_r14 = ctx.index;
const ctx_r12 = ɵɵnextContext(3);
ɵɵadvance(1);
ɵɵproperty("ctrRow", rowIndex_r14)("dataItem", item_r13);
ɵɵadvance(1);
ɵɵproperty("ngIf", item_r13.image || item_r13.image === "");
ɵɵadvance(1);
ɵɵproperty("ngClass", ɵɵpureFunction1(9, _c1, item_r13.image || item_r13.image === ""));
ɵɵadvance(1);
ɵɵproperty("text", item_r13.title)("matchClass", ctx_r12.matchClass)("searchStr", ctx_r12.searchStr)("type", "title");
ɵɵadvance(1);
ɵɵproperty("ngIf", item_r13.description && item_r13.description != "");
} }
function CompleterCmp_div_7_div_1_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "div", 11);
ɵɵtemplate(1, CompleterCmp_div_7_div_1_div_1_Template, 2, 1, "div", 12);
ɵɵtemplate(2, CompleterCmp_div_7_div_1_div_2_Template, 2, 1, "div", 13);
ɵɵtemplate(3, CompleterCmp_div_7_div_1_div_3_Template, 6, 11, "div", 14);
ɵɵelementEnd();
} if (rf & 2) {
const ctx_r22 = ɵɵnextContext();
const searchActive_r6 = ctx_r22.searching;
const items_r5 = ctx_r22.results;
const ctx_r9 = ɵɵnextContext();
ɵɵadvance(1);
ɵɵproperty("ngIf", searchActive_r6 && ctx_r9.displaySearching);
ɵɵadvance(1);
ɵɵproperty("ngIf", !searchActive_r6 && (!items_r5 || (items_r5 == null ? null : items_r5.length) === 0));
ɵɵadvance(1);
ɵɵproperty("ngForOf", items_r5);
} }
function CompleterCmp_div_7_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "div", 9);
ɵɵtemplate(1, CompleterCmp_div_7_div_1_Template, 4, 3, "div", 10);
ɵɵelementEnd();
} if (rf & 2) {
const items_r5 = ctx.results;
const searchActive_r6 = ctx.searching;
const isInitialized_r7 = ctx.searchInitialized;
const isOpen_r8 = ctx.isOpen;
const ctx_r3 = ɵɵnextContext();
ɵɵadvance(1);
ɵɵproperty("ngIf", isInitialized_r7 && isOpen_r8 && ((items_r5 == null ? null : items_r5.length) > 0 || ctx_r3.displayNoResults && !searchActive_r6 || searchActive_r6 && ctx_r3.displaySearching));
} }
function CompleterCmp_div_8_Template(rf, ctx) { if (rf & 1) {
const _r24 = ɵɵgetCurrentView();
ɵɵelementStart(0, "div", 29);
ɵɵelementStart(1, "mat-chip-list", 30);
ɵɵelementStart(2, "mat-chip", 31);
ɵɵlistener("removed", function CompleterCmp_div_8_Template_mat_chip_removed_2_listener() { ɵɵrestoreView(_r24); const ctx_r23 = ɵɵnextContext(); return ctx_r23.removeItem(); });
ɵɵelementStart(3, "span", 32);
ɵɵtext(4);
ɵɵelementEnd();
ɵɵelementStart(5, "mat-icon", 33);
ɵɵtext(6, "cancel");
ɵɵelementEnd();
ɵɵelementEnd();
ɵɵelementEnd();
ɵɵelementEnd();
} if (rf & 2) {
const ctx_r4 = ɵɵnextContext();
const _r2 = ɵɵreference(6);
ɵɵadvance(1);
ɵɵproperty("disabled", _r2.disabled);
ɵɵadvance(1);
ɵɵproperty("selectable", true)("removable", true);
ɵɵadvance(2);
ɵɵtextInterpolate(ctx_r4.completerItem == null ? null : ctx_r4.completerItem.title);
} }
'use strict';
const noop = () => { };
const COMPLETER_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CompleterCmp),
multi: true
};
// tslint:disable-next-line:component-class-suffix
class CompleterCmp {
constructor(completerService, cdr) {
this.completerService = completerService;
this.cdr = cdr;
this.inputName = '';
this.inputId = '';
this.pause = PAUSE;
this.minSearchLength = MIN_SEARCH_LENGTH;
this.maxChars = MAX_CHARS;
this.overrideSuggested = false;
this.clearSelected = false;
this.clearUnselected = false;
this.fillHighlighted = true;
this.placeholder = '';
this.autoMatch = false;
this.disableInput = false;
this.autofocus = false;
this.openOnFocus = false;
this.openOnClick = false;
this.selectOnClick = false;
this.autoHighlight = false;
this.autoSelectOnEnter = true;
this.appearance = '';
this.selected = new EventEmitter();
this.highlighted = new EventEmitter();
// tslint:disable:no-output-rename
this.blurEvent = new EventEmitter();
this.click = new EventEmitter();
this.focusEvent = new EventEmitter();
this.opened = new EventEmitter();
this.keyup = new EventEmitter();
this.keydown = new EventEmitter();
this.searchStr = '';
this.control = new FormControl('');
this.displaySearching = true;
this.displayNoResults = true;
this._textNoResults = TEXT_NO_RESULTS;
this._textSearching = TEXT_SEARCHING;
this._onTouchedCallback = noop;
this._onChangeCallback = noop;
this._focus = false;
this._open = false;
this._onlyOnInit = true;
}
get value() { return (this.completerItem) ? this.completerItem.originalObject : this.searchStr; }
set value(v) {
if (typeof (v) === 'string') {
this.searchStr = v;
}
else {
this.completerItem = v;
}
}
ngAfterViewInit() {
if (this.autofocus) {
this._focus = true;
}
}
ngAfterViewChecked() {
if (this._focus) {
setTimeout(() => {
if (this.ctrInput) {
this.ctrInput.nativeElement.focus();
this._focus = false;
}
}, 0);
}
}
onTouched() {
this._onTouchedCallback();
}
writeValue(value) {
if (value && (value.id === 0 || value.id === 0))
value = null;
if (value && this.dataService.convertToItem) {
this.completerItem = this.dataService.convertToItem(value);
this.searchStr = this.completerItem.title;
}
else {
this.completerItem = null;
this.searchStr = null;
}
}
registerOnChange(fn) {
this._onChangeCallback = fn;
}
registerOnTouched(fn) {
this._onTouchedCallback = fn;
}
setDisabledState(isDisabled) {
this.disableInput = isDisabled;
if (!this.form) {
if (isDisabled) {
this.control.disable({ onlySelf: false, emitEvent: true });
}
else {
this.control.enable({ onlySelf: false, emitEvent: true });
}
}
}
set datasource(source) {
if (source) {
if (source instanceof Array) {
this.dataService = this.completerService.local(source);
}
else if (typeof (source) === 'string') {
this.dataService = this.completerService.remote(source);
}
else {
this.dataService = source;
}
}
}
set textNoResults(text) {
if (this._textNoResults !== text) {
this._textNoResults = text;
this.displayNoResults = !!this._textNoResults && this._textNoResults !== 'false';
}
}
set textSearching(text) {
if (this._textSearching !== text) {
this._textSearching = text;
this.displaySearching = !!this._textSearching && this._textSearching !== 'false';
}
}
ngOnInit() {
if (this.required === '')
this.required = true;
if (this.required) {
this.control.setValidators(Validators.required);
}
if (this.form) {
this.form.control.addControl(this.name, this.control);
this.form.control.get(this.name).updateValueAndValidity();
}
this.completer.selected.subscribe((item) => {
this.completerItem = item;
if (!this.completerItem)
this.searchStr = undefined;
this._onChangeCallback((this.completerItem) ? this.completerItem.originalObject : null);
this.selected.emit(item);
});
this.completer.highlighted.subscribe((item) => {
this.highlighted.emit(item);
});
this.completer.opened.subscribe((isOpen) => {
this._open = isOpen;
this.opened.emit(isOpen);
});
}
removeItem() {
this.completerItem = undefined;
this.searchStr = undefined;
this._onChangeCallback((this.completerItem) ? this.completerItem.originalObject : null);
this.selected.emit(null);
setTimeout(() => {
if (this.ctrInput) {
this.ctrInput.nativeElement.focus();
this._focus = false;
}
}, 10);
}
onBlur() {
this.blurEvent.emit();
this.onTouched();
this.cdr.detectChanges();
}
onFocus() {
this.focusEvent.emit();
//this.onTouched();
}
onClick(event) {
this.click.emit(event);
this.onTouched();
}
onKeyup(event) {
this.keyup.emit(event);
}
onKeydown(event) {
this._onlyOnInit = false;
this.keydown.emit(event);
}
onChange(value) {
this.value = value;
}
open() {
this.completer.open();
}
close() {
this.completer.clear();
}
focus() {
if (this.ctrInput) {
this.ctrInput.nativeElement.focus();
}
else {
this._focus = true;
}
}
blur() {
if (this.ctrInput) {
this.ctrInput.nativeElement.blur();
}
else {
this._focus = false;
}
}
isOpen() {
return this._open;
}
}
CompleterCmp.ɵfac = function CompleterCmp_Factory(t) { return new (t || CompleterCmp)(ɵɵdirectiveInject(CompleterService), ɵɵdirectiveInject(ChangeDetectorRef)); };
CompleterCmp.ɵcmp = ɵɵdefineComponent({ type: CompleterCmp, selectors: [["neo-completer-mat"]], viewQuery: function CompleterCmp_Query(rf, ctx) { if (rf & 1) {
ɵɵstaticViewQuery(CtrCompleter, true);
ɵɵstaticViewQuery(_c0$1, true);
} if (rf & 2) {
var _t;
ɵɵqueryRefresh(_t = ɵɵloadQuery()) && (ctx.completer = _t.first);
ɵɵqueryRefresh(_t = ɵɵloadQuery()) && (ctx.ctrInput = _t.first);
} }, inputs: { dataService: "dataService", required: "required", name: "name", inputName: "inputName", inputId: "inputId", pause: "pause", minSearchLength: "minSearchLength", maxChars: "maxChars", overrideSuggested: "overrideSuggested", clearSelected: "clearSelected", clearUnselected: "clearUnselected", fillHighlighted: "fillHighlighted", placeholder: "placeholder", matchClass: "matchClass", fieldTabindex: "fieldTabindex", autoMatch: "autoMatch", disableInput: "disableInput", inputClass: "inputClass", formFieldClass: "formFieldClass", autofocus: "autofocus", openOnFocus: "openOnFocus", openOnClick: "openOnClick", selectOnClick: "selectOnClick", initialValue: "initialValue", autoHighlight: "autoHighlight", autoSelectOnEnter: "autoSelectOnEnter", appearance: "appearance", form: "form", datasource: "datasource", textNoResults: "textNoResults", textSearching: "textSearching" }, outputs: { selected: "selected", highlighted: "highlighted", blurEvent: "blur", click: "click", focusEvent: "focus", opened: "opened", keyup: "keyup", keydown: "keydown" }, features: [ɵɵProvidersFeature([COMPLETER_CONTROL_VALUE_ACCESSOR])], decls: 9, vars: 33, consts: [[3, "ngClass", "appearance"], [4, "ngIf"], ["ctrCompleter", "", 1, "completer-holder"], ["matInput", "", "type", "search", "ctrInput", "", "autocomplete", "off", "autocorrect", "off", "autocapitalize", "off", 1, "completer-input", 3, "required", "ngClass", "ngModel", "placeholder", "tabindex", "disabled", "clearSelected", "clearUnselected", "overrideSuggested", "openOnFocus", "fillHighlighted", "openOnClick", "selectOnClick", "autoSelectOnEnter", "ngModelChange", "blur", "focus", "keyup", "keydown", "click"], ["ctrInput", ""], ["matInput", "", 3, "formControl"], ["ctrInputHidden", ""], ["class", "completer-dropdown-holder", 4, "ctrList", "ctrListMinSearchLength", "ctrListPause", "ctrListAutoMatch", "ctrListInitialValue", "ctrListAutoHighlight", "ctrListDisplaySearching"], ["class", "completer-holder", 4, "ngIf"], [1, "completer-dropdown-holder"], ["class", "completer-dropdown", "ctrDropdown", "", 4, "ngIf"], ["ctrDropdown", "", 1, "completer-dropdown"], ["class", "completer-searching", 4, "ngIf"], ["class", "completer-no-results", 4, "ngIf"], ["class", "completer-row-wrapper", 4, "ngFor", "ngForOf"], [1, "completer-searching"], [1, "completer-no-results"], [1, "completer-row-wrapper"], [1, "completer-row", 3, "ctrRow", "dataItem"], ["class", "completer-image-holder", 4, "ngIf"], [1, "completer-item-text", 3, "ngClass"], [1, "completer-title", 3, "text", "matchClass", "searchStr", "type"], ["class", "completer-description", 3, "text", "matchClass", "searchStr", "type", 4, "ngIf"], [1, "completer-image-holder"], ["class", "completer-image", 3, "src", 4, "ngIf"], ["class", "completer-image-default", 4, "ngIf"], [1, "completer-image", 3, "src"], [1, "completer-image-default"], [1, "completer-description", 3, "text", "matchClass", "searchStr", "type"], [1, "completer-holder"], [3, "disabled"], ["id", "chip-badge", 3, "selectable", "removable", "removed"], [1, ""], ["matChipRemove", ""]], template: function CompleterCmp_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "mat-form-field", 0);
ɵɵtemplate(1, CompleterCmp_mat_label_1_Template, 2, 1, "mat-label", 1);
ɵɵelementStart(2, "div", 2);
ɵɵelementStart(3, "input", 3, 4);
ɵɵlistener("ngModelChange", function CompleterCmp_Template_input_ngModelChange_3_listener($event) { return ctx.searchStr = $event; })("ngModelChange", function CompleterCmp_Template_input_ngModelChange_3_listener($event) { return ctx.onChange($event); })("blur", function CompleterCmp_Template_input_blur_3_listener() { return ctx.onBlur(); })("focus", function CompleterCmp_Template_input_focus_3_listener() { return ctx.onFocus(); })("keyup", function CompleterCmp_Template_input_keyup_3_listener($event) { return ctx.onKeyup($event); })("keydown", function CompleterCmp_Template_input_keydown_3_listener($event) { return ctx.onKeydown($event); })("click", function CompleterCmp_Template_input_click_3_listener($event) { return ctx.onClick($event); });
ɵɵelementEnd();
ɵɵelement(5, "input", 5, 6);
ɵɵtemplate(7, CompleterCmp_div_7_Template, 2, 1, "div", 7);
ɵɵelementEnd();
ɵɵtemplate(8, CompleterCmp_div_8_Template, 7, 4, "div", 8);
ɵɵelementEnd();
} if (rf & 2) {
const _r2 = ɵɵreference(6);
ɵɵproperty("ngClass", ctx.formFieldClass)("appearance", ctx.appearance);
ɵɵadvance(1);
ɵɵproperty("ngIf", ctx.appearance);
ɵɵadvance(2);
ɵɵclassProp("none-display", ctx.completerItem);
ɵɵproperty("required", ctx.required)("ngClass", ctx.inputClass)("ngModel", ctx.searchStr)("placeholder", ctx.placeholder)("tabindex", ctx.fieldTabindex)("disabled", _r2.disabled)("clearSelected", ctx.clearSelected)("clearUnselected", ctx.clearUnselected)("overrideSuggested", ctx.overrideSuggested)("openOnFocus", ctx.openOnFocus)("fillHighlighted", ctx.fillHighlighted)("openOnClick", ctx.openOnClick)("selectOnClick", ctx.selectOnClick)("autoSelectOnEnter", ctx.autoSelectOnEnter);
ɵɵattribute("id", ctx.inputId.length > 0 ? ctx.inputId : null)("name", ctx.inputName)("maxlength", ctx.maxChars);
ɵɵadvance(2);
ɵɵclassProp("none-display", true);
ɵɵproperty("formControl", ctx.control);
ɵɵadvance(2);
ɵɵproperty("ctrList", ctx.dataService)("ctrListMinSearchLength", ctx.minSearchLength)("ctrListPause", ctx.pause)("ctrListAutoMatch", ctx.autoMatch)("ctrListInitialValue", ctx.initialValue)("ctrListAutoHighlight", ctx.autoHighlight)("ctrListDisplaySearching", ctx.displaySearching);
ɵɵadvance(1);
ɵɵproperty("ngIf", ctx.completerItem);
} }, directives: [MatFormField, NgClass, NgIf, CtrCompleter, MatInput, DefaultValueAccessor, CtrInput, RequiredValidator, NgControlStatus, NgModel, MaxLengthValidator, FormControlDirective, CtrList, MatLabel, CtrDropdown, NgForOf, CtrRow, CompleterListItemCmp, MatChipList, MatChip, MatIcon, MatChipRemove], styles: [".completer-dropdown[_ngcontent-%COMP%]{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);width:100%;border-bottom-left-radius:4px;border-bottom-right-radius:4px;margin-top:10px;cursor:pointer;z-index:9999;position:absolute;background-color:#fff;max-height:200px;height:200px;overflow-y:auto;overflow-x:hidden}.completer-row[_ngcontent-%COMP%]:hover{background:rgba(0,0,0,.04)}.completer-row[_ngcontent-%COMP%]{line-height:48px;height:48px;color:#000;width:100%;text-overflow:ellipsis;text-align:left;padding:0 16px}.completer-row-wrapper[_ngcontent-%COMP%]{text-overflow:ellipsis}.completer-selected-row[_ngcontent-%COMP%]{background:rgba(0,0,0,.04)}.completer-description[_ngcontent-%COMP%]{font-size:14px}.completer-image-default[_ngcontent-%COMP%]{width:16px;height:16px}.completer-image-holder[_ngcontent-%COMP%]{float:left;width:10%}.completer-item-text-image[_ngcontent-%COMP%]{float:right;width:90%}.none-display[_ngcontent-%COMP%]{display:none}.mat-standard-chip[_ngcontent-%COMP%] .mat-chip-remove.mat-icon[_ngcontent-%COMP%]{width:16px!important;height:16px!important}.mat-chip[_ngcontent-%COMP%] .mat-chip-remove.mat-icon[_ngcontent-%COMP%], .mat-chip[_ngcontent-%COMP%] .mat-chip-trailing-icon.mat-icon[_ngcontent-%COMP%]{font-size:16px!important}.mat-standard-chip[_ngcontent-%COMP%]{min-height:24px!important;font-size:14px!important}mat-chip-list[_ngcontent-%COMP%] .mat-chip-list-wrapper[_ngcontent-%COMP%]{margin:-7px!important}#chip-badge[_ngcontent-%COMP%]{margin:1px!important}"] });
/*@__PURE__*/ (function () { ɵsetClassMetadata(CompleterCmp, [{
type: Component,
args: [{
// tslint:disable:max-line-length
selector: 'neo-completer-mat',
template: `
<mat-form-field [ngClass]="formFieldClass" [appearance]="appearance">
<mat-label *ngIf="appearance">{{placeholder}}</mat-label>
<div class="completer-holder" ctrCompleter>
<input #ctrInput [class.none-display]="completerItem" [required]="required" matInput [attr.id]="inputId.length > 0 ? inputId : null" type="search" class="completer-input" ctrInput [ngClass]="inputClass"
[(ngModel)]="searchStr" (ngModelChange)="onChange($event)" [attr.name]="inputName" [placeholder]="placeholder"
[attr.maxlength]="maxChars" [tabindex]="fieldTabindex" [disabled]="ctrInputHidden.disabled"
[clearSelected]="clearSelected" [clearUnselected]="clearUnselected"
[overrideSuggested]="overrideSuggested" [openOnFocus]="openOnFocus" [fillHighlighted]="fillHighlighted"
[openOnClick]="openOnClick" [selectOnClick]="selectOnClick" [autoSelectOnEnter]="autoSelectOnEnter"
(blur)="onBlur()" (focus)="onFocus()" (keyup)="onKeyup($event)" (keydown)="onKeydown($event)" (click)="onClick($event)"
autocomplete="off" autocorrect="off" autocapitalize="off" />
<input #ctrInputHidden [class.none-display]="true" matInput [formControl]="control"/>
<div class="completer-dropdown-holder"
*ctrList="dataService;
minSearchLength: minSearchLength;
pause: pause;
autoMatch: autoMatch;
initialValue: initialValue;
autoHighlight: autoHighlight;
displaySearching: displaySearching;
let items = results;
let searchActive = searching;
let isInitialized = searchInitialized;
let isOpen = isOpen;">
<div class="completer-dropdown" ctrDropdown *ngIf="isInitialized && isOpen && (( items?.length > 0|| (displayNoResults && !searchActive)) || (searchActive && displaySearching))">
<div *ngIf="searchActive && displaySearching" class="completer-searching">{{_textSearching}}</div>
<div *ngIf="!searchActive && (!items || items?.length === 0)" class="completer-no-results">{{_textNoResults}}</div>
<div class="completer-row-wrapper" *ngFor="let item of items; let rowIndex=index">
<div class="completer-row" [ctrRow]="rowIndex" [dataItem]="item">
<div *ngIf="item.image || item.image === ''" class="completer-image-holder">
<img *ngIf="item.image != ''" src="{{item.image}}" class="completer-image" />
<div *ngIf="item.image === ''" class="completer-image-default"></div>
</div>
<div class="completer-item-text" [ngClass]="{'completer-item-text-image': item.image || item.image === '' }">
<completer-list-item class="completer-title" [text]="item.title" [matchClass]="matchClass" [searchStr]="searchStr" [type]="'title'"></completer-list-item>
<completer-list-item *ngIf="item.description && item.description != ''" class="completer-description" [text]="item.description"
[matchClass]="matchClass" [searchStr]="searchStr" [type]="'description'">
</completer-list-item>
</div>
</div>
</div>
</div>
</div>
</div>
<div *ngIf="completerItem" class="completer-holder">
<mat-chip-list [disabled]="ctrInputHidden.disabled">
<mat-chip id="chip-badge" [selectable]="true" [removable]="true" (removed)="removeItem()">
<span class="">{{completerItem?.title}}</span>
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
</mat-chip-list>
</div>
</mat-form-field>
`,
styleUrls: ['completer-cmp.scss'],
providers: [COMPLETER_CONTROL_VALUE_ACCESSOR]
}]
}], function () { return [{ type: CompleterService }, { type: ChangeDetectorRef }]; }, { dataService: [{
type: Input
}], required: [{
type: Input
}], name: [{
type: Input
}], inputName: [{
type: Input
}], inputId: [{
type: Input
}], pause: [{
type: Input
}], minSearchLength: [{
type: Input
}], maxChars: [{
type: Input
}], overrideSuggested: [{
type: Input
}], clearSelected: [{
type: Input
}], clearUnselected: [{
type: Input
}], fillHighlighted: [{
type: Input
}], placeholder: [{
type: Input
}], matchClass: [{
type: Input
}], fieldTabindex: [{
type: Input
}], autoMatch: [{
type: Input
}], disableInput: [{
type: Input
}], inputClass: [{
type: Input
}], formFieldClass: [{
type: Input
}], autofocus: [{
type: Input
}], openOnFocus: [{
type: Input
}], openOnClick: [{
type: Input
}], selectOnClick: [{
type: Input
}], initialValue: [{
type: Input
}], autoHighlight: [{
type: Input
}], autoSelectOnEnter: [{
type: Input
}], appearance: [{
type: Input
}], form: [{
type: Input
}], selected: [{
type: Output
}], highlighted: [{
type: Output
}], blurEvent: [{
type: Output,
args: ['blur']
}], click: [{
type: Output
}], focusEvent: [{
type: Output,
args: ['focus']
}], opened: [{
type: Output
}], keyup: [{
type: Output
}], keydown: [{
type: Output
}], completer: [{
type: ViewChild,
args: [CtrCompleter, { static: true }]
}], ctrInput: [{
type: ViewChild,
args: ['ctrInput', { static: true }]
}], datasource: [{
type: Input
}], textNoResults: [{
type: Input
}], textSearching: [{
type: Input
}] }); })();
class NgxNeoCompleterMatModule {
static forRoot() {
return {
ngModule: NgxNeoCompleterMatModule,
providers: [
CompleterService,
LocalDataFactory,
RemoteDataFactory
]
};
}
}
NgxNeoCompleterMatModule.ɵmod = ɵɵdefineNgModule({ type: NgxNeoCompleterMatModule });
NgxNeoCompleterMatModule.ɵinj = ɵɵdefineInjector({ factory: function NgxNeoCompleterMatModule_Factory(t) { return new (t || NgxNeoCompleterMatModule)(); }, imports: [[
CommonModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
MatInputModule,
MatChipsModule,
MatIconModule
]] });
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && ɵɵsetNgModuleScope(NgxNeoCompleterMatModule, { declarations: [CompleterListItemCmp,
CtrCompleter,
CtrDropdown,
CtrInput,
CtrList,
CtrRow,
CompleterCmp], imports: [CommonModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
MatInputModule,
MatChipsModule,
MatIconModule], exports: [CompleterCmp,
CompleterListItemCmp,
CtrCompleter,
CtrDropdown,
CtrInput,
CtrList,
CtrRow] }); })();
/*@__PURE__*/ (function () { ɵsetClassMetadata(NgxNeoCompleterMatModule, [{
type: NgModule,
args: [{
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
MatInputModule,
MatChipsModule,
MatIconModule
],
declarations: [
CompleterListItemCmp,
CtrCompleter,
CtrDropdown,
CtrInput,
CtrList,
CtrRow,
CompleterCmp
],
exports: [
CompleterCmp,
CompleterListItemCmp,
CtrCompleter,
CtrDropdown,
CtrInput,
CtrList,
CtrRow
]
}]
}], null, null); })();
/**
* Esta clase permite simplificar el uso de los autocompletadores para funcionar con objetos y no con simples string.
*/
class NgxNeoCompleterMatService {
constructor(completerService) {
// variable que realiza el binding con el componente html : [(ngModel)]
this.modelString = '';
// Propiedad sobre la que queremos hacer binding
this.fieldValue = '';
this.completerService = completerService;
}
/**
* Se ejecuta cuando el usuario selecciona un valor del autocompletable
* @author mgesuitti
*/
onSelected(selected) {
if (selected != null) {
this.selectedObject[this.fieldValue] = selected.originalObject;
}
else {
this.selectedObject[this.fieldValue] = this.empty;
}
}
/**
* Se utiliza para asignar los datos locales (cargados previamente desde el servidor)
*
* @author mgesuitti
*/
local(data, selectedObject, fieldValue = '', searchFields, titleField, emptyObject) {
this.selectedObject = selectedObject;
this.fieldValue = fieldValue;
this.dataSource = this.completerService.local(data, searchFields, titleField);
if (fieldValue !== '') {
this.modelString = this.selectedObject[this.fieldValue][searchFields];
}
else {
this.modelString = this.selectedObject[searchFields];
}
this.empty = emptyObject;
return this.dataSource;
}
}
/*
* Public API Surface of ngx-neo-completer
*/
/**
* Generated bundle index. Do not edit.
*/
export { CompleterBaseData, CompleterCmp, CompleterListItemCmp, CompleterService, CtrCompleter, CtrDropdown, CtrInput, CtrList, CtrListContext, CtrRow, CtrRowItem, LocalData, LocalDataFactory, NgxNeoCompleterMatModule, NgxNeoCompleterMatService, RemoteData, RemoteDataFactory };
//# sourceMappingURL=neocomplexx-ngx-neo-completer-mat.js.map