From b15a679132eddd8fdf8c620a980b204bfdde836d Mon Sep 17 00:00:00 2001 From: Brandy Carney Date: Wed, 30 Oct 2019 13:25:11 -0400 Subject: [PATCH] fix(picker): pass data and role to the dismiss based on button click or backdrop (#19787) - Pass the button role on dismiss of the picker (on button click or backdrop tap) - Pass the selected values in the data on dismiss ONLY if the dismiss role is not "cancel" or "backdrop" - Call the cancel handler when dismissing if the role is "cancel" or "backdrop" Fixes #18454 --- core/src/components/picker/picker.tsx | 48 ++++++++++++------- .../components/picker/test/basic/index.html | 11 ++++- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/core/src/components/picker/picker.tsx b/core/src/components/picker/picker.tsx index 0f1c69bf1d5..0665a6cbab4 100644 --- a/core/src/components/picker/picker.tsx +++ b/core/src/components/picker/picker.tsx @@ -2,7 +2,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Meth import { getIonMode } from '../../global/ionic-global'; import { Animation, AnimationBuilder, CssClassMap, OverlayEventDetail, OverlayInterface, PickerButton, PickerColumn } from '../../interface'; -import { dismiss, eventMethod, prepareOverlay, present, safeCall } from '../../utils/overlays'; +import { BACKDROP, dismiss, eventMethod, isCancel, prepareOverlay, present, safeCall } from '../../utils/overlays'; import { getClassMap } from '../../utils/theme'; import { iosEnterAnimation } from './animations/ios.enter'; @@ -163,19 +163,29 @@ export class Picker implements ComponentInterface, OverlayInterface { return Promise.resolve(this.columns.find(column => column.name === name)); } - private buttonClick(button: PickerButton) { - // if (this.disabled) { - // return; - // } - - // keep the time of the most recent button click - // a handler has been provided, execute it - // pass the handler the values from the inputs - const shouldDismiss = safeCall(button.handler, this.getSelected()) !== false; + private async buttonClick(button: PickerButton) { + const role = button.role; + if (isCancel(role)) { + return this.dismiss(undefined, role); + } + const shouldDismiss = await this.callButtonHandler(button); if (shouldDismiss) { - return this.dismiss(); + return this.dismiss(this.getSelected(), button.role); } - return Promise.resolve(false); + return Promise.resolve(); + } + + private async callButtonHandler(button: PickerButton | undefined) { + if (button) { + // a handler has been provided, execute it + // pass the handler the values from the inputs + const rtn = await safeCall(button.handler); + if (rtn === false) { + // if the return value of the handler is false then do not dismiss + return false; + } + } + return true; } private getSelected() { @@ -194,11 +204,14 @@ export class Picker implements ComponentInterface, OverlayInterface { } private onBackdropTap = () => { - const cancelBtn = this.buttons.find(b => b.role === 'cancel'); - if (cancelBtn) { - this.buttonClick(cancelBtn); - } else { - this.dismiss(); + this.dismiss(undefined, BACKDROP); + } + + private dispatchCancelHandler = (ev: CustomEvent) => { + const role = ev.detail.role; + if (isCancel(role)) { + const cancelButton = this.buttons.find(b => b.role === 'cancel'); + this.callButtonHandler(cancelButton); } } @@ -219,6 +232,7 @@ export class Picker implements ComponentInterface, OverlayInterface { zIndex: `${20000 + this.overlayIndex}` }} onIonBackdropTap={this.onBackdropTap} + onIonPickerWillDismiss={this.dispatchCancelHandler} > console.log('Clicked Cancel!') + }, { text: 'Save', handler: () => console.log('Clicked Save!') }, { @@ -112,7 +116,12 @@ }], cssClass: customClass }); - return await pickerElement.present(); + + await pickerElement.present(); + + const { data, role } = await pickerElement.onDidDismiss(); + + console.log('Picker dismissed!', data, role); }