From 1ecfcd190295ac523bb99e6070a6a99bd19f4827 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Tue, 26 Mar 2019 11:29:24 -0400 Subject: [PATCH] fix(select): fix options being added async while overlay is open (#17860) fixes #15716 fixes #17851 --- core/src/components/select/select.tsx | 120 ++++++++++++------ .../components/select/test/async/index.html | 41 +++--- 2 files changed, 104 insertions(+), 57 deletions(-) diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index dcb614dd5c..ce1b3d59f3 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -1,6 +1,6 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Method, Prop, State, Watch } from '@stencil/core'; -import { ActionSheetButton, ActionSheetOptions, AlertOptions, CssClassMap, Mode, OverlaySelect, PopoverOptions, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, StyleEventDetail } from '../../interface'; +import { ActionSheetButton, ActionSheetOptions, AlertInput, AlertOptions, CssClassMap, Mode, OverlaySelect, PopoverOptions, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, StyleEventDetail } from '../../interface'; import { findItemLabel, renderHiddenInput } from '../../utils/helpers'; import { hostContext } from '../../utils/theme'; @@ -143,6 +143,8 @@ export class Select implements ComponentInterface { if (this.didInit) { this.updateOptions(); + this.updateOverlayOptions(); + this.emitStyle(); /** * In the event that options @@ -227,40 +229,29 @@ export class Select implements ComponentInterface { return this.openAlert(); } - private async openPopover(ev: UIEvent) { - const interfaceOptions = this.interfaceOptions; + private updateOverlayOptions(): void { + if (!this.overlay) { return; } + const overlay = (this.overlay as any); - const popoverOpts: PopoverOptions = { - mode: this.mode, - ...interfaceOptions, - - component: 'ion-select-popover', - cssClass: ['select-popover', interfaceOptions.cssClass], - event: ev, - componentProps: { - header: interfaceOptions.header, - subHeader: interfaceOptions.subHeader, - message: interfaceOptions.message, - value: this.value, - options: this.childOpts.map(o => { - return { - text: o.textContent, - value: o.value, - checked: o.selected, - disabled: o.disabled, - handler: () => { - this.value = o.value; - this.close(); - } - } as SelectPopoverOption; - }) - } - }; - return this.popoverCtrl.create(popoverOpts); + switch (this.interface) { + case 'action-sheet': + overlay.buttons = this.createActionSheetButtons(this.childOpts); + break; + case 'popover': + const popover = overlay.querySelector('ion-select-popover'); + if (popover) { + popover.options = this.createPopoverOptions(this.childOpts); + } + break; + default: + const inputType = (this.multiple ? 'checkbox' : 'radio'); + overlay.inputs = this.createAlertInputs(this.childOpts, inputType); + break; + } } - private async openActionSheet() { - const actionSheetButtons = this.childOpts.map(option => { + private createActionSheetButtons(data: any[]): ActionSheetButton[] { + const actionSheetButtons = data.map(option => { return { role: (option.selected ? 'selected' : ''), text: option.textContent, @@ -279,12 +270,65 @@ export class Select implements ComponentInterface { } }); + return actionSheetButtons; + } + + private createAlertInputs(data: any[], inputType: string): AlertInput[] { + return data.map(o => { + return { + type: inputType, + label: o.textContent, + value: o.value, + checked: o.selected, + disabled: o.disabled + } as AlertInput; + }); + } + + private createPopoverOptions(data: any[]): SelectPopoverOption[] { + return data.map(o => { + return { + text: o.textContent, + value: o.value, + checked: o.selected, + disabled: o.disabled, + handler: () => { + this.value = o.value; + this.close(); + } + } as SelectPopoverOption; + }); + } + + private async openPopover(ev: UIEvent) { + const interfaceOptions = this.interfaceOptions; + + const popoverOpts: PopoverOptions = { + mode: this.mode, + ...interfaceOptions, + + component: 'ion-select-popover', + cssClass: ['select-popover', interfaceOptions.cssClass], + event: ev, + componentProps: { + header: interfaceOptions.header, + subHeader: interfaceOptions.subHeader, + message: interfaceOptions.message, + value: this.value, + options: this.createPopoverOptions(this.childOpts) + } + }; + return this.popoverCtrl.create(popoverOpts); + } + + private async openActionSheet() { + const interfaceOptions = this.interfaceOptions; const actionSheetOpts: ActionSheetOptions = { mode: this.mode, ...interfaceOptions, - buttons: actionSheetButtons, + buttons: this.createActionSheetButtons(this.childOpts), cssClass: ['select-action-sheet', interfaceOptions.cssClass] }; return this.actionSheetCtrl.create(actionSheetOpts); @@ -302,15 +346,7 @@ export class Select implements ComponentInterface { ...interfaceOptions, header: interfaceOptions.header ? interfaceOptions.header : labelText, - inputs: this.childOpts.map(o => { - return { - type: inputType, - label: o.textContent, - value: o.value, - checked: o.selected, - disabled: o.disabled - }; - }), + inputs: this.createAlertInputs(this.childOpts, inputType), buttons: [ { text: this.cancelText, diff --git a/core/src/components/select/test/async/index.html b/core/src/components/select/test/async/index.html index 1c28d31088..998fc71156 100644 --- a/core/src/components/select/test/async/index.html +++ b/core/src/components/select/test/async/index.html @@ -12,26 +12,37 @@ - + + + + + Label w/o Placeholder + + + + + Label with Placeholder + +