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 { getIonMode } from '../../global/ionic-global';
import { Animation, AnimationBuilder, CssClassMap, OverlayEventDetail, OverlayInterface, PickerButton, PickerColumn } from '../../interface'; 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 { getClassMap } from '../../utils/theme';
import { iosEnterAnimation } from './animations/ios.enter'; 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)); return Promise.resolve(this.columns.find(column => column.name === name));
} }
private buttonClick(button: PickerButton) { private async buttonClick(button: PickerButton) {
// if (this.disabled) { const role = button.role;
// return; if (isCancel(role)) {
// } return this.dismiss(undefined, role);
// 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();
} }
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() { private getSelected() {
@ -194,11 +204,14 @@ export class Picker implements ComponentInterface, OverlayInterface {
} }
private onBackdropTap = () => { private onBackdropTap = () => {
const cancelBtn = this.buttons.find(b => b.role === 'cancel'); this.dismiss(undefined, BACKDROP);
if (cancelBtn) { }
this.buttonClick(cancelBtn);
} else { private dispatchCancelHandler = (ev: CustomEvent) => {
this.dismiss(); 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}` zIndex: `${20000 + this.overlayIndex}`
}} }}
onIonBackdropTap={this.onBackdropTap} onIonBackdropTap={this.onBackdropTap}
onIonPickerWillDismiss={this.dispatchCancelHandler}
> >
<ion-backdrop <ion-backdrop
visible={this.showBackdrop} visible={this.showBackdrop}

View File

@ -48,6 +48,10 @@
const pickerController = document.querySelector('ion-picker-controller'); const pickerController = document.querySelector('ion-picker-controller');
const pickerElement = await pickerController.create({ const pickerElement = await pickerController.create({
buttons: [{ buttons: [{
text: 'Cancel',
role: 'cancel',
handler: () => console.log('Clicked Cancel!')
}, {
text: 'Save', text: 'Save',
handler: () => console.log('Clicked Save!') handler: () => console.log('Clicked Save!')
}, { }, {
@ -112,7 +116,12 @@
}], }],
cssClass: customClass cssClass: customClass
}); });
return await pickerElement.present();
await pickerElement.present();
const { data, role } = await pickerElement.onDidDismiss();
console.log('Picker dismissed!', data, role);
} }
</script> </script>
</body> </body>