UNPKG

ngx-bootstrap

Version:
240 lines 12.3 kB
import { Component, ElementRef, HostListener, QueryList, ViewChild, ViewChildren, Renderer2 } from '@angular/core'; import { isBs3, Utils } from '../utils'; import { latinize } from './typeahead-utils'; var TypeaheadContainerComponent = /** @class */ (function () { function TypeaheadContainerComponent(element, renderer) { this.renderer = renderer; this.isFocused = false; this._matches = []; this.isScrolledIntoView = function (elem) { var containerViewTop = this.ulElement.nativeElement.scrollTop; var containerViewBottom = containerViewTop + this.ulElement.nativeElement.offsetHeight; var elemTop = elem.offsetTop; var elemBottom = elemTop + elem.offsetHeight; return ((elemBottom <= containerViewBottom) && (elemTop >= containerViewTop)); }; this.element = element; } Object.defineProperty(TypeaheadContainerComponent.prototype, "isBs4", { get: function () { return !isBs3(); }, enumerable: true, configurable: true }); Object.defineProperty(TypeaheadContainerComponent.prototype, "active", { get: function () { return this._active; }, enumerable: true, configurable: true }); Object.defineProperty(TypeaheadContainerComponent.prototype, "matches", { get: function () { return this._matches; }, set: function (value) { var _this = this; this._matches = value; this.needScrollbar = this.typeaheadScrollable && this.typeaheadOptionsInScrollableView < this.matches.length; if (this.typeaheadScrollable) { setTimeout(function () { _this.setScrollableMode(); }); } if (this._matches.length > 0) { this._active = this._matches[0]; if (this._active.isHeader()) { this.nextActiveMatch(); } } }, enumerable: true, configurable: true }); Object.defineProperty(TypeaheadContainerComponent.prototype, "optionsListTemplate", { get: function () { return this.parent ? this.parent.optionsListTemplate : undefined; }, enumerable: true, configurable: true }); Object.defineProperty(TypeaheadContainerComponent.prototype, "typeaheadScrollable", { get: function () { return this.parent ? this.parent.typeaheadScrollable : false; }, enumerable: true, configurable: true }); Object.defineProperty(TypeaheadContainerComponent.prototype, "typeaheadOptionsInScrollableView", { get: function () { return this.parent ? this.parent.typeaheadOptionsInScrollableView : 5; }, enumerable: true, configurable: true }); Object.defineProperty(TypeaheadContainerComponent.prototype, "itemTemplate", { get: function () { return this.parent ? this.parent.typeaheadItemTemplate : undefined; }, enumerable: true, configurable: true }); TypeaheadContainerComponent.prototype.selectActiveMatch = function () { this.selectMatch(this._active); }; TypeaheadContainerComponent.prototype.prevActiveMatch = function () { var index = this.matches.indexOf(this._active); this._active = this.matches[index - 1 < 0 ? this.matches.length - 1 : index - 1]; if (this._active.isHeader()) { this.prevActiveMatch(); } if (this.typeaheadScrollable) { this.scrollPrevious(index); } }; TypeaheadContainerComponent.prototype.nextActiveMatch = function () { var index = this.matches.indexOf(this._active); this._active = this.matches[index + 1 > this.matches.length - 1 ? 0 : index + 1]; if (this._active.isHeader()) { this.nextActiveMatch(); } if (this.typeaheadScrollable) { this.scrollNext(index); } }; TypeaheadContainerComponent.prototype.selectActive = function (value) { this.isFocused = true; this._active = value; }; TypeaheadContainerComponent.prototype.highlight = function (match, query) { var itemStr = match.value; var itemStrHelper = (this.parent && this.parent.typeaheadLatinize ? latinize(itemStr) : itemStr).toLowerCase(); var startIdx; var tokenLen; // Replaces the capture string with the same string inside of a "strong" tag if (typeof query === 'object') { var queryLen = query.length; for (var i = 0; i < queryLen; i += 1) { // query[i] is already latinized and lower case startIdx = itemStrHelper.indexOf(query[i]); tokenLen = query[i].length; if (startIdx >= 0 && tokenLen > 0) { itemStr = itemStr.substring(0, startIdx) + "<strong>" + itemStr.substring(startIdx, startIdx + tokenLen) + "</strong>" + ("" + itemStr.substring(startIdx + tokenLen)); itemStrHelper = itemStrHelper.substring(0, startIdx) + " " + ' '.repeat(tokenLen) + " " + ("" + itemStrHelper.substring(startIdx + tokenLen)); } } } else if (query) { // query is already latinized and lower case startIdx = itemStrHelper.indexOf(query); tokenLen = query.length; if (startIdx >= 0 && tokenLen > 0) { itemStr = itemStr.substring(0, startIdx) + "<strong>" + itemStr.substring(startIdx, startIdx + tokenLen) + "</strong>" + ("" + itemStr.substring(startIdx + tokenLen)); } } return itemStr; }; TypeaheadContainerComponent.prototype.focusLost = function () { this.isFocused = false; }; TypeaheadContainerComponent.prototype.isActive = function (value) { return this._active === value; }; TypeaheadContainerComponent.prototype.selectMatch = function (value, e) { var _this = this; if (e === void 0) { e = void 0; } if (e) { e.stopPropagation(); e.preventDefault(); } this.parent.changeModel(value); setTimeout(function () { return _this.parent.typeaheadOnSelect.emit(value); }, 0); return false; }; TypeaheadContainerComponent.prototype.setScrollableMode = function () { if (!this.ulElement) { this.ulElement = this.element; } if (this.liElements.first) { var ulStyles = Utils.getStyles(this.ulElement.nativeElement); var liStyles = Utils.getStyles(this.liElements.first.nativeElement); var ulPaddingBottom = parseFloat((ulStyles['padding-bottom'] ? ulStyles['padding-bottom'] : '').replace('px', '')); var ulPaddingTop = parseFloat((ulStyles['padding-top'] ? ulStyles['padding-top'] : '0').replace('px', '')); var optionHeight = parseFloat((liStyles['height'] ? liStyles['height'] : '0').replace('px', '')); var height = this.typeaheadOptionsInScrollableView * optionHeight; this.guiHeight = height + ulPaddingTop + ulPaddingBottom + "px"; } this.renderer.setStyle(this.element.nativeElement, 'visibility', 'visible'); }; TypeaheadContainerComponent.prototype.scrollPrevious = function (index) { if (index === 0) { this.scrollToBottom(); return; } if (this.liElements) { var liElement = this.liElements.toArray()[index - 1]; if (liElement && !this.isScrolledIntoView(liElement.nativeElement)) { this.ulElement.nativeElement.scrollTop = liElement.nativeElement.offsetTop; } } }; TypeaheadContainerComponent.prototype.scrollNext = function (index) { if (index + 1 > this.matches.length - 1) { this.scrollToTop(); return; } if (this.liElements) { var liElement = this.liElements.toArray()[index + 1]; if (liElement && !this.isScrolledIntoView(liElement.nativeElement)) { this.ulElement.nativeElement.scrollTop = liElement.nativeElement.offsetTop - this.ulElement.nativeElement.offsetHeight + liElement.nativeElement.offsetHeight; } } }; TypeaheadContainerComponent.prototype.scrollToBottom = function () { this.ulElement.nativeElement.scrollTop = this.ulElement.nativeElement.scrollHeight; }; TypeaheadContainerComponent.prototype.scrollToTop = function () { this.ulElement.nativeElement.scrollTop = 0; }; TypeaheadContainerComponent.decorators = [ { type: Component, args: [{ selector: 'typeahead-container', // tslint:disable-next-line template: "<!-- inject options list template --> <ng-template [ngTemplateOutlet]=\"optionsListTemplate || (isBs4 ? bs4Template : bs3Template)\" [ngTemplateOutletContext]=\"{matches:matches, itemTemplate:itemTemplate, query:query}\"></ng-template> <!-- default options item template --> <ng-template #bsItemTemplate let-match=\"match\" let-query=\"query\"><span [innerHtml]=\"highlight(match, query)\"></span> </ng-template> <!-- Bootstrap 3 options list template --> <ng-template #bs3Template> <ul class=\"dropdown-menu\" #ulElement [style.overflow-y]=\"needScrollbar ? 'scroll': 'auto'\" [style.height]=\"needScrollbar ? guiHeight: 'auto'\"> <ng-template ngFor let-match let-i=\"index\" [ngForOf]=\"matches\"> <li #liElements *ngIf=\"match.isHeader()\" class=\"dropdown-header\">{{ match }}</li> <li #liElements *ngIf=\"!match.isHeader()\" [class.active]=\"isActive(match)\" (mouseenter)=\"selectActive(match)\"> <a href=\"#\" (click)=\"selectMatch(match, $event)\" tabindex=\"-1\"> <ng-template [ngTemplateOutlet]=\"itemTemplate || bsItemTemplate\" [ngTemplateOutletContext]=\"{item:match.item, index:i, match:match, query:query}\"></ng-template> </a> </li> </ng-template> </ul> </ng-template> <!-- Bootstrap 4 options list template --> <ng-template #bs4Template> <ng-template ngFor let-match let-i=\"index\" [ngForOf]=\"matches\"> <h6 *ngIf=\"match.isHeader()\" class=\"dropdown-header\">{{ match }}</h6> <ng-template [ngIf]=\"!match.isHeader()\"> <button #liElements class=\"dropdown-item\" (click)=\"selectMatch(match, $event)\" (mouseenter)=\"selectActive(match)\" [class.active]=\"isActive(match)\"> <ng-template [ngTemplateOutlet]=\"itemTemplate || bsItemTemplate\" [ngTemplateOutletContext]=\"{item:match.item, index:i, match:match, query:query}\"></ng-template> </button> </ng-template> </ng-template> </ng-template> ", host: { class: 'dropdown open', '[class.dropdown-menu]': 'isBs4', '[style.overflow-y]': "isBs4 && needScrollbar ? 'scroll': 'visible'", '[style.height]': "isBs4 && needScrollbar ? guiHeight: 'auto'", '[style.visibility]': "typeaheadScrollable ? 'hidden' : 'visible'", '[class.dropup]': 'dropup', style: 'position: absolute;display: block;' } },] }, ]; /** @nocollapse */ TypeaheadContainerComponent.ctorParameters = function () { return [ { type: ElementRef, }, { type: Renderer2, }, ]; }; TypeaheadContainerComponent.propDecorators = { "ulElement": [{ type: ViewChild, args: ['ulElement',] },], "liElements": [{ type: ViewChildren, args: ['liElements',] },], "focusLost": [{ type: HostListener, args: ['mouseleave',] }, { type: HostListener, args: ['blur',] },], }; return TypeaheadContainerComponent; }()); export { TypeaheadContainerComponent }; //# sourceMappingURL=typeahead-container.component.js.map