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

View File

@ -57,4 +57,4 @@ $select-md-placeholder-color: $select-md-icon-color !default;
color: $select-md-icon-color;
pointer-events: none;
}
}

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 { Alert } from '../alert/alert';
import { Popover } from '../popover/popover';
import { SelectOption } from '../select-option/select-option';
import { ActionSheetController } from '../action-sheet-controller/action-sheet-controller';
import { AlertController } from '../alert-controller/alert-controller';
import { PopoverController } from '../popover-controller/popover-controller';
@ -23,12 +25,11 @@ import { PopoverController } from '../popover-controller/popover-controller';
}
})
export class Select {
text: any;
texts: any;
texts: any = [];
id: string;
labelId: string;
item: any;
options: any;
options: SelectOption[] = [];
overlay: ActionSheet | Alert | Popover;
@Prop({ connect: 'ion-action-sheet-controller' }) actionSheetCtrl: ActionSheetController;
@ -37,6 +38,8 @@ export class Select {
@Element() el: HTMLElement;
@State() text: string;
/**
* @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.
*/
@Prop({ mutable: true }) value: string;
@Prop({ mutable: true }) value: string | string[];
// /**
// * @hidden
// */
// _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(', ');
// }
@PropDidChange('value')
valueChanged() {
this.optionUpdated();
}
/**
* @output {EventEmitter} Emitted when the selection is cancelled.
@ -113,7 +99,7 @@ export class Select {
@Event() ionCancel: EventEmitter;
ionViewWillLoad() {
ionViewDidLoad() {
// Get the parent item
this.item = this.el.closest('ion-item') as HostElement;
@ -123,22 +109,59 @@ export class Select {
setOptions() {
// 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();
if (values.length === 0) {
// there are no values set at this point
// so check to see who should be selected
// we use writeValue() because we don't want to update ngModel
// this.writeValue(val.filter(o => o.selected).map(o => o.value));
let filtered = this.options.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
*/
getValues(): any[] {
if (!this.value) {
return [];
}
const values = Array.isArray(this.value) ? this.value : [this.value];
return values;
}
@ -188,13 +211,12 @@ export class Select {
return selectInterface;
}
// TODO add Alert to finish this
buildAlert(selectOptions: any) {
console.debug('Build Select: Alert with', selectOptions, this.options);
// user cannot provide inputs from selectOptions
// 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 {
type: (this.multiple ? 'checkbox' : 'radio'),
label: option.getText(),
@ -217,13 +239,15 @@ export class Select {
// If the user passed a cssClass for the select, add it
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
const alertOptions = {
cssClass: selectCssClass,
buttons: [{
text: this.okText,
handler: (selectedValues: any) => this.value = selectedValues
}],
...selectOptions
}
@ -234,14 +258,13 @@ export class Select {
buildActionSheet(selectOptions: any) {
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 {
role: (option.selected ? 'selected' : ''),
text: option.getText(),
handler: () => {
this.value = option.value;
// TODO remove $instance
option.$instance.ionSelect.emit(option.value);
option.ionSelect.emit(option.value);
}
};
}));
@ -263,7 +286,7 @@ export class Select {
buildPopover(selectOptions: any) {
console.debug('Building Select: Popover with', selectOptions, this.options);
selectOptions = Array.from(this.options).map((option: any) => {
selectOptions = this.options.map((option: any) => {
return {
text: option.getText(),
checked: option.selected,

View File

@ -29,7 +29,7 @@
<ion-item>
<ion-label>Hair Color</ion-label>
<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="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
@ -50,7 +50,7 @@
<ion-item>
<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="02">February</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="12">December</ion-select-option>
</ion-select>
<ion-select (ionChange)="yearChange($event)" placeholder="Year">
<ion-select placeholder="Year">
<ion-select-option>1989</ion-select-option>
<ion-select-option>1990</ion-select-option>
<ion-select-option>1991</ion-select-option>
@ -94,7 +94,7 @@
<ion-item>
<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="n64">Nintendo64</ion-select-option>
<ion-select-option value="ps">PlayStation</ion-select-option>
@ -106,7 +106,7 @@
<ion-item>
<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="02">February</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="12">December</ion-select-option>
</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>1990</ion-select-option>
<ion-select-option>1991</ion-select-option>