From de24003f3528516c9779f23c6550ce9cae134b69 Mon Sep 17 00:00:00 2001 From: Brandy Carney Date: Fri, 1 Sep 2017 18:50:19 -0400 Subject: [PATCH] fix(select): set the proper values for select for all interfaces --- .../select-option/select-option.tsx | 2 +- .../src/components/select/select-popover.tsx | 65 +++++++---- .../core/src/components/select/select.md.scss | 2 +- .../core/src/components/select/select.tsx | 105 +++++++++++------- .../src/components/select/test/basic.html | 12 +- 5 files changed, 115 insertions(+), 71 deletions(-) diff --git a/packages/core/src/components/select-option/select-option.tsx b/packages/core/src/components/select-option/select-option.tsx index 9eaf6c31b8..3d7f660cb2 100644 --- a/packages/core/src/components/select-option/select-option.tsx +++ b/packages/core/src/components/select-option/select-option.tsx @@ -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. diff --git a/packages/core/src/components/select/select-popover.tsx b/packages/core/src/components/select/select-popover.tsx index ae50926f9d..128e18a73c 100644 --- a/packages/core/src/components/select/select-popover.tsx +++ b/packages/core/src/components/select/select-popover.tsx @@ -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 ( - - {this.options.map(option => - - {option.text} - - - )} + + + {this.options.map(option => + + + {option.text} + + + + + )} + ); } diff --git a/packages/core/src/components/select/select.md.scss b/packages/core/src/components/select/select.md.scss index ea2f6f2468..7391b94f81 100644 --- a/packages/core/src/components/select/select.md.scss +++ b/packages/core/src/components/select/select.md.scss @@ -57,4 +57,4 @@ $select-md-placeholder-color: $select-md-icon-color !default; color: $select-md-icon-color; pointer-events: none; -} +} \ No newline at end of file diff --git a/packages/core/src/components/select/select.tsx b/packages/core/src/components/select/select.tsx index 1cdacc25a5..480df00b85 100644 --- a/packages/core/src/components/select/select.tsx +++ b/packages/core/src/components/select/select.tsx @@ -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; + const options = this.el.querySelectorAll('ion-select-option') as NodeListOf; + + 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, diff --git a/packages/core/src/components/select/test/basic.html b/packages/core/src/components/select/test/basic.html index 428382c2ff..579900ea55 100644 --- a/packages/core/src/components/select/test/basic.html +++ b/packages/core/src/components/select/test/basic.html @@ -29,7 +29,7 @@ Hair Color - Brown + Brown Blonde Black Red @@ -50,7 +50,7 @@ Date - + January February March @@ -64,7 +64,7 @@ November December - + 1989 1990 1991 @@ -94,7 +94,7 @@ Gaming - + NES Nintendo64 PlayStation @@ -106,7 +106,7 @@ Date - + January February March @@ -120,7 +120,7 @@ November December - + 1989 1990 1991