UNPKG

angular-ng-autocomplete

Version:
1 lines 52.4 kB
{"version":3,"file":"angular-ng-autocomplete.mjs","sources":["../../../projects/autocomplete-lib/src/lib/highlight.pipe.ts","../../../projects/autocomplete-lib/src/lib/autocomplete.component.ts","../../../projects/autocomplete-lib/src/lib/autocomplete.component.html","../../../projects/autocomplete-lib/src/lib/autocomplete-lib.module.ts","../../../projects/autocomplete-lib/src/public_api.ts","../../../projects/autocomplete-lib/src/angular-ng-autocomplete.ts"],"sourcesContent":["import {Pipe, PipeTransform} from '@angular/core';\n\n@Pipe({\n name: 'highlight'\n})\nexport class HighlightPipe implements PipeTransform {\n transform(text: any, search: any, searchKeyword?: any): any {\n let pattern = search.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, '\\\\$&');\n pattern = pattern.split(' ').filter((t) => {\n return t.length > 0;\n }).join('|');\n const regex = new RegExp(pattern, 'gi');\n\n if (!search) {\n return text;\n }\n\n if (searchKeyword) {\n const name = text[searchKeyword].replace(regex, (match) => `<b>${match}</b>`);\n // copy original object\n const textCopied = {...text};\n // set bold value into searchKeyword of copied object\n textCopied[searchKeyword] = name;\n return textCopied;\n } else {\n return search ? text.replace(regex, (match) => `<b>${match}</b>`) : text;\n }\n }\n}\n","import {\n AfterViewInit,\n Component, ContentChild,\n ElementRef,\n EventEmitter, forwardRef,\n Input, OnChanges,\n OnInit,\n Output,\n Renderer2,\n SimpleChanges, TemplateRef,\n ViewChild,\n ViewEncapsulation\n} from '@angular/core';\nimport {fromEvent, Observable} from 'rxjs';\nimport {debounceTime, filter, map} from 'rxjs/operators';\nimport {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';\n\n/**\n * Keyboard events\n */\nconst isArrowUp = keyCode => keyCode === 38;\nconst isArrowDown = keyCode => keyCode === 40;\nconst isArrowUpDown = keyCode => isArrowUp(keyCode) || isArrowDown(keyCode);\nconst isEnter = keyCode => keyCode === 13;\nconst isBackspace = keyCode => keyCode === 8;\nconst isDelete = keyCode => keyCode === 46;\nconst isESC = keyCode => keyCode === 27;\nconst isTab = keyCode => keyCode === 9;\n\n\n@Component({\n selector: 'ng-autocomplete',\n templateUrl: './autocomplete.component.html',\n styleUrls: ['./autocomplete.component.scss'],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => AutocompleteComponent),\n multi: true\n }\n ],\n encapsulation: ViewEncapsulation.None,\n host: {\n '(document:click)': 'handleClick($event)',\n 'class': 'ng-autocomplete'\n },\n})\n\nexport class AutocompleteComponent implements OnInit, OnChanges, AfterViewInit, ControlValueAccessor {\n @ViewChild('searchInput') searchInput: ElementRef; // input element\n @ViewChild('filteredListElement') filteredListElement: ElementRef; // element of items\n @ViewChild('historyListElement') historyListElement: ElementRef; // element of history items\n\n inputKeyUp$: Observable<any>;\n inputKeyDown$: Observable<any>;\n\n public query = ''; // search query\n public filteredList = []; // list of items\n public historyList = []; // list of history items\n public isHistoryListVisible = true;\n public elementRef;\n public selectedIdx = -1;\n public toHighlight = '';\n public notFound = false;\n public isFocused = false;\n public isOpen = false;\n public isScrollToEnd = false;\n public overlay = false;\n private manualOpen = undefined;\n private manualClose = undefined;\n\n\n // @Inputs\n /**\n * Data of items list.\n * It can be array of strings or array of objects.\n */\n @Input() public data = [];\n @Input() public searchKeyword: string; // keyword to filter the list\n @Input() public placeholder = '';\n @Input() public heading = '';\n @Input() public initialValue: any;\n /**\n * History identifier of history list\n * When valid history identifier is given, then component stores selected item to local storage of user's browser.\n * If it is null then history is hidden.\n * History list is visible if at least one history item is stored.\n */\n @Input() public historyIdentifier: string;\n /**\n * Heading text of history list.\n * If it is null then history heading is hidden.\n */\n @Input() public historyHeading = 'Recently selected';\n @Input() public historyListMaxNumber = 15; // maximum number of items in the history list.\n @Input() public notFoundText = 'Not found'; // set custom text when filter returns empty result\n @Input() public isLoading: boolean; // loading mask\n @Input() public debounceTime: number; // delay time while typing\n @Input() public disabled: boolean; // input disable/enable\n /**\n * The minimum number of characters the user must type before a search is performed.\n */\n @Input() public minQueryLength = 1;\n\n /**\n * Focus first item in the list\n */\n @Input() public focusFirst = false;\n\n /**\n * Custom filter function\n */\n @Input() public customFilter: (items: any[], query: string) => any[];\n\n /**\n * Custom result render function\n * @param value - selected value to be rendered inside input field\n */\n @Input() public selectedValueRender: (value: any) => string;\n\n // @Output events\n /** Event that is emitted whenever an item from the list is selected. */\n @Output() selected = new EventEmitter<any>();\n\n /** Event that is emitted whenever an input is changed. */\n @Output() inputChanged = new EventEmitter<any>();\n\n /** Event that is emitted whenever an input is focused. */\n @Output() readonly inputFocused: EventEmitter<void> = new EventEmitter<void>();\n\n /** Event that is emitted whenever an input is cleared. */\n @Output() readonly inputCleared: EventEmitter<void> = new EventEmitter<void>();\n\n /** Event that is emitted when the autocomplete panel is opened. */\n @Output() readonly opened: EventEmitter<void> = new EventEmitter<void>();\n\n /** Event that is emitted when the autocomplete panel is closed. */\n @Output() readonly closed: EventEmitter<void> = new EventEmitter<void>();\n\n /** Event that is emitted when scrolled to the end of items. */\n @Output() readonly scrolledToEnd: EventEmitter<void> = new EventEmitter<void>();\n\n\n // Custom templates\n @Input() itemTemplate !: TemplateRef<any>;\n @Input() notFoundTemplate !: TemplateRef<any>;\n @ContentChild(TemplateRef) customTemplate !: TemplateRef<any>;\n\n /**\n * Propagates new value when model changes\n */\n propagateChange: any = () => {\n };\n\n onTouched: any = () => {\n };\n\n /**\n * Writes a new value from the form model into the view,\n * Updates model\n */\n writeValue(value: any = '') {\n this.query = this.selectedValueRender !== undefined ? this.selectedValueRender(value) : this.defaultWriteValue(value);\n }\n\n private defaultWriteValue(value: any) {\n return value && !this.isTypeString(value) ? value[this.searchKeyword] : value;\n }\n\n /**\n * Registers a handler that is called when something in the view has changed\n */\n registerOnChange(fn) {\n this.propagateChange = fn;\n }\n\n /**\n * Registers a handler specifically for when a control receives a touch event\n */\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n /**\n * Event that is called when the value of an input element is changed\n */\n onChange(event) {\n this.propagateChange(event.target.value);\n }\n\n constructor(elementRef: ElementRef, private renderer: Renderer2) {\n this.elementRef = elementRef;\n }\n\n /**\n * Event that is called when the control status changes to or from DISABLED\n */\n setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n\n ngOnInit(): void {\n }\n\n ngAfterViewInit() {\n this.initEventStream();\n this.handleScroll();\n }\n\n /**\n * Set initial value\n * @param value\n */\n public setInitialValue(value: any) {\n if (this.initialValue) {\n this.select(value);\n }\n }\n\n /**\n * Update search results\n */\n ngOnChanges(changes: SimpleChanges): void {\n this.setInitialValue(this.initialValue);\n if (\n changes &&\n changes.data &&\n Array.isArray(changes.data.currentValue)\n ) {\n this.handleItemsChange();\n if (!changes.data.firstChange && this.isFocused) {\n this.handleOpen();\n }\n }\n }\n\n /**\n * Items change\n */\n public handleItemsChange() {\n this.isScrollToEnd = false;\n if (!this.isOpen) {\n return;\n }\n\n this.filteredList = this.data;\n this.notFound = !this.filteredList || this.filteredList.length === 0;\n\n // Filter list when updating data and panel is open\n if (this.isOpen) {\n this.filterList();\n }\n }\n\n /**\n * Filter data\n */\n public filterList() {\n this.selectedIdx = -1;\n this.initSearchHistory();\n if (this.query != null && this.data) {\n this.toHighlight = this.query;\n this.filteredList = this.customFilter !== undefined ? this.customFilter([...this.data], this.query) : this.defaultFilterFunction();\n // If [focusFirst]=\"true\" automatically focus the first match\n if (this.filteredList.length > 0 && this.focusFirst) {\n this.selectedIdx = 0;\n }\n } else {\n this.notFound = false;\n }\n }\n\n /**\n * Default filter function, used unless customFilter is provided\n */\n public defaultFilterFunction(): any[] {\n return this.data.filter((item: any) => {\n if (typeof item === 'string') {\n // string logic, check equality of strings\n return item.toLowerCase().indexOf(this.query.toLowerCase()) > -1;\n } else if (typeof item === 'object' && item instanceof Object) {\n // object logic, check property equality\n return item[this.searchKeyword] ? item[this.searchKeyword].toLowerCase().indexOf(this.query.toLowerCase()) > -1 : \"\";\n }\n });\n }\n\n\n /**\n * Check if item is a string in the list.\n * @param item\n */\n isTypeString(item) {\n return typeof item === 'string';\n }\n\n /**\n * Select item in the list.\n * @param item\n */\n public select(item) {\n this.query = !this.isTypeString(item) ? item[this.searchKeyword] : item;\n this.isOpen = true;\n this.overlay = false;\n this.selected.emit(item);\n this.propagateChange(item);\n\n if (this.initialValue) {\n // check if history already exists in localStorage and then update\n const history = window.localStorage.getItem(`${this.historyIdentifier}`);\n if (history) {\n let existingHistory = JSON.parse(localStorage[`${this.historyIdentifier}`]);\n if (!(existingHistory instanceof Array)) existingHistory = [];\n\n // check if selected item exists in existingHistory\n if (!existingHistory.some((existingItem) => !this.isTypeString(existingItem)\n ? existingItem[this.searchKeyword] == item[this.searchKeyword] : existingItem == item)) {\n existingHistory.unshift(item);\n localStorage.setItem(`${this.historyIdentifier}`, JSON.stringify(existingHistory));\n\n // check if items don't exceed max allowed number\n if (existingHistory.length >= this.historyListMaxNumber) {\n existingHistory.splice(existingHistory.length - 1, 1);\n localStorage.setItem(`${this.historyIdentifier}`, JSON.stringify(existingHistory));\n }\n } else {\n // if selected item exists in existingHistory swap to top in array\n if (!this.isTypeString(item)) {\n // object logic\n const copiedExistingHistory = existingHistory.slice(); // copy original existingHistory array\n const selectedIndex = copiedExistingHistory.map((el) => el[this.searchKeyword]).indexOf(item[this.searchKeyword]);\n copiedExistingHistory.splice(selectedIndex, 1);\n copiedExistingHistory.splice(0, 0, item);\n localStorage.setItem(`${this.historyIdentifier}`, JSON.stringify(copiedExistingHistory));\n } else {\n // string logic\n const copiedExistingHistory = existingHistory.slice(); // copy original existingHistory array\n copiedExistingHistory.splice(copiedExistingHistory.indexOf(item), 1);\n copiedExistingHistory.splice(0, 0, item);\n localStorage.setItem(`${this.historyIdentifier}`, JSON.stringify(copiedExistingHistory));\n }\n }\n } else {\n this.saveHistory(item);\n }\n } else {\n this.saveHistory(item);\n }\n this.handleClose();\n }\n\n /**\n * Document click\n * @param e event\n */\n public handleClick(e) {\n let clickedComponent = e.target;\n let inside = false;\n do {\n if (clickedComponent === this.elementRef.nativeElement) {\n inside = true;\n if (this.filteredList.length) {\n this.handleOpen();\n }\n }\n clickedComponent = clickedComponent.parentNode;\n } while (clickedComponent);\n if (!inside) {\n this.handleClose();\n }\n }\n\n /**\n * Handle body overlay\n */\n handleOverlay() {\n this.overlay = false;\n }\n\n /**\n * Scroll items\n */\n public handleScroll() {\n this.renderer.listen(this.filteredListElement.nativeElement, 'scroll', () => {\n this.scrollToEnd();\n });\n }\n\n /**\n * Define panel state\n */\n setPanelState(event) {\n if (event) {\n event.stopPropagation();\n }\n // If controls are untouched\n if (typeof this.manualOpen === 'undefined'\n && typeof this.manualClose === 'undefined') {\n this.isOpen = false;\n this.handleOpen();\n }\n\n // If one of the controls is untouched and other is deactivated\n if (typeof this.manualOpen === 'undefined'\n && this.manualClose === false\n || typeof this.manualClose === 'undefined'\n && this.manualOpen === false) {\n this.isOpen = false;\n this.handleOpen();\n }\n\n // if controls are touched but both are deactivated\n if (this.manualOpen === false && this.manualClose === false) {\n this.isOpen = false;\n this.handleOpen();\n }\n\n // if open control is touched and activated\n if (this.manualOpen) {\n this.isOpen = false;\n this.handleOpen();\n this.manualOpen = false;\n }\n\n // if close control is touched and activated\n if (this.manualClose) {\n this.isOpen = true;\n this.handleClose();\n this.manualClose = false;\n }\n }\n\n /**\n * Manual controls\n */\n open() {\n this.manualOpen = true;\n this.isOpen = false;\n this.handleOpen();\n }\n\n close() {\n this.manualClose = true;\n this.isOpen = true;\n this.handleClose();\n }\n\n focus() {\n this.handleFocus(event);\n }\n\n clear() {\n this.remove(event);\n }\n\n /**\n * Remove search query\n */\n public remove(e) {\n e.stopPropagation();\n this.query = '';\n this.inputCleared.emit();\n this.propagateChange(this.query);\n this.setPanelState(e);\n\n if (this.data && !this.data.length) {\n this.notFound = false;\n }\n }\n\n /**\n * Initialize historyList search\n */\n initSearchHistory() {\n this.isHistoryListVisible = false;\n if (this.historyIdentifier && !this.query) {\n const history = window.localStorage.getItem(`${this.historyIdentifier}`);\n if (history) {\n this.isHistoryListVisible = true;\n this.filteredList = [];\n this.historyList = history ? JSON.parse(history) : [];\n } else {\n this.isHistoryListVisible = false;\n }\n } else {\n this.isHistoryListVisible = false;\n }\n }\n\n handleOpen() {\n if (this.isOpen || this.isOpen && !this.isLoading) {\n return;\n }\n // If data exists\n if (this.data && this.data.length) {\n this.isOpen = true;\n this.overlay = true;\n this.filterList();\n this.opened.emit();\n }\n }\n\n handleClose() {\n if (!this.isOpen) {\n this.isFocused = false;\n return;\n }\n this.isOpen = false;\n this.overlay = false;\n this.filteredList = [];\n this.selectedIdx = -1;\n this.notFound = false;\n this.isHistoryListVisible = false;\n this.isFocused = false;\n this.closed.emit();\n }\n\n handleFocus(e) {\n this.searchInput.nativeElement.focus();\n if (this.isFocused) {\n return;\n }\n this.inputFocused.emit(e);\n // if data exists then open\n if (this.data && this.data.length) {\n this.setPanelState(e);\n }\n this.isFocused = true;\n }\n\n scrollToEnd(): void {\n if (this.isScrollToEnd) {\n return;\n }\n\n const scrollTop = this.filteredListElement.nativeElement\n .scrollTop;\n const scrollHeight = this.filteredListElement.nativeElement\n .scrollHeight;\n const elementHeight = this.filteredListElement.nativeElement\n .clientHeight;\n const atBottom = elementHeight !=0 && Math.abs(scrollHeight - elementHeight - scrollTop) < 1;\n\n if (atBottom) {\n this.scrolledToEnd.emit();\n this.isScrollToEnd = true;\n }\n }\n\n /**\n * Initialize keyboard events\n */\n initEventStream() {\n this.inputKeyUp$ = fromEvent(\n this.searchInput.nativeElement, 'keyup'\n ).pipe(map(\n (e: any) => e\n ));\n\n this.inputKeyDown$ = fromEvent(\n this.searchInput.nativeElement,\n 'keydown'\n ).pipe(map(\n (e: any) => e\n ));\n\n this.listenEventStream();\n }\n\n /**\n * Listen keyboard events\n */\n listenEventStream() {\n // key up event\n this.inputKeyUp$\n .pipe(\n filter(e =>\n !isArrowUpDown(e.keyCode) &&\n !isEnter(e.keyCode) &&\n !isESC(e.keyCode) &&\n !isTab(e.keyCode)),\n debounceTime(this.debounceTime)\n ).subscribe(e => {\n this.onKeyUp(e);\n });\n\n // cursor up & down\n this.inputKeyDown$.pipe(filter(\n e => isArrowUpDown(e.keyCode)\n )).subscribe(e => {\n e.preventDefault();\n this.onFocusItem(e);\n });\n\n // enter keyup\n this.inputKeyUp$.pipe(filter(e => isEnter(e.keyCode))).subscribe(e => {\n //this.onHandleEnter();\n });\n\n // enter keydown\n this.inputKeyDown$.pipe(filter(e => isEnter(e.keyCode))).subscribe(e => {\n this.onHandleEnter();\n });\n\n // ESC\n this.inputKeyUp$.pipe(\n filter(e => isESC(e.keyCode),\n debounceTime(100))\n ).subscribe(e => {\n this.onEsc();\n });\n\n // TAB\n this.inputKeyDown$.pipe(\n filter(e => isTab(e.keyCode))\n ).subscribe(e => {\n this.onTab();\n });\n\n // delete\n this.inputKeyDown$.pipe(\n filter(e => isBackspace(e.keyCode) || isDelete(e.keyCode))\n ).subscribe(e => {\n this.onDelete();\n });\n }\n\n /**\n * on keyup == when input changed\n * @param e event\n */\n onKeyUp(e) {\n this.notFound = false; // search results are unknown while typing\n // if input is empty\n if (!this.query) {\n this.notFound = false;\n this.inputChanged.emit(e.target.value);\n this.inputCleared.emit();\n this.setPanelState(e);\n }\n // note that '' can be a valid query\n if (!this.query && this.query !== '') {\n return;\n }\n // if query >= to minQueryLength\n if (this.query.length >= this.minQueryLength) {\n this.inputChanged.emit(e.target.value);\n this.filterList();\n\n // If no results found\n if (!this.filteredList.length && !this.isLoading) {\n this.notFoundText ? this.notFound = true : this.notFound = false;\n }\n\n if (this.data && !this.data.length) {\n this.isOpen = true;\n }\n }\n }\n\n\n /**\n * Keyboard arrow top and arrow bottom\n * @param e event\n */\n onFocusItem(e) {\n // move arrow up and down on filteredList or historyList\n if (!this.historyList.length || !this.isHistoryListVisible) {\n // filteredList\n const totalNumItem = this.filteredList.length;\n if (e.key === 'ArrowDown') {\n let sum = this.selectedIdx;\n sum = (this.selectedIdx === null) ? 0 : sum + 1;\n this.selectedIdx = (totalNumItem + sum) % totalNumItem;\n this.scrollToFocusedItem(this.selectedIdx);\n } else if (e.key === 'ArrowUp') {\n if (this.selectedIdx == -1) {\n this.selectedIdx = 0;\n }\n this.selectedIdx = (totalNumItem + this.selectedIdx - 1) % totalNumItem;\n this.scrollToFocusedItem(this.selectedIdx);\n }\n } else {\n // historyList\n const totalNumItem = this.historyList.length;\n if (e.key === 'ArrowDown') {\n let sum = this.selectedIdx;\n sum = (this.selectedIdx === null) ? 0 : sum + 1;\n this.selectedIdx = (totalNumItem + sum) % totalNumItem;\n this.scrollToFocusedItem(this.selectedIdx);\n } else if (e.key === 'ArrowUp') {\n if (this.selectedIdx == -1) {\n this.selectedIdx = 0;\n }\n this.selectedIdx = (totalNumItem + this.selectedIdx - 1) % totalNumItem;\n this.scrollToFocusedItem(this.selectedIdx);\n }\n }\n }\n\n /**\n * Scroll to focused item\n * * @param index\n */\n scrollToFocusedItem(index) {\n let listElement = null;\n // Define list element\n if (!this.historyList.length || !this.isHistoryListVisible) {\n // filteredList element\n listElement = this.filteredListElement.nativeElement;\n } else {\n // historyList element\n listElement = this.historyListElement.nativeElement;\n }\n\n const items = Array.prototype.slice.call(listElement.childNodes).filter((node: any) => {\n if (node.nodeType === 1) {\n // if node is element\n return node.className.includes('item');\n } else {\n return false;\n }\n });\n\n if (!items.length) {\n return;\n }\n\n const listHeight = listElement.offsetHeight;\n const itemHeight = items[index].offsetHeight;\n const visibleTop = listElement.scrollTop;\n const visibleBottom = listElement.scrollTop + listHeight - itemHeight;\n const targetPosition = items[index].offsetTop;\n\n if (targetPosition < visibleTop) {\n listElement.scrollTop = targetPosition;\n }\n\n if (targetPosition > visibleBottom) {\n listElement.scrollTop = targetPosition - listHeight + itemHeight;\n }\n }\n\n /**\n * Select item on enter click\n */\n onHandleEnter() {\n // click enter to choose item from filteredList or historyList\n if (this.selectedIdx > -1) {\n if (!this.historyList.length || !this.isHistoryListVisible) {\n // filteredList\n this.query = !this.isTypeString(this.filteredList[this.selectedIdx])\n ? this.filteredList[this.selectedIdx][this.searchKeyword]\n : this.filteredList[this.selectedIdx];\n\n this.saveHistory(this.filteredList[this.selectedIdx]);\n this.select(this.filteredList[this.selectedIdx]);\n } else {\n // historyList\n this.query = !this.isTypeString(this.historyList[this.selectedIdx])\n ? this.historyList[this.selectedIdx][this.searchKeyword]\n : this.historyList[this.selectedIdx];\n this.saveHistory(this.historyList[this.selectedIdx]);\n this.select(this.historyList[this.selectedIdx]);\n }\n }\n this.isHistoryListVisible = false;\n this.handleClose();\n }\n\n /**\n * Esc click\n */\n onEsc() {\n this.searchInput.nativeElement.blur();\n this.handleClose();\n }\n\n /**\n * Tab click\n */\n onTab() {\n this.searchInput.nativeElement.blur();\n this.handleClose();\n }\n\n /**\n * Delete click\n */\n onDelete() {\n this.isOpen = true;\n }\n\n\n /**\n * Select item to save in localStorage\n * @param selected\n */\n saveHistory(selected) {\n if (this.historyIdentifier) {\n // check if selected item exists in historyList\n if (!this.historyList.some((item) => !this.isTypeString(item)\n ? item[this.searchKeyword] == selected[this.searchKeyword] : item == selected)) {\n this.saveHistoryToLocalStorage([selected, ...this.historyList]);\n\n // check if items don't exceed max allowed number\n if (this.historyList.length >= this.historyListMaxNumber) {\n this.historyList.splice(this.historyList.length - 1, 1);\n this.saveHistoryToLocalStorage([selected, ...this.historyList]);\n }\n } else {\n // if selected item exists in historyList swap to top in array\n if (!this.isTypeString(selected)) {\n // object logic\n const copiedHistoryList = this.historyList.slice(); // copy original historyList array\n const selectedIndex = copiedHistoryList.map((item) => item[this.searchKeyword]).indexOf(selected[this.searchKeyword]);\n copiedHistoryList.splice(selectedIndex, 1);\n copiedHistoryList.splice(0, 0, selected);\n this.saveHistoryToLocalStorage([...copiedHistoryList]);\n } else {\n // string logic\n const copiedHistoryList = this.historyList.slice(); // copy original historyList array\n copiedHistoryList.splice(this.historyList.indexOf(selected), 1);\n copiedHistoryList.splice(0, 0, selected);\n this.saveHistoryToLocalStorage([...copiedHistoryList]);\n }\n }\n }\n }\n\n /**\n * Save item in localStorage\n * @param selected\n */\n saveHistoryToLocalStorage(selected) {\n window.localStorage.setItem(\n `${this.historyIdentifier}`,\n JSON.stringify(selected)\n );\n }\n\n /**\n * Remove item from localStorage\n * @param index\n * @param e event\n */\n removeHistoryItem(index, e) {\n e.stopPropagation();\n this.historyList = this.historyList.filter((v, i) => i !== index);\n this.saveHistoryToLocalStorage(this.historyList);\n if (this.historyList.length == 0) {\n window.localStorage.removeItem(`${this.historyIdentifier}`);\n this.filterList();\n }\n }\n\n /**\n * Reset localStorage\n * @param e event\n */\n resetHistoryList(e) {\n e.stopPropagation();\n this.historyList = [];\n window.localStorage.removeItem(`${this.historyIdentifier}`);\n this.filterList();\n }\n}\n","<div class=\"autocomplete-container\" aria-owns=\"suggestions suggestions-history\" [attr.aria-expanded]=\"isOpen\"\n [ngClass]=\"{ 'active': isOpen}\">\n <div class=\"input-container\">\n <input #searchInput\n type=\"text\"\n attr.aria-label=\"{{placeholder}}\"\n aria-autocomplete=\"list\"\n role=\"combobox\"\n placeholder={{placeholder}}\n [(ngModel)]=query\n (input)=\"onChange($event)\"\n (focus)=handleFocus($event)\n (blur)=onTouched($event)\n [disabled]=\"disabled\"\n autocomplete=\"off\">\n <div class=\"x\" *ngIf=\"query && !isLoading && !disabled\" (click)=\"remove($event)\">\n <i class=\"material-icons\" aria-label=\"Close\">close</i>\n </div>\n <!--Loading mask-->\n <div class=\"sk-fading-circle\" *ngIf=\"isLoading\">\n <div class=\"sk-circle1 sk-circle\"></div>\n <div class=\"sk-circle2 sk-circle\"></div>\n <div class=\"sk-circle3 sk-circle\"></div>\n <div class=\"sk-circle4 sk-circle\"></div>\n <div class=\"sk-circle5 sk-circle\"></div>\n <div class=\"sk-circle6 sk-circle\"></div>\n <div class=\"sk-circle7 sk-circle\"></div>\n <div class=\"sk-circle8 sk-circle\"></div>\n <div class=\"sk-circle9 sk-circle\"></div>\n <div class=\"sk-circle10 sk-circle\"></div>\n <div class=\"sk-circle11 sk-circle\"></div>\n <div class=\"sk-circle12 sk-circle\"></div>\n </div>\n </div>\n\n <!--FilteredList items-->\n <div class=\"suggestions-container\" id=\"suggestions\" role=\"listbox\"\n [ngClass]=\"{ 'is-hidden': isHistoryListVisible, 'is-visible': !isHistoryListVisible}\">\n <!--FilteredList heading-->\n <div class=\"heading\" *ngIf=\"filteredList.length > 0 && heading\">\n <div class=\"text\">{{heading}}</div>\n </div>\n\n <ul #filteredListElement>\n <li *ngFor=\"let item of filteredList; let idx = index\" class=\"item\">\n <!--string logic-->\n <div [class.complete-selected]=\"idx === selectedIdx\" *ngIf='isTypeString(item)'\n (click)=\"select(item)\">\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item | highlight: toHighlight }\">\n </ng-container>\n </div>\n <!--object logic-->\n <div [class.complete-selected]=\"idx === selectedIdx\" *ngIf='!isTypeString(item)'\n (click)=\"select(item)\">\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item | highlight: toHighlight : searchKeyword }\">\n </ng-container>\n </div>\n </li>\n </ul>\n </div>\n\n <!--HistoryList items-->\n <div class=\"suggestions-container\" id=\"suggestions-history\" role=\"listbox\"\n [ngClass]=\"{ 'is-hidden': !isHistoryListVisible, 'is-visible': isHistoryListVisible}\">\n <!--HistoryList heading-->\n <div class=\"heading\" *ngIf=\"historyList.length > 0 && historyHeading\">\n <div class=\"text\">{{historyHeading}}</div>\n <div class=\"x\" (click)=\"resetHistoryList($event)\">\n <i class=\"material-icons\" aria-label=\"Delete\">delete</i>\n </div>\n </div>\n\n <ul #historyListElement>\n <li *ngFor=\"let item of historyList; let idx = index\" class=\"item\">\n <!--string logic-->\n <div [class.complete-selected]=\"idx === selectedIdx\" *ngIf='isTypeString(item)' (click)=\"select(item)\">\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\">\n </ng-container>\n </div>\n <!--object logic-->\n <div [class.complete-selected]=\"idx === selectedIdx\" *ngIf='!isTypeString(item)' (click)=\"select(item)\">\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\">\n </ng-container>\n </div>\n <div class=\"x\" (click)=\"removeHistoryItem(idx, $event)\">\n <i class=\"material-icons\" aria-label=\"Close\">close</i>\n </div>\n </li>\n </ul>\n </div>\n\n <!--Not found-->\n <div class=\"not-found\" *ngIf=\"isLoading ? !isLoading && notFound : notFound\">\n <ng-container\n *ngTemplateOutlet=\"notFoundTemplate; context: { $implicit: notFoundText }\">\n </ng-container>\n </div>\n</div>\n<div class=\"autocomplete-overlay\" *ngIf=\"overlay\" (click)=\"handleOverlay()\"></div>\n","import {NgModule} from '@angular/core';\nimport {AutocompleteComponent} from './autocomplete.component';\nimport {FormsModule} from '@angular/forms';\nimport {CommonModule} from '@angular/common';\nimport {HighlightPipe} from './highlight.pipe';\n\n@NgModule({\n imports: [\n CommonModule,\n FormsModule\n ],\n declarations: [AutocompleteComponent, HighlightPipe],\n exports: [ AutocompleteComponent, HighlightPipe]\n})\nexport class AutocompleteLibModule {\n}\n","/*\n * Public API Surface of autocomplete-lib\n */\n\nexport * from './lib/autocomplete-lib.module';\nexport * from './lib/autocomplete.component';\nexport * from './lib/highlight.pipe';\n\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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