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
This commit is contained in:
Brandy Carney
2019-10-30 13:25:11 -04:00
committed by GitHub
parent 67a7e232b9
commit 7988720b1c
2 changed files with 42 additions and 19 deletions

View File

@ -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;
if (shouldDismiss) {
return this.dismiss();
private async buttonClick(button: PickerButton) {
const role = button.role;
if (isCancel(role)) {
return this.dismiss(undefined, role);
}
return Promise.resolve(false);
const shouldDismiss = await this.callButtonHandler(button);
if (shouldDismiss) {
return this.dismiss(this.getSelected(), button.role);
}
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}
>
<ion-backdrop
visible={this.showBackdrop}

View File

@ -48,6 +48,10 @@
const pickerController = document.querySelector('ion-picker-controller');
const pickerElement = await pickerController.create({
buttons: [{
text: 'Cancel',
role: 'cancel',
handler: () => 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);
}
</script>
</body>