fix(select): set the proper values for select for all interfaces

This commit is contained in:
Brandy Carney
2017-09-01 18:50:19 -04:00
parent f1ac5304d6
commit de24003f35
5 changed files with 115 additions and 71 deletions

View File

@ -20,7 +20,7 @@ export class SelectOption {
/** /**
* @input {boolean} If true, the element is selected. * @input {boolean} If true, the element is selected.
*/ */
@Prop() selected: boolean = false; @Prop({state: true}) selected: boolean = false;
/** /**
* @input {string} The text value of the option. * @input {string} The text value of the option.

View File

@ -1,5 +1,7 @@
import { Component, Prop, PropDidChange } from '@stencil/core'; import { Component, Event, EventEmitter, Listen, Prop, PropDidChange } from '@stencil/core';
import { createThemedClasses } from '../../utils/theme';
export interface SelectPopoverOption { export interface SelectPopoverOption {
text: string; text: string;
@ -10,16 +12,24 @@ export interface SelectPopoverOption {
} }
@Component({ @Component({
tag: 'ion-select-popover' tag: 'ion-select-popover',
}) host: {
theme: 'select-popover'
}}
)
export class SelectPopover { export class SelectPopover {
mode: string;
color: string;
@Event() ionDismiss: EventEmitter;
@Prop() options: SelectPopoverOption[]; @Prop() options: SelectPopoverOption[];
@Prop({ mutable: true }) value: string; @Prop({ mutable: true }) value: string;
@PropDidChange('value') @Listen('ionChange')
valueChanged(val: string) { onChange(ev: CustomEvent) {
console.log('Select popover value', val); this.value = ev.detail.value;
} }
// public get value() { // public get value() {
@ -28,25 +38,36 @@ export class SelectPopover {
// return checkedOption ? checkedOption.value : undefined; // return checkedOption ? checkedOption.value : undefined;
// } // }
// public set value(value: any) { dismiss(value: any) {
// let checkedOption = this.options.find(option => option.value === value); this.ionDismiss.emit(value);
// if (checkedOption && checkedOption.handler) { }
// checkedOption.handler();
// } @PropDidChange('value')
// this.viewController.dismiss(value); valueChanged(value: string) {
// } let checkedOption = this.options.find(option => option.value === value);
if (checkedOption && checkedOption.handler) {
checkedOption.handler();
}
this.dismiss(value);
}
render() { render() {
console.log(this.options);
return ( return (
<ion-list radio-group value="{this.value}"> <ion-list>
<ion-radio-group value={this.value}>
{this.options.map(option => {this.options.map(option =>
<ion-item> <ion-item>
<ion-label>{option.text}</ion-label> <ion-label>
<ion-radio checked={option.checked} value={option.value} disabled={option.disabled}></ion-radio> {option.text}
</ion-label>
<ion-radio
checked={option.checked}
value={option.value}
disabled={option.disabled}>
</ion-radio>
</ion-item> </ion-item>
)} )}
</ion-radio-group>
</ion-list> </ion-list>
); );
} }

View File

@ -1,11 +1,13 @@
import { Component, CssClassMap, Element, Event, EventEmitter, HostElement, Prop } from '@stencil/core'; import { Component, CssClassMap, Element, Event, EventEmitter, HostElement, Prop, PropDidChange, State } from '@stencil/core';
import { deepCopy } from '../../utils/helpers'; import { deepCopy, isCheckedProperty } from '../../utils/helpers';
import { ActionSheet } from '../action-sheet/action-sheet'; import { ActionSheet } from '../action-sheet/action-sheet';
import { Alert } from '../alert/alert'; import { Alert } from '../alert/alert';
import { Popover } from '../popover/popover'; import { Popover } from '../popover/popover';
import { SelectOption } from '../select-option/select-option';
import { ActionSheetController } from '../action-sheet-controller/action-sheet-controller'; import { ActionSheetController } from '../action-sheet-controller/action-sheet-controller';
import { AlertController } from '../alert-controller/alert-controller'; import { AlertController } from '../alert-controller/alert-controller';
import { PopoverController } from '../popover-controller/popover-controller'; import { PopoverController } from '../popover-controller/popover-controller';
@ -23,12 +25,11 @@ import { PopoverController } from '../popover-controller/popover-controller';
} }
}) })
export class Select { export class Select {
text: any; texts: any = [];
texts: any;
id: string; id: string;
labelId: string; labelId: string;
item: any; item: any;
options: any; options: SelectOption[] = [];
overlay: ActionSheet | Alert | Popover; overlay: ActionSheet | Alert | Popover;
@Prop({ connect: 'ion-action-sheet-controller' }) actionSheetCtrl: ActionSheetController; @Prop({ connect: 'ion-action-sheet-controller' }) actionSheetCtrl: ActionSheetController;
@ -37,6 +38,8 @@ export class Select {
@Element() el: HTMLElement; @Element() el: HTMLElement;
@State() text: string;
/** /**
* @input {boolean} If true, the user cannot interact with this element. Defaults to `false`. * @input {boolean} If true, the user cannot interact with this element. Defaults to `false`.
*/ */
@ -83,29 +86,12 @@ export class Select {
/** /**
* @input {string} the value of the select. * @input {string} the value of the select.
*/ */
@Prop({ mutable: true }) value: string; @Prop({ mutable: true }) value: string | string[];
// /** @PropDidChange('value')
// * @hidden valueChanged() {
// */ this.optionUpdated();
// _inputUpdated() { }
// this._texts.length = 0;
// if (this._options) {
// this._options.forEach(option => {
// // check this option if the option's value is in the values array
// option.selected = this.getValues().some(selectValue => {
// return isCheckedProperty(selectValue, option.value);
// });
// if (option.selected) {
// this._texts.push(option.text);
// }
// });
// }
// this._text = this._texts.join(', ');
// }
/** /**
* @output {EventEmitter} Emitted when the selection is cancelled. * @output {EventEmitter} Emitted when the selection is cancelled.
@ -113,7 +99,7 @@ export class Select {
@Event() ionCancel: EventEmitter; @Event() ionCancel: EventEmitter;
ionViewWillLoad() { ionViewDidLoad() {
// Get the parent item // Get the parent item
this.item = this.el.closest('ion-item') as HostElement; this.item = this.el.closest('ion-item') as HostElement;
@ -123,22 +109,59 @@ export class Select {
setOptions() { setOptions() {
// Get the options // Get the options
this.options = this.el.querySelectorAll('ion-select-option') as NodeListOf<HostElement>; const options = this.el.querySelectorAll('ion-select-option') as NodeListOf<any>;
Array.from(options).forEach(option => {
if (!option.value) {
option.value = option.getText();
}
this.options.push(option.$instance);
})
const values = this.getValues(); const values = this.getValues();
if (values.length === 0) { if (values.length === 0) {
// there are no values set at this point // there are no values set at this point
// so check to see who should be selected // so check to see who should be selected
// we use writeValue() because we don't want to update ngModel let filtered = this.options.filter(o => o.selected).map(o => o.value);
// this.writeValue(val.filter(o => o.selected).map(o => o.value)); this.value = filtered;
} else {
this.optionUpdated();
} }
} }
/**
* @hidden
* Update the select options when the value changes
*/
optionUpdated() {
this.texts = [];
if (this.options) {
this.options.forEach(option => {
// check this option if the option's value is in the values array
option.selected = this.getValues().some(selectValue => {
return isCheckedProperty(selectValue, option.value);
});
if (option.selected) {
this.texts.push(option.getText());
}
});
}
this.text = this.texts.join(', ');
}
/** /**
* @hidden * @hidden
*/ */
getValues(): any[] { getValues(): any[] {
if (!this.value) {
return [];
}
const values = Array.isArray(this.value) ? this.value : [this.value]; const values = Array.isArray(this.value) ? this.value : [this.value];
return values; return values;
} }
@ -188,13 +211,12 @@ export class Select {
return selectInterface; return selectInterface;
} }
// TODO add Alert to finish this
buildAlert(selectOptions: any) { buildAlert(selectOptions: any) {
console.debug('Build Select: Alert with', selectOptions, this.options); console.debug('Build Select: Alert with', selectOptions, this.options);
// user cannot provide inputs from selectOptions // user cannot provide inputs from selectOptions
// alert inputs must be created by ionic from ion-select-options // alert inputs must be created by ionic from ion-select-options
selectOptions.inputs = Array.from(this.options).map((option: any) => { selectOptions.inputs = this.options.map((option: any) => {
return { return {
type: (this.multiple ? 'checkbox' : 'radio'), type: (this.multiple ? 'checkbox' : 'radio'),
label: option.getText(), label: option.getText(),
@ -217,13 +239,15 @@ export class Select {
// If the user passed a cssClass for the select, add it // If the user passed a cssClass for the select, add it
selectCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : ''; selectCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
// Add an ok button to the alert
selectOptions.buttons = selectOptions.buttons.concat({
text: this.okText,
handler: (selectedValues: any) => this.value = selectedValues
})
// create the alert instance from our built up selectOptions // create the alert instance from our built up selectOptions
const alertOptions = { const alertOptions = {
cssClass: selectCssClass, cssClass: selectCssClass,
buttons: [{
text: this.okText,
handler: (selectedValues: any) => this.value = selectedValues
}],
...selectOptions ...selectOptions
} }
@ -234,14 +258,13 @@ export class Select {
buildActionSheet(selectOptions: any) { buildActionSheet(selectOptions: any) {
console.debug('Building Select: Action Sheet with', selectOptions, this.options); console.debug('Building Select: Action Sheet with', selectOptions, this.options);
selectOptions.buttons = selectOptions.buttons.concat(Array.from(this.options).map((option: any) => { selectOptions.buttons = selectOptions.buttons.concat(this.options.map((option: any) => {
return { return {
role: (option.selected ? 'selected' : ''), role: (option.selected ? 'selected' : ''),
text: option.getText(), text: option.getText(),
handler: () => { handler: () => {
this.value = option.value; this.value = option.value;
// TODO remove $instance option.ionSelect.emit(option.value);
option.$instance.ionSelect.emit(option.value);
} }
}; };
})); }));
@ -263,7 +286,7 @@ export class Select {
buildPopover(selectOptions: any) { buildPopover(selectOptions: any) {
console.debug('Building Select: Popover with', selectOptions, this.options); console.debug('Building Select: Popover with', selectOptions, this.options);
selectOptions = Array.from(this.options).map((option: any) => { selectOptions = this.options.map((option: any) => {
return { return {
text: option.getText(), text: option.getText(),
checked: option.selected, checked: option.selected,

View File

@ -29,7 +29,7 @@
<ion-item> <ion-item>
<ion-label>Hair Color</ion-label> <ion-label>Hair Color</ion-label>
<ion-select name="hairColor" ok-text="Okay" cancel-text="Dismiss"> <ion-select name="hairColor" ok-text="Okay" cancel-text="Dismiss">
<ion-select-option value="brown">Brown</ion-select-option> <ion-select-option value="brown" selected>Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option> <ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option> <ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option> <ion-select-option value="red">Red</ion-select-option>
@ -50,7 +50,7 @@
<ion-item> <ion-item>
<ion-label>Date</ion-label> <ion-label>Date</ion-label>
<ion-select (ionChange)="monthChange($event)" placeholder="Month"> <ion-select placeholder="Month">
<ion-select-option value="01">January</ion-select-option> <ion-select-option value="01">January</ion-select-option>
<ion-select-option value="02">February</ion-select-option> <ion-select-option value="02">February</ion-select-option>
<ion-select-option value="03" selected="true">March</ion-select-option> <ion-select-option value="03" selected="true">March</ion-select-option>
@ -64,7 +64,7 @@
<ion-select-option value="11">November</ion-select-option> <ion-select-option value="11">November</ion-select-option>
<ion-select-option value="12">December</ion-select-option> <ion-select-option value="12">December</ion-select-option>
</ion-select> </ion-select>
<ion-select (ionChange)="yearChange($event)" placeholder="Year"> <ion-select placeholder="Year">
<ion-select-option>1989</ion-select-option> <ion-select-option>1989</ion-select-option>
<ion-select-option>1990</ion-select-option> <ion-select-option>1990</ion-select-option>
<ion-select-option>1991</ion-select-option> <ion-select-option>1991</ion-select-option>
@ -94,7 +94,7 @@
<ion-item> <ion-item>
<ion-label>Gaming</ion-label> <ion-label>Gaming</ion-label>
<ion-select name="gaming" ok-text="Okay" cancel-text="Dismiss" selected-text="Nintendo 64" interface="popover"> <ion-select name="gaming" ok-text="Okay" cancel-text="Dismiss" value="n64" interface="popover">
<ion-select-option value="nes">NES</ion-select-option> <ion-select-option value="nes">NES</ion-select-option>
<ion-select-option value="n64">Nintendo64</ion-select-option> <ion-select-option value="n64">Nintendo64</ion-select-option>
<ion-select-option value="ps">PlayStation</ion-select-option> <ion-select-option value="ps">PlayStation</ion-select-option>
@ -106,7 +106,7 @@
<ion-item> <ion-item>
<ion-label>Date</ion-label> <ion-label>Date</ion-label>
<ion-select (ionChange)="monthChange($event)" placeholder="Month" interface="popover"> <ion-select placeholder="Month" interface="popover">
<ion-select-option value="01">January</ion-select-option> <ion-select-option value="01">January</ion-select-option>
<ion-select-option value="02">February</ion-select-option> <ion-select-option value="02">February</ion-select-option>
<ion-select-option value="03" selected="true">March</ion-select-option> <ion-select-option value="03" selected="true">March</ion-select-option>
@ -120,7 +120,7 @@
<ion-select-option value="11">November</ion-select-option> <ion-select-option value="11">November</ion-select-option>
<ion-select-option value="12">December</ion-select-option> <ion-select-option value="12">December</ion-select-option>
</ion-select> </ion-select>
<ion-select (ionChange)="yearChange($event)" placeholder="Year" interface="popover"> <ion-select placeholder="Year" interface="popover">
<ion-select-option>1989</ion-select-option> <ion-select-option>1989</ion-select-option>
<ion-select-option>1990</ion-select-option> <ion-select-option>1990</ion-select-option>
<ion-select-option>1991</ion-select-option> <ion-select-option>1991</ion-select-option>