@rifaniponk/ionic-selectable
Version:
An Ionic component similar to Ionic Select, that allows to search items, including async search, group, add, edit, delete items, and much more. Supports Angular 16-20 and Ionic 7-8.
691 lines (673 loc) • 121 kB
JavaScript
import * as i0 from '@angular/core';
import { Directive, HostListener, HostBinding, ViewChild, Component, EventEmitter, TemplateRef, forwardRef, Input, ContentChild, Output, Optional, ViewEncapsulation, NgModule } from '@angular/core';
import { NgIf, NgTemplateOutlet, NgFor, NgClass, NgStyle, CommonModule } from '@angular/common';
import * as i2 from '@angular/forms';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import * as i1 from '@ionic/angular';
import { IonicModule, IonContent, IonInfiniteScroll } from '@ionic/angular';
class IonicSelectableAddItemTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableAddItemTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableAddItemTemplateDirective, isStandalone: true, selector: "[ionicSelectableAddItemTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableAddItemTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableAddItemTemplate]',
standalone: true,
}]
}] });
class IonicSelectableCloseButtonTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableCloseButtonTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableCloseButtonTemplateDirective, isStandalone: true, selector: "[ionicSelectableCloseButtonTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableCloseButtonTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableCloseButtonTemplate]',
standalone: true,
}]
}] });
class IonicSelectableFooterTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableFooterTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableFooterTemplateDirective, isStandalone: true, selector: "[ionicSelectableFooterTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableFooterTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableFooterTemplate]',
standalone: true,
}]
}] });
class IonicSelectableGroupEndTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableGroupEndTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableGroupEndTemplateDirective, isStandalone: true, selector: "[ionicSelectableGroupEndTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableGroupEndTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableGroupEndTemplate]',
standalone: true,
}]
}] });
class IonicSelectableGroupTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableGroupTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableGroupTemplateDirective, isStandalone: true, selector: "[ionicSelectableGroupTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableGroupTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableGroupTemplate]',
standalone: true,
}]
}] });
class IonicSelectableHeaderTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableHeaderTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableHeaderTemplateDirective, isStandalone: true, selector: "[ionicSelectableHeaderTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableHeaderTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableHeaderTemplate]',
standalone: true,
}]
}] });
class IonicSelectableIconTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableIconTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableIconTemplateDirective, isStandalone: true, selector: "[ionicSelectableIconTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableIconTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableIconTemplate]',
standalone: true
}]
}] });
class IonicSelectableItemEndTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableItemEndTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableItemEndTemplateDirective, isStandalone: true, selector: "[ionicSelectableItemEndTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableItemEndTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableItemEndTemplate]',
standalone: true,
}]
}] });
class IonicSelectableItemIconTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableItemIconTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableItemIconTemplateDirective, isStandalone: true, selector: "[ionicSelectableItemIconTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableItemIconTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableItemIconTemplate]',
standalone: true
}]
}] });
class IonicSelectableItemTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableItemTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableItemTemplateDirective, isStandalone: true, selector: "[ionicSelectableItemTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableItemTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableItemTemplate]',
standalone: true
}]
}] });
class IonicSelectableMessageTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableMessageTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableMessageTemplateDirective, isStandalone: true, selector: "[ionicSelectableMessageTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableMessageTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableMessageTemplate]',
standalone: true,
}]
}] });
class IonicSelectableModalComponent {
navParams;
_element;
_content;
_header;
selectComponent;
_searchbarComponent;
_infiniteScroll;
_cssClass = true;
get _canClearCssClass() {
return this.selectComponent.canClear;
}
get _isMultipleCssClass() {
return this.selectComponent.isMultiple;
}
get _isSearchingCssClass() {
return this.selectComponent._isSearching;
}
get _isIos() {
return this.selectComponent._isIos;
}
_isMD() {
return this.selectComponent._isMD;
}
get _isAddItemTemplateVisibleCssClass() {
return this.selectComponent._isAddItemTemplateVisible;
}
onResize() {
// ion-footer inside the template might change its height when
// device orientation changes.
this.selectComponent._positionAddItemTemplate();
}
constructor(navParams, _element) {
this.navParams = navParams;
this._element = _element;
this.selectComponent = this.navParams.get('selectComponent');
this.selectComponent._modalComponent = this;
this.selectComponent._selectedItems = [];
if (!this.selectComponent._isNullOrWhiteSpace(this.selectComponent.value)) {
if (this.selectComponent.isMultiple) {
this.selectComponent.value.forEach((item) => {
this.selectComponent._selectedItems.push(item);
});
}
else {
this.selectComponent._selectedItems.push(this.selectComponent.value);
}
}
this.selectComponent._setItemsToConfirm(this.selectComponent._selectedItems);
}
ngAfterViewInit() {
this._header = this._element.nativeElement.querySelector('ion-header');
if (this._searchbarComponent && this.selectComponent.shouldFocusSearchbar) {
// Focus after a delay because focus doesn't work without it.
setTimeout(() => {
this._searchbarComponent.setFocus();
}, 1000);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableModalComponent, deps: [{ token: i1.NavParams }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableModalComponent, isStandalone: true, selector: "ionic-selectable-modal", host: { listeners: { "window:resize": "onResize()" }, properties: { "class.ionic-selectable-modal": "this._cssClass", "class.ionic-selectable-modal-can-clear": "this._canClearCssClass", "class.ionic-selectable-modal-is-multiple": "this._isMultipleCssClass", "class.ionic-selectable-modal-is-searching": "this._isSearchingCssClass", "class.ionic-selectable-modal-ios": "this._isIos", "class.ionic-selectable-modal-md": "this._isMD", "class.ionic-selectable-modal-is-add-item-template-visible": "this._isAddItemTemplateVisibleCssClass" } }, viewQueries: [{ propertyName: "_content", first: true, predicate: IonContent, descendants: true }, { propertyName: "_searchbarComponent", first: true, predicate: ["searchbarComponent"], descendants: true }, { propertyName: "_infiniteScroll", first: true, predicate: IonInfiniteScroll, descendants: true }], ngImport: i0, template: "<ion-header>\n <ion-toolbar *ngIf=\"!selectComponent.headerTemplate\"\n [color]=\"selectComponent.headerColor ? selectComponent.headerColor : null\">\n <ion-buttons [slot]=\"selectComponent.closeButtonSlot\">\n <ion-button (click)=\"selectComponent._close()\">\n <span *ngIf=\"selectComponent.closeButtonTemplate\" [ngTemplateOutlet]=\"selectComponent.closeButtonTemplate\">\n </span>\n <span *ngIf=\"!selectComponent.closeButtonTemplate\">\n {{selectComponent.closeButtonText}}\n </span>\n </ion-button>\n </ion-buttons>\n <ion-title>\n <!-- Need span for for text ellipsis. -->\n <span *ngIf=\"selectComponent.titleTemplate\" [ngTemplateOutlet]=\"selectComponent.titleTemplate\">\n </span>\n <span *ngIf=\"!selectComponent.titleTemplate\">\n {{selectComponent.label}}\n </span>\n </ion-title>\n </ion-toolbar>\n <div *ngIf=\"selectComponent.headerTemplate\" [ngTemplateOutlet]=\"selectComponent.headerTemplate\">\n </div>\n <ion-toolbar *ngIf=\"selectComponent.canSearch || selectComponent.messageTemplate\">\n <ion-searchbar *ngIf=\"selectComponent.canSearch\" #searchbarComponent [(ngModel)]=\"selectComponent._searchText\"\n (ionInput)=\"selectComponent._filterItems()\" (ionClear)=\"selectComponent._onSearchbarClear()\"\n [placeholder]=\"selectComponent.searchPlaceholder\" [debounce]=\"selectComponent.searchDebounce\">\n </ion-searchbar>\n <div class=\"ionic-selectable-message\" *ngIf=\"selectComponent.messageTemplate\">\n <div [ngTemplateOutlet]=\"selectComponent.messageTemplate\">\n </div>\n </div>\n </ion-toolbar>\n</ion-header>\n<ion-content>\n <div class=\"ionic-selectable-spinner\" *ngIf=\"selectComponent._isSearching\">\n <div class=\"ionic-selectable-spinner-background\"></div>\n <ion-spinner></ion-spinner>\n </div>\n <ion-list class=\"ion-no-margin\" *ngIf=\"selectComponent._hasFilteredItems\">\n <ion-item-group *ngFor=\"let group of selectComponent._filteredGroups\" class=\"ionic-selectable-group\">\n <ion-item-divider *ngIf=\"selectComponent._hasGroups\"\n [color]=\"selectComponent.groupColor ? selectComponent.groupColor : null\">\n <!-- Need span for for text ellipsis. -->\n <span *ngIf=\"selectComponent.groupTemplate\" [ngTemplateOutlet]=\"selectComponent.groupTemplate\"\n [ngTemplateOutletContext]=\"{ group: group }\">\n </span>\n <!-- Need ion-label for text ellipsis. -->\n <ion-label *ngIf=\"!selectComponent.groupTemplate\">\n {{group.text}}\n </ion-label>\n <div *ngIf=\"selectComponent.groupEndTemplate\" slot=\"end\">\n <div [ngTemplateOutlet]=\"selectComponent.groupEndTemplate\" [ngTemplateOutletContext]=\"{ group: group }\">\n </div>\n </div>\n </ion-item-divider>\n <ion-item button=\"true\" detail=\"false\" *ngFor=\"let item of group.items\" (click)=\"selectComponent._select(item)\"\n class=\"ionic-selectable-item\" [ngClass]=\"{\n 'ionic-selectable-item-is-selected': selectComponent._isItemSelected(item),\n 'ionic-selectable-item-is-disabled': selectComponent._isItemDisabled(item)\n }\" [disabled]=\"selectComponent._isItemDisabled(item)\">\n <!-- Need span for text ellipsis. -->\n <span *ngIf=\"selectComponent.itemTemplate\" [ngTemplateOutlet]=\"selectComponent.itemTemplate\"\n [ngTemplateOutletContext]=\"{ item: item, isItemSelected: selectComponent._isItemSelected(item) }\">\n </span>\n <!-- Need ion-label for text ellipsis. -->\n <ion-label *ngIf=\"!selectComponent.itemTemplate\">\n {{selectComponent._formatItem(item)}}\n </ion-label>\n <div *ngIf=\"selectComponent.itemEndTemplate\" slot=\"end\">\n <div [ngTemplateOutlet]=\"selectComponent.itemEndTemplate\"\n [ngTemplateOutletContext]=\"{ item: item, isItemSelected: selectComponent._isItemSelected(item) }\">\n </div>\n </div>\n <span *ngIf=\"selectComponent.itemIconTemplate\" [ngTemplateOutlet]=\"selectComponent.itemIconTemplate\"\n [ngTemplateOutletContext]=\"{ item: item, isItemSelected: selectComponent._isItemSelected(item) }\">\n </span>\n <ion-icon *ngIf=\"!selectComponent.itemIconTemplate\"\n [name]=\"selectComponent._isItemSelected(item) ? 'checkmark-circle' : 'radio-button-off'\"\n [color]=\"selectComponent._isItemSelected(item) ? 'primary' : null\" [slot]=\"selectComponent.itemIconSlot\">\n </ion-icon>\n <ion-button *ngIf=\"selectComponent.canSaveItem\" class=\"ionic-selectable-item-button\" slot=\"end\" fill=\"outline\"\n (click)=\"selectComponent._saveItem($event, item)\">\n <ion-icon slot=\"icon-only\" ios=\"create\" md=\"create-sharp\"></ion-icon>\n </ion-button>\n <ion-button *ngIf=\"selectComponent.canDeleteItem\" class=\"ionic-selectable-item-button\" slot=\"end\" fill=\"outline\"\n (click)=\"selectComponent._deleteItemClick($event, item)\">\n <ion-icon slot=\"icon-only\" ios=\"trash\" md=\"trash-sharp\"></ion-icon>\n </ion-button>\n </ion-item>\n </ion-item-group>\n </ion-list>\n <!-- Fail text should be above InfiniteScroll to avoid a gap when no items are found. -->\n <div *ngIf=\"!selectComponent._hasFilteredItems\">\n <span *ngIf=\"selectComponent.searchFailTemplate\" [ngTemplateOutlet]=\"selectComponent.searchFailTemplate\">\n </span>\n <div *ngIf=\"!selectComponent.searchFailTemplate\" class=\"ion-margin\">\n {{selectComponent.searchFailText}}\n </div>\n </div>\n <ion-infinite-scroll [disabled]=\"!selectComponent.hasInfiniteScroll\"\n (ionInfinite)=\"selectComponent._getMoreItems()\">\n <ion-infinite-scroll-content></ion-infinite-scroll-content>\n </ion-infinite-scroll>\n</ion-content>\n<div class=\"ionic-selectable-add-item-template\" *ngIf=\"selectComponent._isAddItemTemplateVisible\"\n [ngStyle]=\"{ 'top.px': _header.offsetHeight }\">\n <div class=\"ionic-selectable-add-item-template-inner\"\n [ngStyle]=\"{ 'height': selectComponent._addItemTemplateFooterHeight }\">\n <span [ngTemplateOutlet]=\"selectComponent.addItemTemplate\"\n [ngTemplateOutletContext]=\"{ item: selectComponent._itemToAdd, isAdd: selectComponent._itemToAdd === null }\">\n </span>\n </div>\n</div>\n<ion-footer *ngIf=\"selectComponent._footerButtonsCount > 0 || selectComponent.footerTemplate\"\n [ngStyle]=\"{ 'visibility': selectComponent._isFooterVisible ? 'initial' : 'hidden' }\">\n <ion-toolbar *ngIf=\"!selectComponent.footerTemplate\">\n <ion-row>\n <ion-col *ngIf=\"selectComponent.canClear\">\n <ion-button expand=\"full\" (click)=\"selectComponent._clear()\"\n [disabled]=\"!selectComponent._selectedItems.length\">\n {{selectComponent.clearButtonText}}\n </ion-button>\n </ion-col>\n <ion-col *ngIf=\"selectComponent.canAddItem\">\n <ion-button expand=\"full\" (click)=\"selectComponent._addItemClick()\">\n {{selectComponent.addButtonText}}\n </ion-button>\n </ion-col>\n <ion-col *ngIf=\"selectComponent.isMultiple || selectComponent.hasConfirmButton\">\n <ion-button expand=\"full\" (click)=\"selectComponent._confirm()\"\n [disabled]=\"!selectComponent.isConfirmButtonEnabled\">\n {{selectComponent.confirmButtonText}}\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n <div *ngIf=\"selectComponent.footerTemplate\" [ngTemplateOutlet]=\"selectComponent.footerTemplate\">\n </div>\n</ion-footer>\n", dependencies: [{ kind: "ngmodule", type: IonicModule }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i1.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: i1.IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonItemDivider, selector: "ion-item-divider", inputs: ["color", "mode", "sticky"] }, { kind: "component", type: i1.IonItemGroup, selector: "ion-item-group" }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i1.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i1.IonRow, selector: "ion-row" }, { kind: "component", type: i1.IonSearchbar, selector: "ion-searchbar", inputs: ["animated", "autocapitalize", "autocomplete", "autocorrect", "cancelButtonIcon", "cancelButtonText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "maxlength", "minlength", "mode", "name", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value"] }, { kind: "component", type: i1.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: i1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i1.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-input-otp[type=text],ion-textarea,ion-searchbar" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableModalComponent, decorators: [{
type: Component,
args: [{ selector: 'ionic-selectable-modal', standalone: true, imports: [IonicModule, NgIf, NgTemplateOutlet, FormsModule, NgFor, NgClass, NgStyle], template: "<ion-header>\n <ion-toolbar *ngIf=\"!selectComponent.headerTemplate\"\n [color]=\"selectComponent.headerColor ? selectComponent.headerColor : null\">\n <ion-buttons [slot]=\"selectComponent.closeButtonSlot\">\n <ion-button (click)=\"selectComponent._close()\">\n <span *ngIf=\"selectComponent.closeButtonTemplate\" [ngTemplateOutlet]=\"selectComponent.closeButtonTemplate\">\n </span>\n <span *ngIf=\"!selectComponent.closeButtonTemplate\">\n {{selectComponent.closeButtonText}}\n </span>\n </ion-button>\n </ion-buttons>\n <ion-title>\n <!-- Need span for for text ellipsis. -->\n <span *ngIf=\"selectComponent.titleTemplate\" [ngTemplateOutlet]=\"selectComponent.titleTemplate\">\n </span>\n <span *ngIf=\"!selectComponent.titleTemplate\">\n {{selectComponent.label}}\n </span>\n </ion-title>\n </ion-toolbar>\n <div *ngIf=\"selectComponent.headerTemplate\" [ngTemplateOutlet]=\"selectComponent.headerTemplate\">\n </div>\n <ion-toolbar *ngIf=\"selectComponent.canSearch || selectComponent.messageTemplate\">\n <ion-searchbar *ngIf=\"selectComponent.canSearch\" #searchbarComponent [(ngModel)]=\"selectComponent._searchText\"\n (ionInput)=\"selectComponent._filterItems()\" (ionClear)=\"selectComponent._onSearchbarClear()\"\n [placeholder]=\"selectComponent.searchPlaceholder\" [debounce]=\"selectComponent.searchDebounce\">\n </ion-searchbar>\n <div class=\"ionic-selectable-message\" *ngIf=\"selectComponent.messageTemplate\">\n <div [ngTemplateOutlet]=\"selectComponent.messageTemplate\">\n </div>\n </div>\n </ion-toolbar>\n</ion-header>\n<ion-content>\n <div class=\"ionic-selectable-spinner\" *ngIf=\"selectComponent._isSearching\">\n <div class=\"ionic-selectable-spinner-background\"></div>\n <ion-spinner></ion-spinner>\n </div>\n <ion-list class=\"ion-no-margin\" *ngIf=\"selectComponent._hasFilteredItems\">\n <ion-item-group *ngFor=\"let group of selectComponent._filteredGroups\" class=\"ionic-selectable-group\">\n <ion-item-divider *ngIf=\"selectComponent._hasGroups\"\n [color]=\"selectComponent.groupColor ? selectComponent.groupColor : null\">\n <!-- Need span for for text ellipsis. -->\n <span *ngIf=\"selectComponent.groupTemplate\" [ngTemplateOutlet]=\"selectComponent.groupTemplate\"\n [ngTemplateOutletContext]=\"{ group: group }\">\n </span>\n <!-- Need ion-label for text ellipsis. -->\n <ion-label *ngIf=\"!selectComponent.groupTemplate\">\n {{group.text}}\n </ion-label>\n <div *ngIf=\"selectComponent.groupEndTemplate\" slot=\"end\">\n <div [ngTemplateOutlet]=\"selectComponent.groupEndTemplate\" [ngTemplateOutletContext]=\"{ group: group }\">\n </div>\n </div>\n </ion-item-divider>\n <ion-item button=\"true\" detail=\"false\" *ngFor=\"let item of group.items\" (click)=\"selectComponent._select(item)\"\n class=\"ionic-selectable-item\" [ngClass]=\"{\n 'ionic-selectable-item-is-selected': selectComponent._isItemSelected(item),\n 'ionic-selectable-item-is-disabled': selectComponent._isItemDisabled(item)\n }\" [disabled]=\"selectComponent._isItemDisabled(item)\">\n <!-- Need span for text ellipsis. -->\n <span *ngIf=\"selectComponent.itemTemplate\" [ngTemplateOutlet]=\"selectComponent.itemTemplate\"\n [ngTemplateOutletContext]=\"{ item: item, isItemSelected: selectComponent._isItemSelected(item) }\">\n </span>\n <!-- Need ion-label for text ellipsis. -->\n <ion-label *ngIf=\"!selectComponent.itemTemplate\">\n {{selectComponent._formatItem(item)}}\n </ion-label>\n <div *ngIf=\"selectComponent.itemEndTemplate\" slot=\"end\">\n <div [ngTemplateOutlet]=\"selectComponent.itemEndTemplate\"\n [ngTemplateOutletContext]=\"{ item: item, isItemSelected: selectComponent._isItemSelected(item) }\">\n </div>\n </div>\n <span *ngIf=\"selectComponent.itemIconTemplate\" [ngTemplateOutlet]=\"selectComponent.itemIconTemplate\"\n [ngTemplateOutletContext]=\"{ item: item, isItemSelected: selectComponent._isItemSelected(item) }\">\n </span>\n <ion-icon *ngIf=\"!selectComponent.itemIconTemplate\"\n [name]=\"selectComponent._isItemSelected(item) ? 'checkmark-circle' : 'radio-button-off'\"\n [color]=\"selectComponent._isItemSelected(item) ? 'primary' : null\" [slot]=\"selectComponent.itemIconSlot\">\n </ion-icon>\n <ion-button *ngIf=\"selectComponent.canSaveItem\" class=\"ionic-selectable-item-button\" slot=\"end\" fill=\"outline\"\n (click)=\"selectComponent._saveItem($event, item)\">\n <ion-icon slot=\"icon-only\" ios=\"create\" md=\"create-sharp\"></ion-icon>\n </ion-button>\n <ion-button *ngIf=\"selectComponent.canDeleteItem\" class=\"ionic-selectable-item-button\" slot=\"end\" fill=\"outline\"\n (click)=\"selectComponent._deleteItemClick($event, item)\">\n <ion-icon slot=\"icon-only\" ios=\"trash\" md=\"trash-sharp\"></ion-icon>\n </ion-button>\n </ion-item>\n </ion-item-group>\n </ion-list>\n <!-- Fail text should be above InfiniteScroll to avoid a gap when no items are found. -->\n <div *ngIf=\"!selectComponent._hasFilteredItems\">\n <span *ngIf=\"selectComponent.searchFailTemplate\" [ngTemplateOutlet]=\"selectComponent.searchFailTemplate\">\n </span>\n <div *ngIf=\"!selectComponent.searchFailTemplate\" class=\"ion-margin\">\n {{selectComponent.searchFailText}}\n </div>\n </div>\n <ion-infinite-scroll [disabled]=\"!selectComponent.hasInfiniteScroll\"\n (ionInfinite)=\"selectComponent._getMoreItems()\">\n <ion-infinite-scroll-content></ion-infinite-scroll-content>\n </ion-infinite-scroll>\n</ion-content>\n<div class=\"ionic-selectable-add-item-template\" *ngIf=\"selectComponent._isAddItemTemplateVisible\"\n [ngStyle]=\"{ 'top.px': _header.offsetHeight }\">\n <div class=\"ionic-selectable-add-item-template-inner\"\n [ngStyle]=\"{ 'height': selectComponent._addItemTemplateFooterHeight }\">\n <span [ngTemplateOutlet]=\"selectComponent.addItemTemplate\"\n [ngTemplateOutletContext]=\"{ item: selectComponent._itemToAdd, isAdd: selectComponent._itemToAdd === null }\">\n </span>\n </div>\n</div>\n<ion-footer *ngIf=\"selectComponent._footerButtonsCount > 0 || selectComponent.footerTemplate\"\n [ngStyle]=\"{ 'visibility': selectComponent._isFooterVisible ? 'initial' : 'hidden' }\">\n <ion-toolbar *ngIf=\"!selectComponent.footerTemplate\">\n <ion-row>\n <ion-col *ngIf=\"selectComponent.canClear\">\n <ion-button expand=\"full\" (click)=\"selectComponent._clear()\"\n [disabled]=\"!selectComponent._selectedItems.length\">\n {{selectComponent.clearButtonText}}\n </ion-button>\n </ion-col>\n <ion-col *ngIf=\"selectComponent.canAddItem\">\n <ion-button expand=\"full\" (click)=\"selectComponent._addItemClick()\">\n {{selectComponent.addButtonText}}\n </ion-button>\n </ion-col>\n <ion-col *ngIf=\"selectComponent.isMultiple || selectComponent.hasConfirmButton\">\n <ion-button expand=\"full\" (click)=\"selectComponent._confirm()\"\n [disabled]=\"!selectComponent.isConfirmButtonEnabled\">\n {{selectComponent.confirmButtonText}}\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n <div *ngIf=\"selectComponent.footerTemplate\" [ngTemplateOutlet]=\"selectComponent.footerTemplate\">\n </div>\n</ion-footer>\n" }]
}], ctorParameters: () => [{ type: i1.NavParams }, { type: i0.ElementRef }], propDecorators: { _content: [{
type: ViewChild,
args: [IonContent]
}], _searchbarComponent: [{
type: ViewChild,
args: ['searchbarComponent']
}], _infiniteScroll: [{
type: ViewChild,
args: [IonInfiniteScroll]
}], _cssClass: [{
type: HostBinding,
args: ['class.ionic-selectable-modal']
}], _canClearCssClass: [{
type: HostBinding,
args: ['class.ionic-selectable-modal-can-clear']
}], _isMultipleCssClass: [{
type: HostBinding,
args: ['class.ionic-selectable-modal-is-multiple']
}], _isSearchingCssClass: [{
type: HostBinding,
args: ['class.ionic-selectable-modal-is-searching']
}], _isIos: [{
type: HostBinding,
args: ['class.ionic-selectable-modal-ios']
}], _isMD: [{
type: HostBinding,
args: ['class.ionic-selectable-modal-md']
}], _isAddItemTemplateVisibleCssClass: [{
type: HostBinding,
args: ['class.ionic-selectable-modal-is-add-item-template-visible']
}], onResize: [{
type: HostListener,
args: ['window:resize']
}] } });
class IonicSelectablePlaceholderTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectablePlaceholderTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectablePlaceholderTemplateDirective, isStandalone: true, selector: "[ionicSelectablePlaceholderTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectablePlaceholderTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectablePlaceholderTemplate]',
standalone: true,
}]
}] });
class IonicSelectableSearchFailTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableSearchFailTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableSearchFailTemplateDirective, isStandalone: true, selector: "[ionicSelectableSearchFailTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableSearchFailTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableSearchFailTemplate]',
standalone: true,
}]
}] });
class IonicSelectableTitleTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableTitleTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableTitleTemplateDirective, isStandalone: true, selector: "[ionicSelectableTitleTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableTitleTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableTitleTemplate]',
standalone: true,
}]
}] });
class IonicSelectableValueTemplateDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableValueTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.4", type: IonicSelectableValueTemplateDirective, isStandalone: true, selector: "[ionicSelectableValueTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: IonicSelectableValueTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[ionicSelectableValueTemplate]',
standalone: true,
}]
}] });
class IonicSelectableComponent {
_modalController;
_platform;
ionItem;
_iterableDiffers;
_element;
_renderer;
_cssClass = true;
_isIos;
_isMD;
get _isMultipleCssClass() {
return this.isMultiple;
}
get _hasValueCssClass() {
return this.hasValue();
}
get _hasPlaceholderCssClass() {
return this._hasPlaceholder;
}
get _hasIonLabelCssClass() {
return this._hasIonLabel;
}
get _hasDefaultIonLabelCssClass() {
return this._ionLabelPosition === 'default';
}
get _hasFixedIonLabelCssClass() {
return this._ionLabelPosition === 'fixed';
}
get _hasStackedIonLabelCssClass() {
return this._ionLabelPosition === 'stacked';
}
get _hasFloatingIonLabelCssClass() {
return this._ionLabelPosition === 'floating';
}
_isOnSearchEnabled = true;
_isEnabled = true;
_shouldBackdropClose = true;
_isOpened = false;
_value = null;
_modal;
_itemsDiffer;
_hasObjects;
_canClear = false;
_hasConfirmButton = false;
_isMultiple = false;
_canAddItem = false;
_addItemObservable;
_deleteItemObservable;
onItemsChange = new EventEmitter();
_ionItemElement;
_ionLabelElement;
_hasIonLabel = false;
_ionLabelPosition = null;
_label = '';
get _hasInfiniteScroll() {
return this.isEnabled && this._modalComponent &&
this._modalComponent._infiniteScroll ? true : false;
}
get _shouldStoreItemValue() {
return this.shouldStoreItemValue && this._hasObjects;
}
_valueItems = [];
_searchText = '';
_hasSearchText = false;
_groups = [];
_itemsToConfirm = [];
_selectedItems = [];
_modalComponent;
_filteredGroups = [];
_hasGroups;
_isSearching;
_hasPlaceholder;
_isAddItemTemplateVisible = false;
_isFooterVisible = true;
_itemToAdd = null;
_footerButtonsCount = 0;
_hasFilteredItems = false;
/**
* Text of [Ionic Label](https://ionicframework.com/docs/api/label).
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#label).
*
* @readonly
* @default null
* @memberof IonicSelectableComponent
*/
get label() {
return this._label;
}
/**
* Text that the user has typed in Searchbar.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#searchtext).
*
* @readonly
* @default ''
* @memberof IonicSelectableComponent
*/
get searchText() {
return this._searchText;
}
set searchText(searchText) {
this._searchText = searchText;
this._setHasSearchText();
}
/**
* Determines whether search is running.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#issearching).
*
* @default false
* @readonly
* @memberof IonicSelectableComponent
*/
get isSearching() {
return this._isSearching;
}
/**
* Determines whether user has typed anything in Searchbar.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#hassearchtext).
*
* @default false
* @readonly
* @memberof IonicSelectableComponent
*/
get hasSearchText() {
return this._hasSearchText;
}
get value() {
return this._value;
}
set value(value) {
this._value = value;
// Set value items.
this._valueItems.splice(0, this._valueItems.length);
if (this.isMultiple) {
if (value && value.length) {
Array.prototype.push.apply(this._valueItems, value);
}
}
else {
if (!this._isNullOrWhiteSpace(value)) {
this._valueItems.push(value);
}
}
this._setIonItemHasValue();
this._setHasPlaceholder();
}
/**
* A list of items.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#items).
*
* @default []
* @memberof IonicSelectableComponent
*/
items = [];
itemsChange = new EventEmitter();
/**
* Determines whether the component is enabled.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#isenabled).
*
* @default true
* @memberof IonicSelectableComponent
*/
get isEnabled() {
return this._isEnabled;
}
set isEnabled(isEnabled) {
this._isEnabled = !!isEnabled;
this.enableIonItem(this._isEnabled);
}
/**
* Determines whether Modal should be closed when backdrop is clicked.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#shouldbackdropclose).
*
* @default true
* @memberof IonicSelectableComponent
*/
get shouldBackdropClose() {
return this._shouldBackdropClose;
}
set shouldBackdropClose(shouldBackdropClose) {
this._shouldBackdropClose = !!shouldBackdropClose;
}
/**
* Modal CSS class.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#modalcssclass).
*
* @default null
* @memberof IonicSelectableComponent
*/
modalCssClass = '';
/**
* Modal enter animation.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#modalenteranimation).
*
* @default null
* @memberof IonicSelectableComponent
*/
modalEnterAnimation;
/**
* Modal leave animation.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#modalleaveanimation).
*
* @default null
* @memberof IonicSelectableComponent
*/
modalLeaveAnimation;
/**
* Determines whether Modal is opened.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#isopened).
*
* @default false
* @readonly
* @memberof IonicSelectableComponent
*/
get isOpened() {
return this._isOpened;
}
/**
* Determines whether Confirm button is enabled.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#isconfirmbuttonenabled).
*
* @default true
* @memberof IonicSelectableComponent
*/
isConfirmButtonEnabled = true;
/**
* Determines whether Confirm button is visible for single selection.
* By default Confirm button is visible only for multiple selection.
* **Note**: It is always true for multiple selection and cannot be changed.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#hasconfirmbutton).
*
* @default true
* @memberof IonicSelectableComponent
*/
get hasConfirmButton() {
return this._hasConfirmButton;
}
set hasConfirmButton(hasConfirmButton) {
this._hasConfirmButton = !!hasConfirmButton;
this._countFooterButtons();
}
/**
* Item property to use as a unique identifier, e.g, `'id'`.
* **Note**: `items` should be an object array.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#itemvaluefield).
*
* @default null
* @memberof IonicSelectableComponent
*/
itemValueField = '';
/**
* Item property to display, e.g, `'name'`.
* **Note**: `items` should be an object array.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#itemtextfield).
*
* @default false
* @memberof IonicSelectableComponent
*/
itemTextField = '';
/**
*
* Group property to use as a unique identifier to group items, e.g. `'country.id'`.
* **Note**: `items` should be an object array.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#groupvaluefield).
*
* @default null
* @memberof IonicSelectableComponent
*/
groupValueField = '';
/**
* Group property to display, e.g. `'country.name'`.
* **Note**: `items` should be an object array.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#grouptextfield).
*
* @default null
* @memberof IonicSelectableComponent
*/
groupTextField = '';
/**
* Determines whether to show Searchbar.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#cansearch).
*
* @default false
* @memberof IonicSelectableComponent
*/
canSearch = false;
/**
* Determines whether `onSearch` event is enabled.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#isonsearchenabled).
*
* @default true
* @memberof IonicSelectableComponent
*/
get isOnSearchEnabled() {
return this._isOnSearchEnabled;
}
set isOnSearchEnabled(isOnSearchEnabled) {
this._isOnSearchEnabled = !!isOnSearchEnabled;
}
/**
* Determines whether to show Clear button.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#canclear).
*
* @default false
* @memberof IonicSelectableComponent
*/
get canClear() {
return this._canClear;
}
set canClear(canClear) {
this._canClear = !!canClear;
this._countFooterButtons();
}
/**
* Determines whether Ionic [InfiniteScroll](https://ionicframework.com/docs/api/components/infinite-scroll/InfiniteScroll/) is enabled.
* **Note**: Infinite scroll cannot be used together with virtual scroll.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#hasinfinitescroll).
*
* @default false
* @memberof IonicSelectableComponent
*/
hasInfiniteScroll = false;
/**
* Determines whether Ionic [VirtualScroll](https://ionicframework.com/docs/api/components/virtual-scroll/VirtualScroll/) is enabled.
* **Note**: Virtual scroll cannot be used together with infinite scroll.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#hasvirtualscroll).
*
* @default false
* @memberof IonicSelectableComponent
*/
hasVirtualScroll = false;
/**
* See Ionic VirtualScroll [approxItemHeight](https://ionicframework.com/docs/api/components/virtual-scroll/VirtualScroll/).
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#virtualscrollapproxitemheight).
*
* @default '40px'
* @memberof IonicSelectableComponent
*/
virtualScrollApproxItemHeight = '40px';
/**
* A placeholder for Searchbar.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#searchplaceholder).
*
* @default 'Search'
* @memberof IonicSelectableComponent
*/
searchPlaceholder = 'Search';
/**
* A placeholder.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#placeholder).
*
* @default null
* @memberof IonicSelectableComponent
*/
placeholder = '';
/**
* Determines whether multiple items can be selected.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#ismultiple).
*
* @default false
* @memberof IonicSelectableComponent
*/
get isMultiple() {
return this._isMultiple;
}
set isMultiple(isMultiple) {
this._isMultiple = !!isMultiple;
this._countFooterButtons();
}
/**
* Text to display when no items have been found during search.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#searchfailtext).
*
* @default 'No items found.'
* @memberof IonicSelectableComponent
*/
searchFailText = 'No items found.';
/**
* Clear button text.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#clearbuttontext).
*
* @default 'Clear'
* @memberof IonicSelectableComponent
*/
clearButtonText = 'Clear';
/**
* Add button text.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#addbuttontext).
*
* @default 'Add'
* @memberof IonicSelectableComponent
*/
addButtonText = 'Add';
/**
* Confirm button text.
* See more on [GitHub](https://github.com/eakoriakin/ionic-selectable/wiki/Documentation#confirmbuttontext).
*
* @default 'OK'
* @memberof IonicSelectableComponent
*/
confirmButtonText = 'OK';
/**
* Close button text.