diff --git a/ionic/components/button/test/button.spec.ts b/ionic/components/button/test/button.spec.ts index e72be680da..a7c17093ca 100644 --- a/ionic/components/button/test/button.spec.ts +++ b/ionic/components/button/test/button.spec.ts @@ -2,6 +2,183 @@ import {Button, Config} from 'ionic/ionic'; export function run() { + describe('button', () => { + + it('should ignore certain attributes', () => { + let b = mockButton(['_ngcontent', 'button']); + b._assignCss(true); + expect(hasClass(b, 'button')).toEqual(true); + expect(hasClass(b, 'button-_ngcontent')).toEqual(false); + expect(hasClass(b, 'button-button')).toEqual(false); + }); + + it('should set a different button role', () => { + let b = mockButton(['outline', 'small', 'full', 'primary']); + b.setRole('bar-button'); + b._assignCss(true); + expect(hasClass(b, 'bar-button-outline')).toEqual(true); + expect(hasClass(b, 'bar-button-small')).toEqual(true); + expect(hasClass(b, 'bar-button-full')).toEqual(true); + expect(hasClass(b, 'bar-button-outline-primary')).toEqual(true); + + expect(hasClass(b, 'button-outline')).toEqual(false); + expect(hasClass(b, 'button-small')).toEqual(false); + expect(hasClass(b, 'button-full')).toEqual(false); + expect(hasClass(b, 'button-primary')).toEqual(false); + }); + + it('should remove button color attributes and add different role', () => { + let b = mockButton(['outline', 'small', 'full', 'primary']); + b._assignCss(true); + expect(hasClass(b, 'button-outline')).toEqual(true); + expect(hasClass(b, 'button-small')).toEqual(true); + expect(hasClass(b, 'button-full')).toEqual(true); + expect(hasClass(b, 'button-outline-primary')).toEqual(true); + + b._assignCss(false); + expect(hasClass(b, 'button-outline')).toEqual(false); + expect(hasClass(b, 'button-small')).toEqual(false); + expect(hasClass(b, 'button-full')).toEqual(false); + expect(hasClass(b, 'button-outline-primary')).toEqual(false); + }); + + it('should read button color attributes with styles', () => { + let b = mockButton(['outline', 'small', 'full', 'primary']); + b._assignCss(true); + expect(hasClass(b, 'button')).toEqual(true); + expect(hasClass(b, 'button-outline')).toEqual(true); + expect(hasClass(b, 'button-small')).toEqual(true); + expect(hasClass(b, 'button-full')).toEqual(true); + expect(hasClass(b, 'button-outline-primary')).toEqual(true); + + b = mockButton(['clear', 'primary', 'secondary']); + b._assignCss(true); + expect(hasClass(b, 'button')).toEqual(true); + expect(hasClass(b, 'button-clear')).toEqual(true); + expect(hasClass(b, 'button-clear-primary')).toEqual(true); + expect(hasClass(b, 'button-clear-secondary')).toEqual(true); + + b = mockButton(['solid', 'primary', 'secondary']); + b._assignCss(true); + expect(hasClass(b, 'button')).toEqual(true); + expect(hasClass(b, 'button-solid')).toEqual(true); + expect(hasClass(b, 'button-solid-primary')).toEqual(true); + expect(hasClass(b, 'button-solid-secondary')).toEqual(true); + }); + + it('should auto add the default style', () => { + let b = mockButton(); + b._assignCss(true); + expect(hasClass(b, 'button')).toEqual(true); + expect(hasClass(b, 'button-default')).toEqual(true); + + b = mockButton(['clear']); + b._assignCss(true); + expect(hasClass(b, 'button')).toEqual(true); + expect(hasClass(b, 'button-default')).toEqual(false); + expect(hasClass(b, 'button-clear')).toEqual(true); + }); + + it('should read button color attributes', () => { + let b = mockButton(['primary']); + b._assignCss(true); + expect(hasClass(b, 'button-primary')).toEqual(true); + + b = mockButton(['primary', 'secondary']); + b._assignCss(true); + expect(hasClass(b, 'button-primary')).toEqual(true); + expect(hasClass(b, 'button-secondary')).toEqual(true); + }); + + it('should read button style attributes', () => { + let b = mockButton(['clear']); + b._assignCss(true); + expect(hasClass(b, 'button-clear')).toEqual(true); + + b = mockButton(['outline']); + b._assignCss(true); + expect(hasClass(b, 'button-outline')).toEqual(true); + + b = mockButton(['clear', 'outline', 'small', 'full']); + b._assignCss(true); + expect(hasClass(b, 'button-clear')).toEqual(false); + expect(hasClass(b, 'button-outline')).toEqual(true); + expect(hasClass(b, 'button-small')).toEqual(true); + expect(hasClass(b, 'button-full')).toEqual(true); + }); + + it('should read button shape attributes', () => { + let b = mockButton(['round']); + b._assignCss(true); + expect(hasClass(b, 'button-round')).toEqual(true); + + b = mockButton(['fab']); + b._assignCss(true); + expect(hasClass(b, 'button-fab')).toEqual(true); + }); + + it('should read button display attributes', () => { + let b = mockButton(['block']); + b._assignCss(true); + expect(hasClass(b, 'button-block')).toEqual(true); + + b = mockButton(['full']); + b._assignCss(true); + expect(hasClass(b, 'button-full')).toEqual(true); + + b = mockButton(['block', 'full']); + b._assignCss(true); + expect(hasClass(b, 'button-block')).toEqual(false); + expect(hasClass(b, 'button-full')).toEqual(true); + }); + + it('should read button size attributes', () => { + let b = mockButton(['small']); + b._assignCss(true); + expect(hasClass(b, 'button-small')).toEqual(true); + + b = mockButton(['large']); + b._assignCss(true); + expect(hasClass(b, 'button-large')).toEqual(true); + + b = mockButton(['large', 'small']); + b._assignCss(true); + expect(hasClass(b, 'button-large')).toEqual(false); + expect(hasClass(b, 'button-small')).toEqual(true); + }); + + it('should not add button css class for ion-item attribute', () => { + let b = mockButton(['ion-item']); + b._assignCss(true); + expect(hasClass(b, 'button')).toEqual(false); + }); + + it('should add button css class', () => { + let b = mockButton(); + b._assignCss(true); + expect(hasClass(b, 'button')).toEqual(true); + }); + + it('should add disable-hover css class', () => { + let config = new Config({ + hoverCSS: false + }); + let b = mockButton(null, config); + + expect(hasClass(b, 'disable-hover')).toEqual(true); + }); + + it('should set defaults', () => { + let b = mockButton(); + expect(b._role).toEqual('button'); + expect(b._size).toEqual(null); + expect(b._colors.length).toEqual(0); + expect(b._style).toEqual('default'); + expect(b._display).toEqual(null); + }); + + }); + function mockButton(attrs, config) { config = config || new Config(); let elementRef = { @@ -13,188 +190,15 @@ export function run() { } } let renderer = { - setElementClass: function(elementRef, className, shouldAdd) { - elementRef.nativeElement.classList[shouldAdd ? 'add' : 'remove'](className); + setElementClass: function(nativeElement, className, shouldAdd) { + nativeElement.classList[shouldAdd ? 'add' : 'remove'](className); } }; - return new Button(config, elementRef, renderer); + return new Button(config, elementRef, renderer, null); } function hasClass(button, className) { return button._elementRef.nativeElement.classList.contains(className); } - it('should ignore certain attributes', () => { - let b = mockButton(['_ngcontent', 'button']); - b._assignCss(true); - expect(hasClass(b, 'button')).toEqual(true); - expect(hasClass(b, 'button-_ngcontent')).toEqual(false); - expect(hasClass(b, 'button-button')).toEqual(false); - }); - - it('should set a different button role', () => { - let b = mockButton(['outline', 'small', 'full', 'primary']); - b.setRole('bar-button'); - b._assignCss(true); - expect(hasClass(b, 'bar-button-outline')).toEqual(true); - expect(hasClass(b, 'bar-button-small')).toEqual(true); - expect(hasClass(b, 'bar-button-full')).toEqual(true); - expect(hasClass(b, 'bar-button-outline-primary')).toEqual(true); - - expect(hasClass(b, 'button-outline')).toEqual(false); - expect(hasClass(b, 'button-small')).toEqual(false); - expect(hasClass(b, 'button-full')).toEqual(false); - expect(hasClass(b, 'button-primary')).toEqual(false); - }); - - it('should remove button color attributes and add different role', () => { - let b = mockButton(['outline', 'small', 'full', 'primary']); - b._assignCss(true); - expect(hasClass(b, 'button-outline')).toEqual(true); - expect(hasClass(b, 'button-small')).toEqual(true); - expect(hasClass(b, 'button-full')).toEqual(true); - expect(hasClass(b, 'button-outline-primary')).toEqual(true); - - b._assignCss(false); - expect(hasClass(b, 'button-outline')).toEqual(false); - expect(hasClass(b, 'button-small')).toEqual(false); - expect(hasClass(b, 'button-full')).toEqual(false); - expect(hasClass(b, 'button-outline-primary')).toEqual(false); - }); - - it('should read button color attributes with styles', () => { - let b = mockButton(['outline', 'small', 'full', 'primary']); - b._assignCss(true); - expect(hasClass(b, 'button')).toEqual(true); - expect(hasClass(b, 'button-outline')).toEqual(true); - expect(hasClass(b, 'button-small')).toEqual(true); - expect(hasClass(b, 'button-full')).toEqual(true); - expect(hasClass(b, 'button-outline-primary')).toEqual(true); - - b = mockButton(['clear', 'primary', 'secondary']); - b._assignCss(true); - expect(hasClass(b, 'button')).toEqual(true); - expect(hasClass(b, 'button-clear')).toEqual(true); - expect(hasClass(b, 'button-clear-primary')).toEqual(true); - expect(hasClass(b, 'button-clear-secondary')).toEqual(true); - - b = mockButton(['solid', 'primary', 'secondary']); - b._assignCss(true); - expect(hasClass(b, 'button')).toEqual(true); - expect(hasClass(b, 'button-solid')).toEqual(true); - expect(hasClass(b, 'button-solid-primary')).toEqual(true); - expect(hasClass(b, 'button-solid-secondary')).toEqual(true); - }); - - it('should auto add the default style', () => { - let b = mockButton(); - b._assignCss(true); - expect(hasClass(b, 'button')).toEqual(true); - expect(hasClass(b, 'button-default')).toEqual(true); - - b = mockButton(['clear']); - b._assignCss(true); - expect(hasClass(b, 'button')).toEqual(true); - expect(hasClass(b, 'button-default')).toEqual(false); - expect(hasClass(b, 'button-clear')).toEqual(true); - }); - - it('should read button color attributes', () => { - let b = mockButton(['primary']); - b._assignCss(true); - expect(hasClass(b, 'button-primary')).toEqual(true); - - b = mockButton(['primary', 'secondary']); - b._assignCss(true); - expect(hasClass(b, 'button-primary')).toEqual(true); - expect(hasClass(b, 'button-secondary')).toEqual(true); - }); - - it('should read button style attributes', () => { - let b = mockButton(['clear']); - b._assignCss(true); - expect(hasClass(b, 'button-clear')).toEqual(true); - - b = mockButton(['outline']); - b._assignCss(true); - expect(hasClass(b, 'button-outline')).toEqual(true); - - b = mockButton(['clear', 'outline', 'small', 'full']); - b._assignCss(true); - expect(hasClass(b, 'button-clear')).toEqual(false); - expect(hasClass(b, 'button-outline')).toEqual(true); - expect(hasClass(b, 'button-small')).toEqual(true); - expect(hasClass(b, 'button-full')).toEqual(true); - }); - - it('should read button shape attributes', () => { - let b = mockButton(['round']); - b._assignCss(true); - expect(hasClass(b, 'button-round')).toEqual(true); - - b = mockButton(['fab']); - b._assignCss(true); - expect(hasClass(b, 'button-fab')).toEqual(true); - }); - - it('should read button display attributes', () => { - let b = mockButton(['block']); - b._assignCss(true); - expect(hasClass(b, 'button-block')).toEqual(true); - - b = mockButton(['full']); - b._assignCss(true); - expect(hasClass(b, 'button-full')).toEqual(true); - - b = mockButton(['block', 'full']); - b._assignCss(true); - expect(hasClass(b, 'button-block')).toEqual(false); - expect(hasClass(b, 'button-full')).toEqual(true); - }); - - it('should read button size attributes', () => { - let b = mockButton(['small']); - b._assignCss(true); - expect(hasClass(b, 'button-small')).toEqual(true); - - b = mockButton(['large']); - b._assignCss(true); - expect(hasClass(b, 'button-large')).toEqual(true); - - b = mockButton(['large', 'small']); - b._assignCss(true); - expect(hasClass(b, 'button-large')).toEqual(false); - expect(hasClass(b, 'button-small')).toEqual(true); - }); - - it('should not add button css class for ion-item attribute', () => { - let b = mockButton(['ion-item']); - b._assignCss(true); - expect(hasClass(b, 'button')).toEqual(false); - }); - - it('should add button css class', () => { - let b = mockButton(); - b._assignCss(true); - expect(hasClass(b, 'button')).toEqual(true); - }); - - it('should add disable-hover css class', () => { - let config = new Config({ - hoverCSS: false - }); - let b = mockButton(null, config); - - expect(hasClass(b, 'disable-hover')).toEqual(true); - }); - - it('should set defaults', () => { - let b = mockButton(); - expect(b._role).toEqual('button'); - expect(b._size).toEqual(null); - expect(b._colors.length).toEqual(0); - expect(b._style).toEqual('default'); - expect(b._display).toEqual(null); - }); - } diff --git a/ionic/components/checkbox/checkbox.ts b/ionic/components/checkbox/checkbox.ts index 8fe5cbb5ba..c1feef4cac 100644 --- a/ionic/components/checkbox/checkbox.ts +++ b/ionic/components/checkbox/checkbox.ts @@ -3,6 +3,7 @@ import {NgControl} from 'angular2/common'; import {Form} from '../../util/form'; import {Item} from '../item/item'; +import {isTrueProperty} from '../../util/util'; /** * The checkbox is no different than the HTML checkbox input, except @@ -99,7 +100,7 @@ export class Checkbox { set checked(val) { if (!this._disabled) { - this._checked = (val === true || val === 'true'); + this._checked = isTrueProperty(val); this.onChange(this._checked); this._item && this._item.setCssClass('item-checkbox-checked', this._checked); } @@ -111,7 +112,7 @@ export class Checkbox { } set disabled(val) { - this._disabled = (val === true || val === 'true'); + this._disabled = isTrueProperty(val); this._item && this._item.setCssClass('item-checkbox-disabled', this._disabled); } @@ -132,8 +133,10 @@ export class Checkbox { * the checked value. * https://github.com/angular/angular/blob/master/modules/angular2/src/forms/directives/shared.ts#L34 */ - writeValue(value) { - this.checked = value; + writeValue(val) { + if (val !== null) { + this.checked = val; + } } /** diff --git a/ionic/components/checkbox/test/basic/main.html b/ionic/components/checkbox/test/basic/main.html index 4badb5ec30..b7670ad5fa 100644 --- a/ionic/components/checkbox/test/basic/main.html +++ b/ionic/components/checkbox/test/basic/main.html @@ -30,12 +30,12 @@ secondary color - + light color - + diff --git a/ionic/components/input/test/text-input.spec.ts b/ionic/components/input/test/text-input.spec.ts index 05449434a1..e8bf672c8b 100644 --- a/ionic/components/input/test/text-input.spec.ts +++ b/ionic/components/input/test/text-input.spec.ts @@ -1,4 +1,4 @@ -import {ItemInput} from 'ionic/ionic'; +import {TextInput} from 'ionic/ionic'; export function run() { @@ -14,7 +14,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(-205); expect(scrollData.scrollTo).toBe(235); @@ -33,7 +33,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(-205); expect(scrollData.scrollTo).toBe(235); @@ -41,7 +41,7 @@ export function run() { }); it('should scroll, top above safe', () => { - // ItemInput top within safe area, bottom below safe area, room to scroll + // TextInput top within safe area, bottom below safe area, room to scroll let inputOffsetTop = 100; let inputOffsetHeight = 33; let scrollViewDimensions = { @@ -53,7 +53,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(150); expect(scrollData.scrollTo).toBe(100); @@ -61,7 +61,7 @@ export function run() { }); it('should scroll, top in safe, bottom below safe, below more than top in, not enough padding', () => { - // ItemInput top within safe area, bottom below safe area, room to scroll + // TextInput top within safe area, bottom below safe area, room to scroll let inputOffsetTop = 100; let inputOffsetHeight = 320; let scrollViewDimensions = { @@ -73,7 +73,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(-80); expect(scrollData.scrollTo).toBe(100); @@ -81,7 +81,7 @@ export function run() { }); it('should scroll, top in safe, bottom below safe, below more than top in, enough padding', () => { - // ItemInput top within safe area, bottom below safe area, room to scroll + // TextInput top within safe area, bottom below safe area, room to scroll let inputOffsetTop = 20; let inputOffsetHeight = 330; let scrollViewDimensions = { @@ -91,7 +91,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(-20); expect(scrollData.scrollTo).toBe(20); @@ -99,7 +99,7 @@ export function run() { }); it('should scroll, top in safe, bottom below safe, below less than top in, enough padding', () => { - // ItemInput top within safe area, bottom below safe area, room to scroll + // TextInput top within safe area, bottom below safe area, room to scroll let inputOffsetTop = 250; let inputOffsetHeight = 80; // goes 30px below safe area let scrollViewDimensions = { @@ -109,7 +109,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(-180); expect(scrollData.scrollTo).toBe(180); @@ -117,7 +117,7 @@ export function run() { }); it('should not scroll, top in safe, bottom in safe', () => { - // ItemInput top within safe area, bottom within safe area + // TextInput top within safe area, bottom within safe area let inputOffsetTop = 100; let inputOffsetHeight = 50; let scrollViewDimensions = { @@ -128,7 +128,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(0); }); diff --git a/ionic/components/nav/test/nav-controller.spec.ts b/ionic/components/nav/test/nav-controller.spec.ts index e0918ac76d..e842e22a5c 100644 --- a/ionic/components/nav/test/nav-controller.spec.ts +++ b/ionic/components/nav/test/nav-controller.spec.ts @@ -628,7 +628,10 @@ export function run() { class Page5 {} beforeEach(() => { - nav = new NavController(null, null, config, null, null, null, null, null, null, null); + let elementRef = { + nativeElement: document.createElement('div') + }; + nav = new NavController(null, null, config, null, elementRef, null, null, null, null, null); nav._renderer = { setElementAttribute: function(){}, setElementClass: function(){}, diff --git a/ionic/components/option/option.ts b/ionic/components/option/option.ts index 0b750ab986..d1c0fca995 100644 --- a/ionic/components/option/option.ts +++ b/ionic/components/option/option.ts @@ -1,6 +1,6 @@ import {Directive, ElementRef, Input} from 'angular2/core'; -import {isDefined} from '../../util/util'; +import {isDefined, isTrueProperty} from '../../util/util'; /** * @name Option @@ -9,7 +9,7 @@ import {isDefined} from '../../util/util'; selector: 'ion-option' }) export class Option { - private _checked: boolean = false; + private _checked: any = false; private _value; constructor(private _elementRef: ElementRef) {} @@ -19,8 +19,8 @@ export class Option { return this._checked; } - set checked(val: any) { - this._checked = (val === 'true' || val === true || val === ''); + set checked(val) { + this._checked = isTrueProperty(val); } @Input() diff --git a/ionic/components/radio/radio-button.ts b/ionic/components/radio/radio-button.ts index 1836a42018..12b54a5fc4 100644 --- a/ionic/components/radio/radio-button.ts +++ b/ionic/components/radio/radio-button.ts @@ -1,9 +1,9 @@ import {Component, Optional, Input, Output, HostListener, EventEmitter} from 'angular2/core'; +import {Form} from '../../util/form'; +import {isTrueProperty} from '../../util/util'; import {Item} from '../item/item'; import {ListHeader} from '../list/list'; -import {Form} from '../../util/form'; -import {isDefined} from '../../util/util'; import {RadioGroup} from './radio-group'; @@ -85,7 +85,7 @@ export class RadioButton { set checked(val) { if (!this._disabled) { - this._checked = (val === true || val === 'true'); + this._checked = isTrueProperty(val); this.select.emit(this); this._item && this._item.setCssClass('item-radio-checked', this._checked); } @@ -97,7 +97,7 @@ export class RadioButton { } set disabled(val) { - this._disabled = (val === true || val === 'true'); + this._disabled = isTrueProperty(val); this._item && this._item.setCssClass('item-radio-disabled', this._disabled); } diff --git a/ionic/components/select/select.ts b/ionic/components/select/select.ts index 2ec0190ff9..a1e1f192b8 100644 --- a/ionic/components/select/select.ts +++ b/ionic/components/select/select.ts @@ -4,7 +4,7 @@ import {NgControl} from 'angular2/common'; import {Alert} from '../alert/alert'; import {Form} from '../../util/form'; import {Item} from '../item/item'; -import {merge, isDefined} from '../../util/util'; +import {merge, isDefined, isTrueProperty} from '../../util/util'; import {NavController} from '../nav/nav-controller'; import {Option} from '../option/option'; @@ -97,7 +97,7 @@ import {Option} from '../option/option'; @Component({ selector: 'ion-select', template: - '
{{_selectedText}}
' + + '
{{text}}
' + '
' + '
' + '
' + @@ -110,11 +110,11 @@ import {Option} from '../option/option'; } }) export class Select { - private _selectedText: string = ''; private _disabled: any = false; private _labelId: string; id: string; + text: string = ''; @Input() cancelText: string = 'Cancel'; @Input() okText: string = 'OK'; @@ -155,18 +155,18 @@ export class Select { * @private */ ngAfterContentInit() { - let values = []; + let selectedValues = []; let selectedTexts = []; this.options.toArray().forEach(option => { if (option.checked) { - values.push( isDefined(option.value) ? option.value : option.text ); + selectedValues.push( isDefined(option.value) ? option.value : option.text ); selectedTexts.push(option.text); } }); - this.value = values.join(','); - this._selectedText = selectedTexts.join(', '); + this.value = selectedValues.join(','); + this.text = selectedTexts.join(', '); setTimeout(()=> { this.onChange(this.value); @@ -203,7 +203,7 @@ export class Select { type: (isMulti ? 'checkbox' : 'radio'), label: input.text, value: input.value, - checked: !!input.checked + checked: input.checked } }); @@ -235,7 +235,7 @@ export class Select { } }); - this._selectedText = selectedTexts.join(', '); + this.text = selectedTexts.join(', '); this.onChange(selectedValues); } @@ -252,12 +252,12 @@ export class Select { // or undefined if nothing was checked this.value = selectedValue; - this._selectedText = ''; + this.text = ''; this.options.toArray().forEach(option => { if (option.value === selectedValue) { // this option was the one that was checked option.checked = true; - this._selectedText = option.text; + this.text = option.text; } else { // this option was not checked @@ -280,7 +280,9 @@ export class Select { * https://github.com/angular/angular/blob/master/modules/angular2/src/forms/directives/shared.ts#L34 */ writeValue(value) { - this.value = value; + if (value !== null) { + this.value = value; + } } /** diff --git a/ionic/components/toggle/toggle.ts b/ionic/components/toggle/toggle.ts index e1a281743d..334b28bdaf 100644 --- a/ionic/components/toggle/toggle.ts +++ b/ionic/components/toggle/toggle.ts @@ -1,8 +1,9 @@ import {Component, ElementRef, Renderer, Input, Optional} from 'angular2/core'; import {NgControl} from 'angular2/common'; -import {Config} from '../../config/config'; import {Form} from '../../util/form'; +import {Config} from '../../config/config'; +import {isTrueProperty} from '../../util/util'; import {Item} from '../item/item'; import {pointerCoord} from '../../util/dom'; @@ -125,7 +126,7 @@ export class Toggle { set checked(val) { if (!this._disabled) { - this._checked = (val === true || val === 'true'); + this._checked = isTrueProperty(val); this.onChange(this._checked); this._item && this._item.setCssClass('item-toggle-checked', this._checked); } @@ -137,7 +138,7 @@ export class Toggle { } set disabled(val) { - this._disabled = (val === true || val === 'true'); + this._disabled = isTrueProperty(val); this._item && this._item.setCssClass('item-toggle-disabled', this._disabled); } @@ -145,7 +146,7 @@ export class Toggle { * @private */ private pointerDown(ev) { - if (/touch/.test(ev.type)) { + if (ev.type.indexOf('touch') > -1) { this._touched = Date.now(); } diff --git a/ionic/platform/test/platform.spec.ts b/ionic/platform/test/platform.spec.ts index b00e5a5cd4..374bd6d652 100644 --- a/ionic/platform/test/platform.spec.ts +++ b/ionic/platform/test/platform.spec.ts @@ -68,7 +68,6 @@ export function run() { expect(platform.is('mobile')).toEqual(true); expect(platform.is('android')).toEqual(false); expect(platform.is('ios')).toEqual(true); - expect(platform.is('tablet')).toEqual(false); }); it('should set ios via querystring, even with android user agent', () => { diff --git a/ionic/util/test/util.spec.ts b/ionic/util/test/util.spec.ts index c3df1109b2..6ae9c00f6c 100644 --- a/ionic/util/test/util.spec.ts +++ b/ionic/util/test/util.spec.ts @@ -3,6 +3,53 @@ import * as util from 'ionic/util'; export function run() { describe('extend', function() { + describe('isTrueProperty', function() { + + it('should be true from boolean true', () => { + expect(util.isTrueProperty(true)).toBe(true); + }); + + it('should be true from string "true"', () => { + expect(util.isTrueProperty('true')).toBe(true); + expect(util.isTrueProperty('TRUE')).toBe(true); + expect(util.isTrueProperty(' true ')).toBe(true); + }); + + it('should be true from empty string ""', () => { + expect(util.isTrueProperty('')).toBe(true); + expect(util.isTrueProperty(' ')).toBe(true); + }); + + it('should be true from number greater than zero', () => { + expect(util.isTrueProperty(1)).toBe(true); + expect(util.isTrueProperty(999)).toBe(true); + }); + + it('should be false from boolean false', () => { + expect(util.isTrueProperty(false)).toBe(false); + }); + + it('should be false from null', () => { + expect(util.isTrueProperty(null)).toBe(false); + }); + + it('should be false from undefined', () => { + expect(util.isTrueProperty(undefined)).toBe(false); + }); + + it('should be false from string "false"', () => { + expect(util.isTrueProperty('false')).toBe(false); + expect(util.isTrueProperty(' FALSE ')).toBe(false); + expect(util.isTrueProperty('doesnt actually matter')).toBe(false); + }); + + it('should be false from number less than 1', () => { + expect(util.isTrueProperty(0)).toBe(false); + expect(util.isTrueProperty(-1)).toBe(false); + }); + + }); + it('should extend simple', () => { var obj = { a: '0', c: '0' }; expect( util.assign(obj, { a: '1', b: '2' }) ).toBe(obj); diff --git a/ionic/util/util.ts b/ionic/util/util.ts index 1d1ca86a73..53d88ecdbe 100644 --- a/ionic/util/util.ts +++ b/ionic/util/util.ts @@ -111,7 +111,16 @@ export const isUndefined = val => typeof val === 'undefined'; export const isBlank = val => val === undefined || val === null; export const isObject = val => typeof val === 'object'; export const isArray = Array.isArray; -export const isTrueProperty = val => typeof val !== 'undefined' && val !== "false"; + +export const isTrueProperty = function(val) { + if (typeof val === 'boolean') return val; + if (typeof val === 'string') { + val = val.toLowerCase().trim(); + return (val === 'true' || val === ''); + } + if (typeof val === 'number') return (val > 0); + return !!val; +}; /** * Convert a string in the format thisIsAString to a slug format this-is-a-string diff --git a/scripts/karma/karma.conf.js b/scripts/karma/karma.conf.js index c1791fb6b3..2a90c1563d 100644 --- a/scripts/karma/karma.conf.js +++ b/scripts/karma/karma.conf.js @@ -17,7 +17,7 @@ module.exports = function(config) { 'node_modules/rxjs/bundles/Rx.min.js', 'dist/bundles/ionic.system.js', //'node_modules/angular2/bundles/test_lib.js', - { pattern: 'dist/tests/**/nav-controller.spec.js', included: false }, + { pattern: 'dist/tests/**/*.spec.js', included: false }, 'scripts/karma/test-main.js' ],