refactor(forms): upgrade to @angular/forms

This commit is contained in:
Adam Bradley
2016-06-30 21:54:48 -05:00
parent 9b2f4a682e
commit 4d56219a4c
42 changed files with 219 additions and 249 deletions

View File

@ -48,6 +48,7 @@
'@angular/core': '/node_modules/@angular/core/bundles/core.umd.js',
'@angular/compiler': '/node_modules/@angular/compiler/bundles/compiler.umd.js',
'@angular/common': '/node_modules/@angular/common/bundles/common.umd.js',
'@angular/forms': '/node_modules/@angular/forms/bundles/forms.umd.js',
'@angular/http': '/node_modules/@angular/http/bundles/http.umd.js',
'@angular/platform-browser': '/node_modules/@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': '/node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',

View File

@ -10,8 +10,8 @@ module.exports = {
'@angular/common': {
commonjs2: ['angular2', 'common']
},
'@angular/router' : {
commonjs2: ['angular2', 'router']
'@angular/forms' : {
commonjs2: ['angular2', 'forms']
},
'@angular/http': {
commonjs2: ['angular2', 'http']

View File

@ -28,7 +28,7 @@ System.config({
main: 'index.js',
defaultExtension: 'js'
},
'@angular/router': {
'@angular/forms': {
main: 'index.js',
defaultExtension: 'js'
},

View File

@ -15,8 +15,8 @@ module.exports = {
'@angular/common': {
commonjs2: ['angular2', 'common']
},
'@angular/router' : {
commonjs2: ['angular2', 'router']
'@angular/forms' : {
commonjs2: ['angular2', 'forms']
},
'@angular/http': {
commonjs2: ['angular2', 'http']

View File

@ -41,11 +41,11 @@ export class E2EPage {
</ion-navbar>
</ion-header>
<ion-content padding>
<form [ngFormModel]="form" (ngSubmit)="submit(form.value)">
<form [formGroup]="form" (ngSubmit)="submit(form.value)">
<ion-list>
<ion-item [class.error]="!form.controls.name.valid && form.controls.name.touched">
<ion-label>Name</ion-label>
<ion-input type="text" [(ngFormControl)]="form.controls.name"></ion-input>
<ion-input type="text" [(formControl)]="form.controls.name"></ion-input>
</ion-item>
</ion-list>
<div padding style="padding-top: 0 !important;">

View File

@ -1,6 +1,5 @@
import {Component} from '@angular/core';
import {Control, ControlGroup} from '@angular/common';
import {ionicBootstrap, Storage, LocalStorage, SqlStorage} from '../../../../../src';
import { Component } from '@angular/core';
import { ionicBootstrap, Storage, LocalStorage, SqlStorage } from '../../../../../src';
@Component({

View File

@ -1,5 +1,5 @@
import { Component, EventEmitter, forwardRef, HostListener, Input, Optional, Output, Provider, ViewEncapsulation } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/common';
import { AfterContentInit, Component, EventEmitter, forwardRef, HostListener, Input, OnDestroy, Optional, Output, Provider, ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Form } from '../../util/form';
import { Item } from '../item/item';
@ -68,7 +68,7 @@ const CHECKBOX_VALUE_ACCESSOR = new Provider(
providers: [CHECKBOX_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None,
})
export class Checkbox {
export class Checkbox implements AfterContentInit, ControlValueAccessor, OnDestroy {
private _checked: boolean = false;
private _init: boolean;
private _disabled: boolean = false;
@ -177,7 +177,7 @@ export class Checkbox {
* @private
*/
onChange(isChecked: boolean) {
// used when this input does not have an ngModel or ngControl
// used when this input does not have an ngModel or formControlName
console.debug('checkbox, onChange (no ngModel)', isChecked);
this._setChecked(isChecked);
this.onTouched();

View File

@ -1,6 +1,6 @@
it('should check apple, enable/check grape, submit form', function() {
element(by.css('[ngControl=appleCtrl]')).click();
element(by.css('[formControlName=appleCtrl]')).click();
element(by.css('.e2eGrapeDisabled')).click();
element(by.css('.e2eGrapeChecked')).click();
element(by.css('.e2eSubmit')).click();

View File

@ -1,13 +1,13 @@
import {Component} from '@angular/core';
import {Control, ControlGroup} from '@angular/common';
import {ionicBootstrap} from '../../../../../src';
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { ionicBootstrap, Checkbox } from '../../../../../src';
@Component({
templateUrl: 'main.html'
})
class E2EPage {
fruitsForm: ControlGroup;
fruitsForm: FormGroup;
grapeDisabled: boolean;
grapeChecked: boolean;
kiwiValue: boolean;
@ -16,11 +16,11 @@ class E2EPage {
formResults: string;
constructor() {
this.fruitsForm = new ControlGroup({
"appleCtrl": new Control(true),
"bananaCtrl": new Control(true),
"cherryCtrl": new Control(false),
"grapeCtrl": new Control(true)
this.fruitsForm = new FormGroup({
"appleCtrl": new FormControl(true),
"bananaCtrl": new FormControl(true),
"cherryCtrl": new FormControl(false),
"grapeCtrl": new FormControl(true)
});
this.grapeDisabled = true;
@ -36,17 +36,17 @@ class E2EPage {
this.grapeDisabled = !this.grapeDisabled;
}
kiwiChange(ev) {
console.log('kiwiChange', ev);
this.kiwiValue = ev.checked;
kiwiChange(checkbox: Checkbox) {
console.log('kiwiChange', checkbox);
this.kiwiValue = checkbox.checked;
}
strawberryChange(ev) {
console.log('strawberryChange', ev);
this.strawberryValue = ev.checked;
strawberryChange(checkbox: Checkbox) {
console.log('strawberryChange', checkbox);
this.strawberryValue = checkbox.checked;
}
doSubmit(ev) {
doSubmit(ev: UIEvent) {
console.log('Submitting form', this.fruitsForm.value);
this.formResults = JSON.stringify(this.fruitsForm.value);
ev.preventDefault();

View File

@ -9,28 +9,28 @@
<ion-content>
<form (submit)="doSubmit($event)" [ngFormModel]="fruitsForm">
<form (submit)="doSubmit($event)" [formGroup]="fruitsForm">
<ion-list>
<ion-item>
<ion-label>Apple, ngControl</ion-label>
<ion-checkbox ngControl="appleCtrl"></ion-checkbox>
<ion-label>Apple, formControlName</ion-label>
<ion-checkbox formControlName="appleCtrl"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Banana, ngControl</ion-label>
<ion-checkbox ngControl="bananaCtrl"></ion-checkbox>
<ion-label>Banana, formControlName</ion-label>
<ion-checkbox formControlName="bananaCtrl"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Cherry, ngControl, disabled</ion-label>
<ion-checkbox disabled="true" ngControl="cherryCtrl"></ion-checkbox>
<ion-label>Cherry, formControlName, disabled</ion-label>
<ion-checkbox disabled="true" formControlName="cherryCtrl"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Grape, ngControl, checked, disabled</ion-label>
<ion-checkbox [checked]="grapeChecked" [disabled]="grapeDisabled" ngControl="grapeCtrl"></ion-checkbox>
<ion-label>Grape, formControlName, checked, disabled</ion-label>
<ion-checkbox [checked]="grapeChecked" [disabled]="grapeDisabled" formControlName="grapeCtrl"></ion-checkbox>
</ion-item>
<ion-item>

View File

@ -1,5 +1,5 @@
import { Component, EventEmitter, forwardRef, HostListener, Input, Optional, Output, Provider, ViewEncapsulation } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/common';
import { AfterContentInit, Component, EventEmitter, forwardRef, HostListener, Input, OnDestroy, Optional, Output, Provider, ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Config } from '../../config/config';
import { Picker, PickerController } from '../picker/picker';
@ -264,7 +264,7 @@ const DATETIME_VALUE_ACCESSOR = new Provider(
providers: [DATETIME_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None,
})
export class DateTime {
export class DateTime implements AfterContentInit, ControlValueAccessor, OnDestroy {
private _disabled: any = false;
private _labelId: string;
private _text: string = '';
@ -817,8 +817,8 @@ export class DateTime {
* @private
*/
onChange(val: any) {
// onChange used when there is not an ngControl
console.debug('datetime, onChange w/out ngControl', val);
// onChange used when there is not an formControlName
console.debug('datetime, onChange w/out formControlName', val);
this.setValue(val);
this.updateText();
this.onTouched();

View File

@ -1,11 +1,12 @@
import {Component} from '@angular/core';
import {ionicBootstrap} from '../../../../../src';
import { Component } from '@angular/core';
import { ionicBootstrap } from '../../../../../src';
@Component({
templateUrl: 'main.html'
})
class E2EPage {
myDate: any;
wwwInvented = '1989';
time = '13:47:00';
netscapeReleased = '1994-12-15T13:47:20.789';

View File

@ -1,5 +1,5 @@
import {Component} from '@angular/core';
import {ionicBootstrap} from '../../../../../src';
import { Component } from '@angular/core';
import { ionicBootstrap } from '../../../../../src';
@Component({

View File

@ -1,5 +1,5 @@
import { ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { NgControl } from '@angular/common';
import { NgControl } from '@angular/forms';
import { App } from '../app/app';
import { closest, copyInputAttributes, Coordinates, hasPointerMoved, pointerCoord } from '../../util/dom';
@ -430,16 +430,15 @@ export class InputBase {
/**
* @private
* Angular2 Forms API method called by the view (NgControl) to register the
* Angular2 Forms API method called by the view (formControlName) to register the
* onChange event handler that updates the model (Control).
* https://github.com/angular/angular/blob/master/modules/angular2/src/forms/directives/shared.ts#L27
* @param {Function} fn the onChange event handler.
*/
registerOnChange(fn: any) { this.onChange = fn; }
/**
* @private
* Angular2 Forms API method called by the view (NgControl) to register
* Angular2 Forms API method called by the view (formControlName) to register
* the onTouched event handler that marks model (Control) as touched.
* @param {Function} fn onTouched event handler.
*/

View File

@ -1,5 +1,5 @@
import { Component, Optional, ElementRef, ViewChild, ViewEncapsulation } from '@angular/core';
import { NgControl } from '@angular/common';
import { NgControl } from '@angular/forms';
import { App } from '../app/app';
import { Config } from '../../config/config';

View File

@ -1,7 +1,7 @@
import { Directive, ElementRef, EventEmitter, HostListener, Input, Output, Renderer} from '@angular/core';
import { NgControl} from '@angular/common';
import { Directive, ElementRef, EventEmitter, HostListener, Output, Renderer } from '@angular/core';
import { NgControl } from '@angular/forms';
import { Config} from '../../config/config';
import { Config } from '../../config/config';
import { CSS, hasFocus } from '../../util/dom';

View File

@ -1,6 +1,6 @@
import {Component} from '@angular/core';
import {ionicBootstrap} from '../../../../../src';
import {FormBuilder, Validators} from '@angular/common';
import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/common';
import { ionicBootstrap } from '../../../../../src';
@Component({
@ -35,7 +35,7 @@ class E2EPage {
});
}
emailValidator(control) {
emailValidator(control: any) {
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
if (!EMAIL_REGEXP.test(control.value)) {
@ -43,7 +43,7 @@ class E2EPage {
}
}
submit(ev, value) {
submit(ev: UIEvent, value: any) {
console.log("Submitted", value);
this.submitted = true;
}

View File

@ -9,32 +9,32 @@
<ion-content>
<form [ngFormModel]="loginForm" #mf="ngForm" novalidate>
<form [formGroup]="loginForm" #mf="ngForm" novalidate>
<ion-list>
<ion-item>
<ion-label floating>Email</ion-label>
<ion-input clearInput [(ngModel)]="login.email" ngControl="email" type="email" required></ion-input>
<ion-input clearInput [(ngModel)]="login.email" formControlName="email" type="email" required></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Username</ion-label>
<ion-input clearInput [(ngModel)]="login.username" ngControl="username"></ion-input>
<ion-input clearInput [(ngModel)]="login.username" formControlName="username"></ion-input>
</ion-item>
<ion-item>
<ion-label>Password</ion-label>
<ion-input clearInput [(ngModel)]="login.password" ngControl="password" type="password" required></ion-input>
<ion-input clearInput [(ngModel)]="login.password" formControlName="password" type="password" required></ion-input>
</ion-item>
<ion-item>
<ion-label>Comments</ion-label>
<ion-textarea clearInput [(ngModel)]="login.comments" ngControl="comments" required>Comment value</ion-textarea>
<ion-textarea clearInput [(ngModel)]="login.comments" formControlName="comments" required>Comment value</ion-textarea>
</ion-item>
<ion-item>
<ion-label>Gender</ion-label>
<ion-select [(ngModel)]="login.gender" ngControl="gender">
<ion-select [(ngModel)]="login.gender" formControlName="gender">
<ion-option value="f">Female</ion-option>
<ion-option value="m">Male</ion-option>
</ion-select>
@ -58,11 +58,11 @@
<ion-list>
<ion-item>
<ion-label floating>Username</ion-label>
<ion-input [(ngModel)]="user.username" ngControl="username" required></ion-input>
<ion-input [(ngModel)]="user.username" formControlName="username" required></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Password</ion-label>
<ion-input type="password" [(ngModel)]="user.password" ngControl="password" required></ion-input>
<ion-input type="password" [(ngModel)]="user.password" formControlName="password" required></ion-input>
</ion-item>
<div padding-left padding-right>
<button block type="submit">Login</button>

View File

@ -247,15 +247,15 @@ class ToolbarModal {
<ion-list>
<ion-item>
<ion-label floating>Title <span [hidden]="title.valid">(Required)</span></ion-label>
<ion-input ngControl="title" type="text" [(ngModel)]="data.title" #title="ngForm" required autofocus></ion-input>
<ion-input formControlName="title" type="text" [(ngModel)]="data.title" #title="ngForm" required autofocus></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Note <span [hidden]="note.valid">(Required)</span></ion-label>
<ion-input ngControl="note" type="text" [(ngModel)]="data.note" #note="ngForm" required></ion-input>
<ion-input formControlName="note" type="text" [(ngModel)]="data.note" #note="ngForm" required></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Icon</ion-label>
<ion-input ngControl="icon" type="text" [(ngModel)]="data.icon" #icon="ngForm" autocomplete="on" autocorrect="on"></ion-input>
<ion-input formControlName="icon" type="text" [(ngModel)]="data.icon" #icon="ngForm" autocomplete="on" autocorrect="on"></ion-input>
</ion-item>
</ion-list>
<div padding>

View File

@ -1,4 +1,4 @@
import {Component, EventEmitter, HostListener, Input, Optional, Output, ViewEncapsulation } from '@angular/core';
import { Component, EventEmitter, HostListener, Input, OnInit, OnDestroy, Optional, Output, ViewEncapsulation } from '@angular/core';
import { Form } from '../../util/form';
import { isBlank, isCheckedProperty, isPresent, isTrueProperty } from '../../util/util';
@ -61,7 +61,7 @@ import { RadioGroup } from './radio-group';
},
encapsulation: ViewEncapsulation.None,
})
export class RadioButton {
export class RadioButton implements OnDestroy, OnInit {
private _checked: boolean = false;
private _disabled: boolean = false;
private _labelId: string;

View File

@ -1,5 +1,5 @@
import { ContentChild, Directive, ElementRef, EventEmitter, forwardRef, Input, Output, Provider, Renderer } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/common';
import { AfterContentInit, ContentChild, Directive, ElementRef, EventEmitter, forwardRef, Input, Output, Provider, Renderer } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ListHeader } from '../list/list';
import { isCheckedProperty } from '../../util/util';
@ -67,7 +67,7 @@ const RADIO_VALUE_ACCESSOR = new Provider(
},
providers: [RADIO_VALUE_ACCESSOR]
})
export class RadioGroup {
export class RadioGroup implements AfterContentInit, ControlValueAccessor {
private _btns: Array<RadioButton> = [];
private _fn: Function;
private _ids: number = -1;
@ -95,6 +95,16 @@ export class RadioGroup {
this.id = ++radioGroupIds;
}
/**
* @private
*/
ngAfterContentInit() {
let activeButton = this._btns.find(b => b.checked);
if (activeButton) {
this._setActive(activeButton);
}
}
/**
* @private
*/
@ -111,23 +121,13 @@ export class RadioGroup {
this._init = true;
}
/**
* @private
*/
ngAfterContentInit() {
let activeButton = this._btns.find(b => b.checked);
if (activeButton) {
this._setActive(activeButton);
}
}
/**
* @private
*/
registerOnChange(fn: Function): void {
this._fn = fn;
this.onChange = (val: any) => {
// onChange used when there's an ngControl
// onChange used when there's an formControlName
console.debug('radio group, onChange', val);
fn(val);
this.value = val;
@ -212,8 +212,8 @@ export class RadioGroup {
* @private
*/
onChange(val: any) {
// onChange used when there is not an ngControl
console.debug('radio group, onChange w/out ngControl', val);
// onChange used when there is not an formControlName
console.debug('radio group, onChange w/out formControlName', val);
this.value = val;
this._update();
this.onTouched();

View File

@ -1,31 +1,31 @@
import {Component} from '@angular/core';
import {ionicBootstrap} from '../../../../../src';
import {Control, ControlGroup} from '@angular/common';
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { ionicBootstrap, RadioButton, RadioGroup } from '../../../../../src';
@Component({
templateUrl: 'main.html'
})
class E2EPage {
fruits: Control;
fruitsForm: ControlGroup;
currenciesControl: Control;
currencyForm: ControlGroup;
fruits: FormControl;
fruitsForm: FormGroup;
currenciesControl: FormControl;
currencyForm: FormGroup;
currencies: Array<string>;
items: Array<{description: string, value: any}>;
relationship: string;
selectedTime: number = 60;
constructor() {
this.fruits = new Control('apple');
this.fruits = new FormControl('apple');
this.fruitsForm = new ControlGroup({
this.fruitsForm = new FormGroup({
'fruits': this.fruits
});
this.currencies = ['USD', 'EUR'];
this.currenciesControl = new Control('EUR');
this.currencyForm = new ControlGroup({
this.currenciesControl = new FormControl('EUR');
this.currencyForm = new FormGroup({
'currenciesControl': this.currenciesControl
});
@ -51,25 +51,25 @@ class E2EPage {
this.fruits.updateValue('cherry');
}
doSubmit(event) {
doSubmit(ev: UIEvent) {
console.log('Submitting form', this.fruitsForm.value);
event.preventDefault();
ev.preventDefault();
}
petChange(ev) {
console.log('petChange', ev);
petChange(radioGroup: RadioGroup) {
console.log('petChange', radioGroup);
}
dogSelect(ev) {
console.log('dogSelect', ev);
dogSelect(radioButton: RadioButton) {
console.log('dogSelect', radioButton);
}
catSelect(ev) {
console.log('catSelect', ev);
catSelect(radioButton: RadioButton) {
console.log('catSelect', radioButton);
}
turtleSelect(ev) {
console.log('turtleSelect', ev);
turtleSelect(radioButton: RadioButton) {
console.log('turtleSelect', radioButton);
}
}

View File

@ -10,9 +10,9 @@
<ion-content>
<form (submit)="doSubmit($event)" [ngFormModel]="fruitsForm">
<form (submit)="doSubmit($event)" [formGroup]="fruitsForm">
<ion-list radio-group ngControl="fruits">
<ion-list radio-group formControlName="fruits">
<ion-list-header>
Fruits
@ -68,8 +68,8 @@
<code><b>fruits.value:</b> {{fruitsForm.controls.fruits.value}}</code><br>
</div>
<form (submit)="doSubmit($event)" [ngFormModel]="currencyForm">
<ion-list radio-group ngControl="currenciesControl">
<form (submit)="doSubmit($event)" [formGroup]="currencyForm">
<ion-list radio-group formControlName="currenciesControl">
<ion-list-header id="currencies">
Currencies
</ion-list-header>

View File

@ -1,5 +1,5 @@
import { Component, ElementRef, EventEmitter, forwardRef, Input, Inject, Optional, Output, Provider, QueryList, Renderer, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/common';
import { AfterViewInit, Component, ElementRef, EventEmitter, forwardRef, Input, Inject, OnDestroy, OnInit, Optional, Output, Provider, QueryList, Renderer, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { clamp, isNumber, isPresent, isString, isTrueProperty } from '../../util/util';
import { Coordinates, pointerCoord, raf } from '../../util/dom';
@ -34,7 +34,7 @@ const RANGE_VALUE_ACCESSOR = new Provider(
'tabindex': '0'
}
})
export class RangeKnob {
export class RangeKnob implements OnInit {
private _ratio: number;
private _val: number;
private _x: string;
@ -195,7 +195,7 @@ export class RangeKnob {
providers: [RANGE_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None,
})
export class Range {
export class Range implements AfterViewInit, ControlValueAccessor, OnDestroy {
private _dual: boolean = false;
private _pin: boolean;
private _disabled: boolean = false;
@ -661,7 +661,7 @@ export class Range {
* @private
*/
onChange(val: any) {
// used when this input does not have an ngModel or ngControl
// used when this input does not have an ngModel or formControlName
this.onTouched();
}

View File

@ -1,5 +1,5 @@
import {Component} from '@angular/core';
import {ionicBootstrap, Range} from '../../../../../src';
import { Component } from '@angular/core';
import { ionicBootstrap, Range } from '../../../../../src';
@Component({
@ -13,8 +13,8 @@ class Page1 {
dualValue: any;
dualValue2 = {lower: 33, upper: 60};
rangeChange(ev: Range) {
console.log(`range, change, ratio: ${ev.ratio}, value: ${ev.value}`);
rangeChange(range: Range) {
console.log(`range, change, ratio: ${range.ratio}, value: ${range.value}`);
}
}

View File

@ -1,9 +1,9 @@
import {Component, Directive, ElementRef, EventEmitter, HostBinding, Input, Optional, Output, ViewChild, ViewEncapsulation} from '@angular/core';
import {NgControl} from '@angular/common';
import { Component, Directive, ElementRef, EventEmitter, HostBinding, Input, Optional, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { NgControl} from '@angular/forms';
import {Config} from '../../config/config';
import {isPresent} from '../../util/util';
import {Debouncer} from '../../util/debouncer';
import { Config } from '../../config/config';
import { isPresent } from '../../util/util';
import { Debouncer } from '../../util/debouncer';
/**

View File

@ -1,6 +1,5 @@
import {Component, ChangeDetectorRef} from '@angular/core';
import {FormBuilder, Validators, Control, ControlGroup} from '@angular/common';
import {ionicBootstrap} from '../../../../../src';
import { Component, ChangeDetectorRef } from '@angular/core';
import { ionicBootstrap } from '../../../../../src';
@Component({

View File

@ -1,5 +1,5 @@
import { Component, ContentChildren, Directive, ElementRef, EventEmitter, HostListener, Input, Output, Optional, QueryList, Renderer, ViewEncapsulation } from '@angular/core';
import { NgControl } from '@angular/common';
import { NgControl } from '@angular/forms';
import { isPresent, isTrueProperty } from '../../util/util';
@ -152,8 +152,8 @@ export class SegmentButton {
* </ion-segment>
*
* <!-- Segment in a form -->
* <form [ngFormModel]="myForm">
* <ion-segment ngControl="mapStyle" danger>
* <form [formGroup]="myForm">
* <ion-segment formControlName="mapStyle" danger>
* <ion-segment-button value="standard">
* Standard
* </ion-segment-button>

View File

@ -1,11 +1,10 @@
import {Component} from '@angular/core';
import {FormBuilder, Validators} from '@angular/common';
import {ionicBootstrap} from '../../../../../src';
import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { ionicBootstrap, SegmentButton } from '../../../../../src';
@Component({
templateUrl: 'main.html',
providers: [FormBuilder]
templateUrl: 'main.html'
})
class E2EPage {
relationship: string = 'enemies';
@ -25,15 +24,15 @@ class E2EPage {
this.isDisabled = !this.isDisabled;
}
onSegmentChanged(segmentButton) {
onSegmentChanged(segmentButton: SegmentButton) {
console.log("Segment changed to", segmentButton.value);
}
onSegmentSelected(segmentButton) {
onSegmentSelected(segmentButton: SegmentButton) {
console.log("Segment selected", segmentButton.value);
}
doSubmit(ev) {
doSubmit(ev: UIEvent) {
console.log('Submitting form', this.myForm.value);
ev.preventDefault();
}

View File

@ -34,10 +34,10 @@
<div>Are we friends or enemies? <b>{{ relationship }}</b></div>
<h4>Map mode: NgControl</h4>
<h4>Map mode: formControlName</h4>
<form (submit)="doSubmit($event)" [ngFormModel]="myForm">
<ion-segment ngControl="mapStyle" danger>
<form (submit)="doSubmit($event)" [formGroup]="myForm">
<ion-segment formControlName="mapStyle" danger>
<ion-segment-button value="active" class="e2eSegmentStandard">
Active
</ion-segment-button>

View File

@ -1,6 +1,5 @@
import {Component} from '@angular/core';
import {Validators, Control, ControlGroup} from '@angular/common';
import {ionicBootstrap, NavController} from '../../../../../src';
import { Component } from '@angular/core';
import { ionicBootstrap, NavController } from '../../../../../src';
@Component({
@ -36,10 +35,7 @@ class SegmentPage {
</ion-content>
`
})
class SegmentPage2 {
constructor() {
}
}
class SegmentPage2 {}
@Component({

View File

@ -1,7 +1,5 @@
import {Component, ViewChild} from '@angular/core';
import {Validators, Control, ControlGroup} from '@angular/common';
import {Http} from '@angular/http';
import {ionicBootstrap, NavController, Slides} from '../../../../../src';
import { Component, ViewChild } from '@angular/core';
import { ionicBootstrap, Slides, SegmentButton } from '../../../../../src';
@Component({
@ -30,7 +28,7 @@ class SegmentPage {
}
onSegmentChanged(segmentButton) {
onSegmentChanged(segmentButton: SegmentButton) {
console.log("Segment changed to", segmentButton.value);
const selectedIndex = this.slides.findIndex((slide) => {
@ -39,7 +37,7 @@ class SegmentPage {
this.sliderComponent.slideTo(selectedIndex);
}
onSlideChanged(slider) {
onSlideChanged(slider: any) {
console.log('Slide changed', slider);
const currentSlide = this.slides[slider.activeIndex];

View File

@ -1,5 +1,5 @@
import { Component, ContentChildren, ElementRef, EventEmitter, forwardRef, Input, HostListener, Optional, Output, Provider, Renderer, QueryList, ViewEncapsulation } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/common';
import { AfterContentInit, Component, ContentChildren, ElementRef, EventEmitter, forwardRef, Input, HostListener, OnDestroy, Optional, Output, Provider, Renderer, QueryList, ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ActionSheet } from '../action-sheet/action-sheet';
import { Alert } from '../alert/alert';
@ -135,7 +135,7 @@ const SELECT_VALUE_ACCESSOR = new Provider(
providers: [SELECT_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None,
})
export class Select {
export class Select implements AfterContentInit, ControlValueAccessor, OnDestroy {
private _disabled: any = false;
private _labelId: string;
private _multi: boolean = false;
@ -217,17 +217,20 @@ export class Select {
}
ev.preventDefault();
ev.stopPropagation();
this._open();
this.open();
}
@HostListener('keyup.space')
private _keyup() {
if (!this._isOpen) {
this._open();
this.open();
}
}
private _open() {
/**
* Open the select interface.
*/
open() {
if (this._disabled) {
return;
}
@ -436,8 +439,8 @@ export class Select {
* @private
*/
onChange(val: any) {
// onChange used when there is not an ngControl
console.debug('select, onChange w/out ngControl', val);
// onChange used when there is not an formControlName
console.debug('select, onChange w/out formControlName', val);
this._values = (Array.isArray(val) ? val : isBlank(val) ? [] : [val]);
this._updOpts();
this.onTouched();

View File

@ -1,6 +1,6 @@
import {Component} from '@angular/core';
import {Control, ControlGroup} from '@angular/common';
import {ionicBootstrap} from '../../../../../src';
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { ionicBootstrap } from '../../../../../src';
@Component({
@ -11,7 +11,7 @@ class E2EPage {
carFeatures: Array<string>;
pets: Array<string>;
petOptions: Array<{text: string, value: string}>;
authForm: ControlGroup;
authForm: FormGroup;
status: string;
constructor() {
@ -27,17 +27,17 @@ class E2EPage {
];
this.status = "checked";
this.authForm = new ControlGroup({
name: new Control(''),
select: new Control([1, '3'])
this.authForm = new FormGroup({
name: new FormControl(''),
select: new FormControl([1, '3'])
});
}
carChange(selectedValues) {
carChange(selectedValues: any) {
console.log('carChange', selectedValues);
}
onSubmit(data) {
onSubmit(data: any) {
console.log('onSubmit', data);
}

View File

@ -66,14 +66,14 @@
<code>pets: {{pets}}</code><br>
</p>
<form [ngFormModel]="authForm" (ngSubmit)="onSubmit(authForm.value)">
<form [formGroup]="authForm" (ngSubmit)="onSubmit(authForm.value)">
<ion-list padding-vertical>
<ion-item>
<ion-input ngControl="name" type="text"></ion-input>
<ion-input formControlName="name" type="text"></ion-input>
</ion-item>
<ion-item class="no-border">
<ion-label>Select</ion-label>
<ion-select multiple="true" ngControl="select">
<ion-select multiple="true" formControlName="select">
<ion-option>1</ion-option>
<ion-option>2</ion-option>
<ion-option>3</ion-option>

View File

@ -1,40 +1,11 @@
import {Component} from '@angular/core';
import {Control, ControlGroup} from '@angular/common';
import {ionicBootstrap} from '../../../../../src';
import { Component } from '@angular/core';
import { ionicBootstrap } from '../../../../../src';
@Component({
templateUrl: 'main.html'
})
class E2EPage {
fruitsForm: ControlGroup;
grapeDisabled = true;
grapeChecked = true;
formResults: any;
constructor() {
this.fruitsForm = new ControlGroup({
"appleCtrl": new Control(),
"bananaCtrl": new Control(true),
"cherryCtrl": new Control(false),
"grapeCtrl": new Control(true)
});
}
toggleGrapeChecked() {
this.grapeChecked = !this.grapeChecked;
}
toggleGrapeDisabled() {
this.grapeDisabled = !this.grapeDisabled;
}
doSubmit(ev) {
console.log('Submitting form', this.fruitsForm.value);
this.formResults = JSON.stringify(this.fruitsForm.value);
ev.preventDefault();
}
}
class E2EPage {}
@Component({

View File

@ -1,6 +1,6 @@
it('should check apple via switch element click', function() {
element(by.css('[ngControl="appleCtrl"]')).click();
element(by.css('[formControlName="appleCtrl"]')).click();
});

View File

@ -1,13 +1,13 @@
import {Component} from '@angular/core';
import {Control, ControlGroup, NgFormModel} from '@angular/common';
import {ionicBootstrap} from '../../../../../src';
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { ionicBootstrap, Toggle } from '../../../../../src';
@Component({
templateUrl: 'main.html'
})
class E2EPage {
fruitsForm: ControlGroup;
fruitsForm: FormGroup;
grapeDisabled: boolean;
grapeChecked: boolean;
kiwiValue: boolean;
@ -15,11 +15,11 @@ class E2EPage {
formResults: string;
constructor() {
this.fruitsForm = new ControlGroup({
"appleCtrl": new Control(false),
"bananaCtrl": new Control(true),
"cherryCtrl": new Control(false),
"grapeCtrl": new Control(true)
this.fruitsForm = new FormGroup({
"appleCtrl": new FormControl(false),
"bananaCtrl": new FormControl(true),
"cherryCtrl": new FormControl(false),
"grapeCtrl": new FormControl(true)
});
this.grapeChecked = true;
@ -34,25 +34,25 @@ class E2EPage {
this.grapeDisabled = !this.grapeDisabled;
}
appleChange(ev) {
console.log('appleChange', ev);
appleChange(toggle: Toggle) {
console.log('appleChange', toggle);
}
bananaChange(ev) {
console.log('bananaChange', ev);
bananaChange(toggle: Toggle) {
console.log('bananaChange', toggle);
}
kiwiChange(ev) {
console.log('kiwiChange', ev);
this.kiwiValue = ev.checked;
kiwiChange(toggle: Toggle) {
console.log('kiwiChange', toggle);
this.kiwiValue = toggle.checked;
}
strawberryChange(ev) {
console.log('strawberryChange', ev);
this.strawberryValue = ev.checked;
strawberryChange(toggle: Toggle) {
console.log('strawberryChange', toggle);
this.strawberryValue = toggle.checked;
}
doSubmit(ev) {
doSubmit(ev: UIEvent) {
console.log('Submitting form', this.fruitsForm.value);
this.formResults = JSON.stringify(this.fruitsForm.value);
ev.preventDefault();

View File

@ -9,7 +9,7 @@
<ion-content>
<form (submit)="doSubmit($event)" [ngFormModel]="fruitsForm">
<form (submit)="doSubmit($event)" [formGroup]="fruitsForm">
<ion-list>
@ -20,27 +20,27 @@
<ion-item>
<ion-label>Apple</ion-label>
<ion-toggle item-left value="apple"></ion-toggle>
<ion-toggle item-left></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Apple, ngControl</ion-label>
<ion-toggle ngControl="appleCtrl" (ionChange)="appleChange($event)"></ion-toggle>
<ion-label>Apple, formControlName</ion-label>
<ion-toggle formControlName="appleCtrl" (ionChange)="appleChange($event)"></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Banana, ngControl</ion-label>
<ion-toggle ngControl="bananaCtrl" (ionChange)="bananaChange($event)"></ion-toggle>
<ion-label>Banana, formControlName</ion-label>
<ion-toggle formControlName="bananaCtrl" (ionChange)="bananaChange($event)"></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Cherry, ngControl, disabled</ion-label>
<ion-toggle disabled="true" ngControl="cherryCtrl"></ion-toggle>
<ion-label>Cherry, formControlName, disabled</ion-label>
<ion-toggle disabled="true" formControlName="cherryCtrl"></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Grape, ngControl, checked, disabled</ion-label>
<ion-toggle [checked]="grapeChecked" [disabled]="grapeDisabled" ngControl="grapeCtrl"></ion-toggle>
<ion-label>Grape, formControlName, checked, disabled</ion-label>
<ion-toggle [checked]="grapeChecked" [disabled]="grapeDisabled" formControlName="grapeCtrl"></ion-toggle>
</ion-item>
<ion-item>

View File

@ -1,5 +1,5 @@
import { Component, ElementRef, EventEmitter, forwardRef, Input, Optional, Output, Provider, Renderer, ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/common';
import { AfterContentInit, Component, ElementRef, EventEmitter, forwardRef, Input, OnDestroy, Optional, Output, Provider, Renderer, ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Form } from '../../util/form';
import { isTrueProperty } from '../../util/util';
@ -70,7 +70,7 @@ const TOGGLE_VALUE_ACCESSOR = new Provider(
providers: [TOGGLE_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None,
})
export class Toggle implements ControlValueAccessor {
export class Toggle implements AfterContentInit, ControlValueAccessor, OnDestroy {
private _checked: boolean = false;
private _init: boolean;
private _disabled: boolean = false;
@ -225,7 +225,7 @@ export class Toggle implements ControlValueAccessor {
* @private
*/
onChange(isChecked: boolean) {
// used when this input does not have an ngModel or ngControl
// used when this input does not have an ngModel or formControlName
console.debug('toggle, onChange (no ngModel)', isChecked);
this._setChecked(isChecked);
this.onTouched();

View File

@ -1,4 +1,5 @@
import { CORE_DIRECTIVES, FORM_DIRECTIVES } from '@angular/common';
import { CORE_DIRECTIVES } from '@angular/common';
import { REACTIVE_FORM_DIRECTIVES } from '@angular/forms';
import { Menu } from '../components/menu/menu';
import { MenuToggle } from '../components/menu/menu-toggle';
@ -120,7 +121,7 @@ import { ShowWhen, HideWhen } from '../components/show-hide-when/show-hide-when'
export const IONIC_DIRECTIVES: any[] = [
// Angular
CORE_DIRECTIVES,
FORM_DIRECTIVES,
REACTIVE_FORM_DIRECTIVES,
// Content
Menu,

View File

@ -1,4 +1,5 @@
import { enableProdMode, PLATFORM_DIRECTIVES, provide } from '@angular/core';
import { disableDeprecatedForms, provideForms } from '@angular/forms';
import { HTTP_PROVIDERS } from '@angular/http';
import { ActionSheetController } from '../components/action-sheet/action-sheet';
@ -59,6 +60,7 @@ export function ionicProviders(customProviders?: Array<any>, config?: any): any[
AlertController,
App,
provide(Config, {useValue: config}),
disableDeprecatedForms(),
provide(Events, {useValue: events}),
provide(FeatureDetect, {useValue: featureDetect}),
Form,
@ -71,6 +73,7 @@ export function ionicProviders(customProviders?: Array<any>, config?: any): any[
PopoverController,
provide(Platform, {useValue: platform}),
provide(PLATFORM_DIRECTIVES, {useValue: IONIC_DIRECTIVES, multi: true}),
provideForms(),
TapClick,
ToastController,
Translate,