ionic-selectable-v3
Version:
An Ionic component similar to Ionic Select, that allows to search items, including async search, group, add, edit, delete items, and much more.
1 lines • 38.9 kB
JavaScript
import{Directive,Component,ContentChild,ElementRef,EventEmitter,forwardRef,HostBinding,HostListener,Input,IterableDiffers,Optional,Output,TemplateRef,ViewChild,NgModule}from"@angular/core";import{NG_VALUE_ACCESSOR}from"@angular/forms";import{Form,Item,ModalController,Platform,Content,NavParams,IonicPageModule}from"ionic-angular";import"rxjs";import{CommonModule}from"@angular/common";class IonicSelectableAddItemTemplateDirective{}IonicSelectableAddItemTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableAddItemTemplate]"}]}],IonicSelectableAddItemTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableCloseButtonTemplateDirective{}IonicSelectableCloseButtonTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableCloseButtonTemplate]"}]}],IonicSelectableCloseButtonTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableFooterTemplateDirective{}IonicSelectableFooterTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableFooterTemplate]"}]}],IonicSelectableFooterTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableGroupEndTemplateDirective{}IonicSelectableGroupEndTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableGroupEndTemplate]"}]}],IonicSelectableGroupEndTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableGroupTemplateDirective{}IonicSelectableGroupTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableGroupTemplate]"}]}],IonicSelectableGroupTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableHeaderTemplateDirective{}IonicSelectableHeaderTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableHeaderTemplate]"}]}],IonicSelectableHeaderTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableItemEndTemplateDirective{}IonicSelectableItemEndTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableItemEndTemplate]"}]}],IonicSelectableItemEndTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableItemIconTemplateDirective{}IonicSelectableItemIconTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableItemIconTemplate]"}]}],IonicSelectableItemIconTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableItemTemplateDirective{}IonicSelectableItemTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableItemTemplate]"}]}],IonicSelectableItemTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableMessageTemplateDirective{}IonicSelectableMessageTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableMessageTemplate]"}]}],IonicSelectableMessageTemplateDirective.ctorParameters=(()=>[]);class IonicSelectablePlaceholderTemplateDirective{}IonicSelectablePlaceholderTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectablePlaceholderTemplate]"}]}],IonicSelectablePlaceholderTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableSearchFailTemplateDirective{}IonicSelectableSearchFailTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableSearchFailTemplate]"}]}],IonicSelectableSearchFailTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableTitleTemplateDirective{}IonicSelectableTitleTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableTitleTemplate]"}]}],IonicSelectableTitleTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableValueTemplateDirective{}IonicSelectableValueTemplateDirective.decorators=[{type:Directive,args:[{selector:"[ionicSelectableValueTemplate]"}]}],IonicSelectableValueTemplateDirective.ctorParameters=(()=>[]);class IonicSelectableComponent{constructor(e,t,i,n,l,s){this._modalController=e,this.ionForm=t,this._platform=i,this.ionItem=n,this._iterableDiffers=l,this.element=s,this._cssClass=!0,this._isOnSearchEnabled=!0,this._isEnabled=!0,this._shouldBackdropClose=!0,this._isOpened=!1,this._value=null,this._canClear=!1,this._hasConfirmButton=!1,this._isMultiple=!1,this._canAddItem=!1,this.onItemsChange=new EventEmitter,this._label=null,this._valueItems=[],this._searchText="",this._hasSearchText=!1,this._groups=[],this._itemsToConfirm=[],this._selectedItems=[],this._filteredGroups=[],this._isAddItemTemplateVisible=!1,this._isFooterVisible=!0,this._itemToAdd=null,this._footerButtonsCount=0,this._hasFilteredItems=!1,this.items=[],this.itemsChange=new EventEmitter,this.modalCssClass=null,this.modalEnterAnimation=null,this.modalLeaveAnimation=null,this.isConfirmButtonEnabled=!0,this.itemValueField=null,this.itemTextField=null,this.groupValueField=null,this.groupTextField=null,this.canSearch=!1,this.hasInfiniteScroll=!1,this.hasVirtualScroll=!1,this.virtualScrollApproxItemHeight="40px",this.virtualScrollApproxItemWidth="100%",this.virtualScrollBufferRatio=3,this.virtualScrollHeaderFn=(()=>null),this.searchPlaceholder="Search",this.placeholder=null,this.searchFailText="No items found.",this.clearButtonText="Clear",this.addButtonText="Add",this.confirmButtonText="OK",this.closeButtonText="Cancel",this.focusSearchbar=!1,this.headerColor=null,this.groupColor=null,this.onChange=new EventEmitter,this.onSearch=new EventEmitter,this.onSearchFail=new EventEmitter,this.onSearchSuccess=new EventEmitter,this.onInfiniteScroll=new EventEmitter,this.onOpen=new EventEmitter,this.onClose=new EventEmitter,this.onSelect=new EventEmitter,this.onClear=new EventEmitter,this.searchDebounce=250,this.disabledItems=[],this.shouldStoreItemValue=!1,this.canSaveItem=!1,this.canDeleteItem=!1,this.onSaveItem=new EventEmitter,this.onDeleteItem=new EventEmitter,this.onAddItem=new EventEmitter,this.propagateOnChange=(e=>{}),this.propagateOnTouched=(()=>{}),this.items&&this.items.length||(this.items=[]),this._itemsDiffer=this._iterableDiffers.find(this.items).create()}get _isMultipleCssClass(){return this.isMultiple}get _hasValueCssClass(){return this.hasValue()}get _hasPlaceholderCssClass(){return this._hasPlaceholder}get _shouldStoreItemValue(){return this.shouldStoreItemValue&&this._hasObjects}get label(){return this._label}get searchText(){return this._searchText}set searchText(e){this._searchText=e,this._setHasSearchText()}get isSearching(){return this._isSearching}get hasSearchText(){return this._hasSearchText}get value(){return this._value}set value(e){this._value=e,this._valueItems.splice(0,this._valueItems.length),this.isMultiple?e&&e.length&&Array.prototype.push.apply(this._valueItems,e):this._isNullOrWhiteSpace(e)||this._valueItems.push(e),this._setIonItemHasValue(),this._setHasPlaceholder()}get isEnabled(){return this._isEnabled}set isEnabled(e){this._isEnabled=!!e,this.enableIonItem(this._isEnabled)}get shouldBackdropClose(){return this._shouldBackdropClose}set shouldBackdropClose(e){this._shouldBackdropClose=!!e}get isOpened(){return this._isOpened}get hasConfirmButton(){return this._hasConfirmButton}set hasConfirmButton(e){this._hasConfirmButton=!!e,this._countFooterButtons()}get isOnSearchEnabled(){return this._isOnSearchEnabled}set isOnSearchEnabled(e){this._isOnSearchEnabled=!!e}get canClear(){return this._canClear}set canClear(e){this._canClear=!!e,this._countFooterButtons()}get isMultiple(){return this._isMultiple}set isMultiple(e){this._isMultiple=!!e,this._countFooterButtons()}get itemsToConfirm(){return this._itemsToConfirm}get canAddItem(){return this._canAddItem}set canAddItem(e){this._canAddItem=!!e,this._countFooterButtons()}initFocus(){}enableIonItem(e){this.ionItem&&this.ionItem.setElementClass("item-input-disabled",!e)}_click(e){this.isEnabled&&0!==e.detail&&(this._label=this._getLabelText(),e.preventDefault(),e.stopPropagation(),this.open().then(()=>{this.onOpen.emit({component:this})}))}_isNullOrWhiteSpace(e){return null==e||e.toString().replace(/\s/g,"").length<1}_setHasSearchText(){this._hasSearchText=!this._isNullOrWhiteSpace(this._searchText)}_hasOnSearch(){return this.isOnSearchEnabled&&this.onSearch.observers.length>0}_hasOnSaveItem(){return this.canSaveItem&&this.onSaveItem.observers.length>0}_hasOnAddItem(){return this.canAddItem&&this.onAddItem.observers.length>0}_hasOnDeleteItem(){return this.canDeleteItem&&this.onDeleteItem.observers.length>0}_emitValueChange(){this.propagateOnChange(this.value),this._setIonItemValidityClasses(),this.onChange.emit({component:this,value:this.value})}_emitSearch(){this.canSearch&&this.onSearch.emit({component:this,text:this._searchText})}_emitOnSelect(e,t){this.onSelect.emit({component:this,item:e,isSelected:t})}_emitOnClear(e){this.onClear.emit({component:this,items:e})}_emitOnSearchSuccessOrFail(e){const t={component:this,text:this._searchText};e?this.onSearchSuccess.emit(t):this.onSearchFail.emit(t)}_formatItem(e){return this._isNullOrWhiteSpace(e)?null:this.itemTextField?e[this.itemTextField]:e.toString()}_formatValueItem(e){if(this._shouldStoreItemValue){let t=this.items.find(t=>t[this.itemValueField]===e);return this._formatItem(t)}return this._formatItem(e)}_getItemValue(e){return this._hasObjects?e[this.itemValueField]:e}_getStoredItemValue(e){return this._hasObjects?this._shouldStoreItemValue?e:e[this.itemValueField]:e}_filterItems(){if(this._setHasSearchText(),this._hasOnSearch())this._emitSearch();else{let e=[];if(this._searchText&&this._searchText.trim()){let t=this._searchText.trim().toLowerCase();this._groups.forEach(i=>{let n=i.items.filter(e=>{return-1!==(this.itemTextField?e[this.itemTextField]:e).toString().toLowerCase().indexOf(t)});n.length&&e.push({value:i.value,text:i.text,items:n})}),e.length||e.push({items:[]})}else e=this._groups;this._filteredGroups=e,this._hasFilteredItems=!this._areGroupsEmpty(e),this._emitOnSearchSuccessOrFail(this._hasFilteredItems)}}_isItemDisabled(e){if(this.disabledItems)return this.disabledItems.some(t=>this._getItemValue(t)===this._getItemValue(e))}_isItemSelected(e){return void 0!==this._selectedItems.find(t=>this._getItemValue(e)===this._getStoredItemValue(t))}_addSelectedItem(e){this._shouldStoreItemValue?this._selectedItems.push(this._getItemValue(e)):this._selectedItems.push(e)}_deleteSelectedItem(e){let t;this._selectedItems.forEach((i,n)=>{this._getItemValue(e)===this._getStoredItemValue(i)&&(t=n)}),this._selectedItems.splice(t,1)}_saveItem(e,t){e.stopPropagation(),this._itemToAdd=t,this._hasOnSaveItem()?this.onSaveItem.emit({component:this,item:this._itemToAdd}):this.showAddItemTemplate()}_deleteItemClick(e,t){e.stopPropagation(),this._itemToAdd=t,this._hasOnDeleteItem()?this.onDeleteItem.emit({component:this,item:this._itemToAdd}):this.deleteItem(this._itemToAdd)}_addItemClick(){this._itemToAdd=null,this._hasOnAddItem()?this.onAddItem.emit({component:this}):this.showAddItemTemplate()}_close(){this._modalComponent._searchbarComponent&&this._modalComponent._searchbarComponent._fireBlur(),setTimeout(()=>{this.close().then(()=>{this.onClose.emit({component:this})}),this._hasOnSearch()||(this._searchText="",this._setHasSearchText())})}_clear(){const e=this._selectedItems;this.clear(),this._emitValueChange(),this._emitOnClear(e),this.close().then(()=>{this.onClose.emit({component:this})})}_getMoreItems(e){this._infiniteScroll=e,this.onInfiniteScroll.emit({component:this,text:this._searchText})}_setItemsToConfirm(e){this._itemsToConfirm=[].concat(e)}_doSelect(e){this.value=e,this._emitValueChange()}_select(e){const t=this._isItemSelected(e);this.isMultiple?(t?this._deleteSelectedItem(e):this._addSelectedItem(e),this._setItemsToConfirm(this._selectedItems),this._emitOnSelect(e,!t)):this.hasConfirmButton||this.footerTemplate?(this._selectedItems=[],t?this._deleteSelectedItem(e):this._addSelectedItem(e),this._setItemsToConfirm(this._selectedItems),this._emitOnSelect(e,!t)):(t||(this._selectedItems=[],this._addSelectedItem(e),this._emitOnSelect(e,!0),this._shouldStoreItemValue?this._doSelect(this._getItemValue(e)):this._doSelect(e)),this._close())}_confirm(){this.confirm(),this._close()}_getLabelText(){let e=this.ionItem?this.ionItem.getNativeElement().querySelector("ion-label"):null;return e?e.textContent:null}_areGroupsEmpty(e){return 0===e.length||e.every(e=>!e.items||0===e.items.length)}_countFooterButtons(){let e=0;this.canClear&&e++,(this.isMultiple||this._hasConfirmButton)&&e++,this.canAddItem&&e++,this._footerButtonsCount=e}_setItems(e){let t=[{items:e||[]}];e&&e.length&&this._hasGroups&&(t=[],e.forEach(e=>{let i=this._getPropertyValue(e,this.groupValueField),n=t.find(e=>e.value===i);n?n.items.push(e):t.push({value:i,text:this._getPropertyValue(e,this.groupTextField),items:[e]})})),this._groups=t,this._filteredGroups=this._groups,this._hasFilteredItems=!this._areGroupsEmpty(this._filteredGroups)}_getPropertyValue(e,t){return t?t.split(".").reduce((e,t)=>e?e[t]:null,e):null}_setIonItemHasFocus(e){this.ionItem&&this.ionItem.setElementClass("item-input-has-focus",e)}_setIonItemHasValue(){this.ionItem&&this.ionItem.setElementClass("item-input-has-value",this.hasValue())}_setHasPlaceholder(){this._hasPlaceholder=!(this.hasValue()||this._isNullOrWhiteSpace(this.placeholder)&&!this.placeholderTemplate)}_setIonItemValidityClasses(){this.ionItem&&requestAnimationFrame(()=>{let e=this.element.nativeElement.classList;this.ionItem.setElementClass("ng-invalid",!1),this.ionItem.setElementClass("ng-valid",!1),this.ionItem.setElementClass("ng-touched",!1),this.ionItem.setElementClass("ng-untouched",!1),this.ionItem.setElementClass("ng-dirty",!1),this.ionItem.setElementClass("ng-pristine",!1),e.forEach(e=>{"ng-invalid"===e&&this.ionItem.setElementClass("ng-invalid",!0),"ng-valid"===e&&this.ionItem.setElementClass("ng-valid",!0),"ng-touched"===e&&this.ionItem.setElementClass("ng-touched",!0),"ng-untouched"===e&&this.ionItem.setElementClass("ng-untouched",!0),"ng-dirty"===e&&this.ionItem.setElementClass("ng-dirty",!0),"ng-pristine"===e&&this.ionItem.setElementClass("ng-pristine",!0)})})}_toggleAddItemTemplate(e){this.addItemTemplate&&(this._isAddItemTemplateVisible=e,this._isFooterVisible=!e)}writeValue(e){this.value=e,this._setIonItemValidityClasses()}registerOnChange(e){this.propagateOnChange=e}registerOnTouched(e){this.propagateOnTouched=e}setDisabledState(e){this.isEnabled=!e}ngOnInit(){this._isIos=this._platform.is("ios"),this._isMD=!this._isIos,this._hasObjects=!this._isNullOrWhiteSpace(this.itemValueField),this._hasGroups=Boolean(this._hasObjects&&this.groupValueField&&!this.hasVirtualScroll),this.ionForm.register(this),this.ionItem&&(this.ionItem.setElementClass("item-input",!0),this.ionItem.setElementClass("item-ionic-selectable",!0)),this.enableIonItem(this.isEnabled)}ngOnDestroy(){this.ionForm.deregister(this)}ngDoCheck(){this._itemsDiffer.diff(this.items)&&(this._setItems(this.items),this.value=this.value,this.onItemsChange.emit({component:this}))}addItem(e){let t=this;return this.items.unshift(e),this._addItemObservable&&this._addItemObservable.unsubscribe(),new Promise(function(e,i){t._addItemObservable=t.onItemsChange.asObservable().subscribe(()=>{t._addItemObservable.unsubscribe(),e()},()=>{t._addItemObservable.unsubscribe(),i()})})}deleteItem(e){let t=this,i=!1;if(this._selectedItems&&(this._selectedItems=this._selectedItems.filter(t=>this._getItemValue(e)!==this._getStoredItemValue(t))),this.value)if(this.isMultiple){let t=this.value.filter(t=>t.id!==e.id);t.length!==this.value.length&&(this.value=t,i=!0)}else e===this.value&&(this.value=null,i=!0);i&&this._emitValueChange();let n=this.items.filter(t=>t.id!==e.id);return this.itemsChange.emit(n),this._setItems(n),this.onItemsChange.emit({component:this}),this._deleteItemObservable&&this._deleteItemObservable.unsubscribe(),new Promise(function(e,i){t._deleteItemObservable=t.onItemsChange.asObservable().subscribe(()=>{t._deleteItemObservable.unsubscribe(),e()},()=>{t._deleteItemObservable.unsubscribe(),i()})})}hasValue(){return this.isMultiple?0!==this._valueItems.length:0!==this._valueItems.length&&!this._isNullOrWhiteSpace(this._valueItems[0])}open(){let e=this;return new Promise(function(t,i){if(!e._isEnabled||e._isOpened)return void i("IonicSelectable is disabled or already opened.");e._filterItems(),e._isOpened=!0;const n={enableBackdropDismiss:e._shouldBackdropClose};e.modalCssClass&&(n.cssClass=e.modalCssClass),e.modalEnterAnimation&&(n.enterAnimation=e.modalEnterAnimation),e.modalLeaveAnimation&&(n.leaveAnimation=e.modalLeaveAnimation),e._modal=e._modalController.create(IonicSelectableModalComponent,{selectComponent:e},n),e._modal.present({animate:!1}).then(()=>{e._setIonItemHasFocus(!0),t()}),e._modal.onWillDismiss(()=>{e._setIonItemHasFocus(!1)}),e._modal.onDidDismiss((t,i)=>{e._isOpened=!1,e._itemsToConfirm=[],"backdrop"===i&&e.onClose.emit({component:e})})})}close(){let e=this;return new Promise(function(t,i){e._isEnabled&&e._isOpened?(e.propagateOnTouched(),e._setIonItemValidityClasses(),e._infiniteScroll=null,e._isOpened=!1,e._itemToAdd=null,e._modal.dismiss().then(()=>{e._setIonItemHasFocus(!1),e.hideAddItemTemplate(),t()})):i("IonicSelectable is disabled or already closed.")})}clear(){this.value=this.isMultiple?[]:null,this._itemsToConfirm=[],this.propagateOnChange(this.value),this._setIonItemValidityClasses()}confirm(){this.isMultiple?this._doSelect(this._selectedItems):(this.hasConfirmButton||this.footerTemplate)&&this._doSelect(this._selectedItems[0]||null)}toggleItems(e,t){if(e){const e=t&&t.length;let i=this._groups.reduce((e,t)=>e.concat(t.items),[]);this.isMultiple||e||(i=[]),e&&(i=i.filter(e=>void 0!==t.find(t=>this._getItemValue(e)===this._getItemValue(t))),this.isMultiple||i.splice(0,1)),i.forEach(e=>{this._addSelectedItem(e)})}else this._selectedItems=[];this._setItemsToConfirm(this._selectedItems)}scrollToTop(){let e=this;return new Promise(function(t,i){e._isOpened?e._modalComponent._content.scrollToTop().then(()=>{t()}):i("IonicSelectable content cannot be scrolled.")})}scrollToBottom(){let e=this;return new Promise(function(t,i){e._isOpened?e._modalComponent._content.scrollToBottom().then(()=>{t()}):i("IonicSelectable content cannot be scrolled.")})}startSearch(){this._isEnabled&&this.showLoading()}endSearch(){this._isEnabled&&(this.hideLoading(),this._setItems(this.items),this._emitOnSearchSuccessOrFail(this._hasFilteredItems))}enableInfiniteScroll(){this._isEnabled&&this._infiniteScroll&&this._infiniteScroll.enable(!0)}disableInfiniteScroll(){this._isEnabled&&this._infiniteScroll&&this._infiniteScroll.enable(!1)}endInfiniteScroll(){this._isEnabled&&this._infiniteScroll&&(this._infiniteScroll.complete(),this._setItems(this.items))}search(e){this._isEnabled&&this._isOpened&&this.canSearch&&(this._searchText=e,this._setHasSearchText(),this._filterItems())}showLoading(){this._isEnabled&&(this._isSearching=!0)}hideLoading(){this._isEnabled&&(this._isSearching=!1)}showAddItemTemplate(){this._toggleAddItemTemplate(!0)}hideAddItemTemplate(){this._toggleAddItemTemplate(!1)}}IonicSelectableComponent.decorators=[{type:Component,args:[{selector:"ionic-selectable",template:'<div class="ionic-selectable-value">\n <div *ngIf="valueTemplate && _valueItems.length && isMultiple"\n [ngTemplateOutlet]="valueTemplate"\n [ngTemplateOutletContext]="{ value: _valueItems }">\n </div>\n <div class="ionic-selectable-value-item"\n *ngIf="valueTemplate && _valueItems.length && !isMultiple">\n <div [ngTemplateOutlet]="valueTemplate"\n [ngTemplateOutletContext]="{ value: _valueItems[0] }">\n </div>\n </div>\n <span *ngIf="!valueTemplate && _valueItems.length">\n <div class="ionic-selectable-value-item"\n *ngFor="let valueItem of _valueItems">\n {{_formatValueItem(valueItem)}}\n </div>\n </span>\n <div *ngIf="_hasPlaceholder && placeholderTemplate"\n class="ionic-selectable-value-item">\n <div [ngTemplateOutlet]="placeholderTemplate">\n </div>\n </div>\n <div class="ionic-selectable-value-item"\n *ngIf="_hasPlaceholder && !placeholderTemplate">\n {{placeholder}}\n </div>\n</div>\n<div class="ionic-selectable-icon">\n <div class="ionic-selectable-icon-inner"></div>\n</div>\n<button aria-haspopup="true" ion-button="item-cover" class="item-cover"\n [disabled]="!isEnabled">\n</button>\n',providers:[{provide:NG_VALUE_ACCESSOR,useExisting:forwardRef(()=>IonicSelectableComponent),multi:!0}]}]}],IonicSelectableComponent.ctorParameters=(()=>[{type:ModalController},{type:Form},{type:Platform},{type:Item,decorators:[{type:Optional}]},{type:IterableDiffers},{type:ElementRef}]),IonicSelectableComponent.propDecorators={_cssClass:[{type:HostBinding,args:["class.ionic-selectable"]}],_isIos:[{type:HostBinding,args:["class.ionic-selectable-ios"]}],_isMD:[{type:HostBinding,args:["class.ionic-selectable-md"]}],_isMultipleCssClass:[{type:HostBinding,args:["class.ionic-selectable-is-multiple"]}],_hasValueCssClass:[{type:HostBinding,args:["class.ionic-selectable-has-value"]}],_hasPlaceholderCssClass:[{type:HostBinding,args:["class.ionic-selectable-has-placeholder"]}],items:[{type:Input}],itemsChange:[{type:Output}],isEnabled:[{type:HostBinding,args:["class.ionic-selectable-is-enabled"]},{type:Input,args:["isEnabled"]}],shouldBackdropClose:[{type:Input,args:["shouldBackdropClose"]}],modalCssClass:[{type:Input}],modalEnterAnimation:[{type:Input}],modalLeaveAnimation:[{type:Input}],isConfirmButtonEnabled:[{type:Input,args:["isConfirmButtonEnabled"]}],hasConfirmButton:[{type:Input,args:["hasConfirmButton"]}],itemValueField:[{type:Input}],itemTextField:[{type:Input}],groupValueField:[{type:Input}],groupTextField:[{type:Input}],canSearch:[{type:Input}],isOnSearchEnabled:[{type:Input,args:["isOnSearchEnabled"]}],canClear:[{type:HostBinding,args:["class.ionic-selectable-can-clear"]},{type:Input,args:["canClear"]}],hasInfiniteScroll:[{type:Input}],hasVirtualScroll:[{type:Input}],virtualScrollApproxItemHeight:[{type:Input}],virtualScrollApproxItemWidth:[{type:Input}],virtualScrollBufferRatio:[{type:Input}],virtualScrollHeaderFn:[{type:Input}],searchPlaceholder:[{type:Input}],placeholder:[{type:Input}],isMultiple:[{type:Input,args:["isMultiple"]}],searchFailText:[{type:Input}],clearButtonText:[{type:Input}],addButtonText:[{type:Input}],confirmButtonText:[{type:Input}],closeButtonText:[{type:Input}],focusSearchbar:[{type:Input}],headerColor:[{type:Input}],groupColor:[{type:Input}],onChange:[{type:Output}],onSearch:[{type:Output}],onSearchFail:[{type:Output}],onSearchSuccess:[{type:Output}],onInfiniteScroll:[{type:Output}],onOpen:[{type:Output}],onClose:[{type:Output}],onSelect:[{type:Output}],onClear:[{type:Output}],valueTemplate:[{type:ContentChild,args:[IonicSelectableValueTemplateDirective,{read:TemplateRef}]}],itemTemplate:[{type:ContentChild,args:[IonicSelectableItemTemplateDirective,{read:TemplateRef}]}],itemEndTemplate:[{type:ContentChild,args:[IonicSelectableItemEndTemplateDirective,{read:TemplateRef}]}],titleTemplate:[{type:ContentChild,args:[IonicSelectableTitleTemplateDirective,{read:TemplateRef}]}],placeholderTemplate:[{type:ContentChild,args:[IonicSelectablePlaceholderTemplateDirective,{read:TemplateRef}]}],messageTemplate:[{type:ContentChild,args:[IonicSelectableMessageTemplateDirective,{read:TemplateRef}]}],groupTemplate:[{type:ContentChild,args:[IonicSelectableGroupTemplateDirective,{read:TemplateRef}]}],groupEndTemplate:[{type:ContentChild,args:[IonicSelectableGroupEndTemplateDirective,{read:TemplateRef}]}],closeButtonTemplate:[{type:ContentChild,args:[IonicSelectableCloseButtonTemplateDirective,{read:TemplateRef}]}],searchFailTemplate:[{type:ContentChild,args:[IonicSelectableSearchFailTemplateDirective,{read:TemplateRef}]}],addItemTemplate:[{type:ContentChild,args:[IonicSelectableAddItemTemplateDirective,{read:TemplateRef}]}],footerTemplate:[{type:ContentChild,args:[IonicSelectableFooterTemplateDirective,{read:TemplateRef}]}],headerTemplate:[{type:ContentChild,args:[IonicSelectableHeaderTemplateDirective,{read:TemplateRef}]}],itemIconTemplate:[{type:ContentChild,args:[IonicSelectableItemIconTemplateDirective,{read:TemplateRef}]}],searchDebounce:[{type:Input}],disabledItems:[{type:Input}],shouldStoreItemValue:[{type:Input}],canSaveItem:[{type:Input}],canDeleteItem:[{type:Input}],canAddItem:[{type:Input,args:["canAddItem"]}],onSaveItem:[{type:Output}],onDeleteItem:[{type:Output}],onAddItem:[{type:Output}],_click:[{type:HostListener,args:["click",["$event"]]}]};class IonicSelectableModalComponent{constructor(e,t){this.navParams=e,this._element=t,this._cssClass=!0,this.selectComponent=this.navParams.get("selectComponent"),this.selectComponent._modalComponent=this,this.selectComponent._selectedItems=[],this.selectComponent._isNullOrWhiteSpace(this.selectComponent.value)||(this.selectComponent.isMultiple?this.selectComponent.value.forEach(e=>{this.selectComponent._selectedItems.push(e)}):this.selectComponent._selectedItems.push(this.selectComponent.value)),this.selectComponent._setItemsToConfirm(this.selectComponent._selectedItems)}get _canClearCssClass(){return this.selectComponent.canClear}get _isMultipleCssClass(){return this.selectComponent.isMultiple}get _isSearchingCssClass(){return this.selectComponent._isSearching}get _isAddItemTemplateVisibleCssClass(){return this.selectComponent._isAddItemTemplateVisible}get _isIos(){return this.selectComponent._isIos}_isMD(){return this.selectComponent._isMD}ngAfterViewInit(){this._header=this._element.nativeElement.querySelector("ion-header"),this._searchbarComponent&&this.selectComponent.focusSearchbar&&setTimeout(()=>{this._searchbarComponent.setFocus()},500)}}IonicSelectableModalComponent.decorators=[{type:Component,args:[{selector:"ionic-selectable-modal",template:'<ion-header>\n <ion-navbar *ngIf="!selectComponent.headerTemplate"\n [color]="selectComponent.headerColor ? selectComponent.headerColor : null">\n <ion-title>\n \x3c!-- Use span for titleTemplate to preserve Ionic ellipsis styles. --\x3e\n <span *ngIf="selectComponent.titleTemplate"\n [ngTemplateOutlet]="selectComponent.titleTemplate">\n </span>\n <span *ngIf="!selectComponent.titleTemplate">\n {{selectComponent.label}}\n </span>\n </ion-title>\n <ion-buttons start>\n <button ion-button (click)="selectComponent._close()">\n <span *ngIf="selectComponent.closeButtonTemplate"\n [ngTemplateOutlet]="selectComponent.closeButtonTemplate">\n </span>\n <span *ngIf="!selectComponent.closeButtonTemplate" ion-text\n showWhen="ios">\n {{selectComponent.closeButtonText}}\n </span>\n <ion-icon *ngIf="!selectComponent.closeButtonTemplate" name="md-close"\n hideWhen="ios">\n </ion-icon>\n </button>\n </ion-buttons>\n </ion-navbar>\n <div *ngIf="selectComponent.headerTemplate"\n [ngTemplateOutlet]="selectComponent.headerTemplate">\n </div>\n <ion-toolbar>\n <ion-searchbar #searchbarComponent\n [(ngModel)]="selectComponent._searchText"\n (ionInput)="selectComponent._filterItems()"\n [placeholder]="selectComponent.searchPlaceholder"\n [debounce]="selectComponent.searchDebounce">\n </ion-searchbar>\n <div class="ionic-selectable-message"\n *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\n <button ion-item detail-none\n *ngIf="selectComponent._searchText"\n (click)="selectComponent._select(selectComponent._searchText)"\n class="ionic-selectable-item searchTextItem"\n [ngClass]="{ \'ionic-selectable-item-is-selected\': selectComponent._isItemSelected(selectComponent._searchText) }">\n <span *ngIf="!selectComponent.itemTemplate">\n Add new symptom\n </span>\n <ion-icon class="addCustomItemIcon" name="md-add"></ion-icon>\n </button>\n <ion-list no-margin\n *ngIf="!selectComponent.hasVirtualScroll && selectComponent._hasFilteredItems">\n <ion-item-group *ngFor="let group of selectComponent._filteredGroups"\n class="ionic-selectable-group">\n <ion-item-divider *ngIf="selectComponent._hasGroups"\n [color]="selectComponent.groupColor ? selectComponent.groupColor : null">\n \x3c!-- Use span for groupTemplate to preserve Ionic ellipsis styles. --\x3e\n <span *ngIf="selectComponent.groupTemplate"\n [ngTemplateOutlet]="selectComponent.groupTemplate"\n [ngTemplateOutletContext]="{ group: group }">\n </span>\n <span *ngIf="!selectComponent.groupTemplate">\n {{group.text}}\n </span>\n <div *ngIf="selectComponent.groupEndTemplate" item-right>\n <div [ngTemplateOutlet]="selectComponent.groupEndTemplate"\n [ngTemplateOutletContext]="{ group: group }">\n </div>\n </div>\n </ion-item-divider>\n <button ion-item detail-none *ngFor="let item of group.items"\n (click)="selectComponent._select(item)" class="ionic-selectable-item"\n [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 \x3c!-- Use span for itemTemplate to preserve Ionic ellipsis styles. --\x3e\n <span *ngIf="selectComponent.itemTemplate"\n [ngTemplateOutlet]="selectComponent.itemTemplate"\n [ngTemplateOutletContext]="{ item: item, isItemSelected: selectComponent._isItemSelected(item) }">\n </span>\n <span *ngIf="!selectComponent.itemTemplate">\n {{selectComponent._formatItem(item)}}\n </span>\n <div *ngIf="selectComponent.itemEndTemplate" item-right>\n <div [ngTemplateOutlet]="selectComponent.itemEndTemplate"\n [ngTemplateOutletContext]="{ item: item, isItemSelected: selectComponent._isItemSelected(item) }">\n </div>\n </div>\n <span *ngIf="selectComponent.itemIconTemplate" item-left\n class="ionic-selectable-item-icon-template"\n [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\' : \'daek\'"\n item-left>\n </ion-icon>\n <button *ngIf="selectComponent.canSaveItem"\n class="ionic-selectable-item-button" ion-button icon-only item-end\n outline (click)="selectComponent._saveItem($event, item)">\n <ion-icon name="md-create"></ion-icon>\n </button>\n <button *ngIf="selectComponent.canDeleteItem"\n class="ionic-selectable-item-button" ion-button icon-only item-end\n outline (click)="selectComponent._deleteItemClick($event, item)">\n <ion-icon name="md-trash"></ion-icon>\n </button>\n </button>\n </ion-item-group>\n </ion-list>\n \x3c!-- Fail text should be above InfiniteScroll to avoid a gap when no items are found. --\x3e\n <div *ngIf="!selectComponent._hasFilteredItems">\n <span *ngIf="selectComponent.searchFailTemplate"\n [ngTemplateOutlet]="selectComponent.searchFailTemplate">\n </span>\n <div *ngIf="!selectComponent.searchFailTemplate" margin>\n {{selectComponent.searchFailText}}\n </div>\n </div>\n <ion-infinite-scroll *ngIf="!selectComponent.hasVirtualScroll"\n [enabled]="selectComponent.hasInfiniteScroll"\n (ionInfinite)="selectComponent._getMoreItems($event)">\n <ion-infinite-scroll-content></ion-infinite-scroll-content>\n </ion-infinite-scroll>\n <ion-list no-margin\n *ngIf="selectComponent.hasVirtualScroll && selectComponent._hasFilteredItems"\n [virtualScroll]="selectComponent._filteredGroups[0].items"\n [approxItemHeight]="selectComponent.virtualScrollApproxItemHeight"\n [approxItemWidth]="selectComponent.virtualScrollApproxItemWidth"\n [bufferRatio]="selectComponent.virtualScrollBufferRatio"\n [headerFn]="selectComponent.virtualScrollHeaderFn">\n <ion-item-divider *virtualHeader="let header"\n [color]="selectComponent.groupColor ? selectComponent.groupColor : null">\n {{header}}\n </ion-item-divider>\n <button ion-item detail-none *virtualItem="let item"\n (click)="selectComponent._select(item)" class="ionic-selectable-item"\n [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 \x3c!-- Use span for itemTemplate to preserve Ionic ellipsis styles. --\x3e\n <span *ngIf="selectComponent.itemTemplate"\n [ngTemplateOutlet]="selectComponent.itemTemplate"\n [ngTemplateOutletContext]="{ item: item, isItemSelected: selectComponent._isItemSelected(item) }">\n </span>\n <span *ngIf="!selectComponent.itemTemplate">\n {{selectComponent._formatItem(item)}}\n </span>\n <div *ngIf="selectComponent.itemEndTemplate" item-right>\n <div [ngTemplateOutlet]="selectComponent.itemEndTemplate"\n [ngTemplateOutletContext]="{ item: item, isItemSelected: selectComponent._isItemSelected(item) }">\n </div>\n </div>\n <span *ngIf="selectComponent.itemIconTemplate" item-left\n class="ionic-selectable-item-icon-template"\n [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\' : \'daek\'"\n item-left>\n </ion-icon>\n <button *ngIf="selectComponent.canSaveItem"\n class="ionic-selectable-item-button" ion-button icon-only item-end\n outline (click)="selectComponent._saveItem($event, item)">\n <ion-icon name="md-create"></ion-icon>\n </button>\n <button *ngIf="selectComponent.canDeleteItem"\n class="ionic-selectable-item-button" ion-button icon-only item-end\n outline (click)="selectComponent._deleteItemClick($event, item)">\n <ion-icon name="md-trash"></ion-icon>\n </button>\n </button>\n </ion-list>\n</ion-content>\n<div class="ionic-selectable-add-item-template"\n *ngIf="selectComponent._isAddItemTemplateVisible"\n [ngStyle]="{ \'top.px\': _header.offsetHeight }">\n <span [ngTemplateOutlet]="selectComponent.addItemTemplate"\n [ngTemplateOutletContext]="{ item: selectComponent._itemToAdd, isAdd: selectComponent._itemToAdd === null }">\n </span>\n</div>\n<ion-footer\n *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 <button ion-button full no-margin (click)="selectComponent._clear()"\n [disabled]="!selectComponent._selectedItems.length">\n {{selectComponent.clearButtonText}}\n </button>\n </ion-col>\n <ion-col *ngIf="selectComponent.canAddItem">\n <button ion-button full no-margin\n (click)="selectComponent._addItemClick()">\n {{selectComponent.addButtonText}}\n </button>\n </ion-col>\n <ion-col\n *ngIf="selectComponent.isMultiple || selectComponent.hasConfirmButton">\n <button ion-button full no-margin (click)="selectComponent._confirm()"\n [disabled]="!selectComponent.isConfirmButtonEnabled">\n {{selectComponent.confirmButtonText}}\n </button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n <div *ngIf="selectComponent.footerTemplate"\n [ngTemplateOutlet]="selectComponent.footerTemplate">\n </div>\n</ion-footer>\n'}]}],IonicSelectableModalComponent.ctorParameters=(()=>[{type:NavParams},{type:ElementRef}]),IonicSelectableModalComponent.propDecorators={_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"]}],_isAddItemTemplateVisibleCssClass:[{type:HostBinding,args:["class.ionic-selectable-modal-is-add-item-template-visible"]}],_isIos:[{type:HostBinding,args:["class.ionic-selectable-modal-ios"]}],_isMD:[{type:HostBinding,args:["class.ionic-selectable-modal-md"]}],_searchbarComponent:[{type:ViewChild,args:["searchbarComponent"]}],_content:[{type:ViewChild,args:[Content]}]};const components=[IonicSelectableComponent,IonicSelectableModalComponent],directives=[IonicSelectableValueTemplateDirective,IonicSelectableItemTemplateDirective,IonicSelectableItemEndTemplateDirective,IonicSelectableTitleTemplateDirective,IonicSelectablePlaceholderTemplateDirective,IonicSelectableMessageTemplateDirective,IonicSelectableGroupTemplateDirective,IonicSelectableGroupEndTemplateDirective,IonicSelectableCloseButtonTemplateDirective,IonicSelectableSearchFailTemplateDirective,IonicSelectableAddItemTemplateDirective,IonicSelectableFooterTemplateDirective,IonicSelectableHeaderTemplateDirective,IonicSelectableItemIconTemplateDirective];class IonicSelectableModule{}IonicSelectableModule.decorators=[{type:NgModule,args:[{imports:[CommonModule,IonicPageModule.forChild(IonicSelectableComponent),IonicPageModule.forChild(IonicSelectableModalComponent)],declarations:[...components,...directives],exports:[...components,...directives],entryComponents:components}]}],IonicSelectableModule.ctorParameters=(()=>[]);export{IonicSelectableAddItemTemplateDirective,IonicSelectableCloseButtonTemplateDirective,IonicSelectableFooterTemplateDirective,IonicSelectableGroupEndTemplateDirective,IonicSelectableGroupTemplateDirective,IonicSelectableHeaderTemplateDirective,IonicSelectableItemEndTemplateDirective,IonicSelectableItemIconTemplateDirective,IonicSelectableItemTemplateDirective,IonicSelectableMessageTemplateDirective,IonicSelectableModalComponent,IonicSelectablePlaceholderTemplateDirective,IonicSelectableSearchFailTemplateDirective,IonicSelectableTitleTemplateDirective,IonicSelectableValueTemplateDirective,IonicSelectableComponent,IonicSelectableModule};