mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 11:17:19 +08:00
fix(select): fix options being added async while overlay is open (#17860)
fixes #15716 fixes #17851
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Method, Prop, State, Watch } from '@stencil/core';
|
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 { findItemLabel, renderHiddenInput } from '../../utils/helpers';
|
||||||
import { hostContext } from '../../utils/theme';
|
import { hostContext } from '../../utils/theme';
|
||||||
|
|
||||||
@ -143,6 +143,8 @@ export class Select implements ComponentInterface {
|
|||||||
|
|
||||||
if (this.didInit) {
|
if (this.didInit) {
|
||||||
this.updateOptions();
|
this.updateOptions();
|
||||||
|
this.updateOverlayOptions();
|
||||||
|
this.emitStyle();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In the event that options
|
* In the event that options
|
||||||
@ -227,40 +229,29 @@ export class Select implements ComponentInterface {
|
|||||||
return this.openAlert();
|
return this.openAlert();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async openPopover(ev: UIEvent) {
|
private updateOverlayOptions(): void {
|
||||||
const interfaceOptions = this.interfaceOptions;
|
if (!this.overlay) { return; }
|
||||||
|
const overlay = (this.overlay as any);
|
||||||
|
|
||||||
const popoverOpts: PopoverOptions = {
|
switch (this.interface) {
|
||||||
mode: this.mode,
|
case 'action-sheet':
|
||||||
...interfaceOptions,
|
overlay.buttons = this.createActionSheetButtons(this.childOpts);
|
||||||
|
break;
|
||||||
component: 'ion-select-popover',
|
case 'popover':
|
||||||
cssClass: ['select-popover', interfaceOptions.cssClass],
|
const popover = overlay.querySelector('ion-select-popover');
|
||||||
event: ev,
|
if (popover) {
|
||||||
componentProps: {
|
popover.options = this.createPopoverOptions(this.childOpts);
|
||||||
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;
|
break;
|
||||||
})
|
default:
|
||||||
|
const inputType = (this.multiple ? 'checkbox' : 'radio');
|
||||||
|
overlay.inputs = this.createAlertInputs(this.childOpts, inputType);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
return this.popoverCtrl.create(popoverOpts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async openActionSheet() {
|
private createActionSheetButtons(data: any[]): ActionSheetButton[] {
|
||||||
const actionSheetButtons = this.childOpts.map(option => {
|
const actionSheetButtons = data.map(option => {
|
||||||
return {
|
return {
|
||||||
role: (option.selected ? 'selected' : ''),
|
role: (option.selected ? 'selected' : ''),
|
||||||
text: option.textContent,
|
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 interfaceOptions = this.interfaceOptions;
|
||||||
const actionSheetOpts: ActionSheetOptions = {
|
const actionSheetOpts: ActionSheetOptions = {
|
||||||
mode: this.mode,
|
mode: this.mode,
|
||||||
...interfaceOptions,
|
...interfaceOptions,
|
||||||
|
|
||||||
buttons: actionSheetButtons,
|
buttons: this.createActionSheetButtons(this.childOpts),
|
||||||
cssClass: ['select-action-sheet', interfaceOptions.cssClass]
|
cssClass: ['select-action-sheet', interfaceOptions.cssClass]
|
||||||
};
|
};
|
||||||
return this.actionSheetCtrl.create(actionSheetOpts);
|
return this.actionSheetCtrl.create(actionSheetOpts);
|
||||||
@ -302,15 +346,7 @@ export class Select implements ComponentInterface {
|
|||||||
...interfaceOptions,
|
...interfaceOptions,
|
||||||
|
|
||||||
header: interfaceOptions.header ? interfaceOptions.header : labelText,
|
header: interfaceOptions.header ? interfaceOptions.header : labelText,
|
||||||
inputs: this.childOpts.map(o => {
|
inputs: this.createAlertInputs(this.childOpts, inputType),
|
||||||
return {
|
|
||||||
type: inputType,
|
|
||||||
label: o.textContent,
|
|
||||||
value: o.value,
|
|
||||||
checked: o.selected,
|
|
||||||
disabled: o.disabled
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
text: this.cancelText,
|
text: this.cancelText,
|
||||||
|
@ -12,14 +12,25 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<ion-select id="animals" placeholder="Select One"></ion-select>
|
<ion-select id="default" placeholder="Default"></ion-select>
|
||||||
|
<ion-select id="popover" interface="popover" placeholder="Popover"></ion-select>
|
||||||
|
<ion-select id="actionSheet" interface="action-sheet" placeholder="Action Sheet"></ion-select>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-label position="floating">Label w/o Placeholder</ion-label>
|
||||||
|
<ion-select id="actionSheet" interface="action-sheet"></ion-select>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-label position="floating">Label with Placeholder</ion-label>
|
||||||
|
<ion-select id="actionSheet" interface="action-sheet" placeholder="A Placeholder"></ion-select>
|
||||||
|
</ion-item>
|
||||||
<script>
|
<script>
|
||||||
let select = document.getElementById('animals');
|
let selects = document.querySelectorAll('ion-select');
|
||||||
const options = ['bird', 'dog', 'shark', 'lizard'];
|
const options = ['bird', 'dog', 'shark', 'lizard'];
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
selects.forEach(select => {
|
||||||
options.forEach(option => {
|
options.forEach(option => {
|
||||||
let o = document.createElement('ion-select-option');
|
let o = document.createElement('ion-select-option');
|
||||||
o.value = option;
|
o.value = option;
|
||||||
@ -29,8 +40,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
select.value = options[0];
|
select.value = options[0];
|
||||||
|
});
|
||||||
}, 500);
|
}, 5000);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
Reference in New Issue
Block a user