Skip to content

Commit 5fc23ca

Browse files
committed
feat(forms): changed forms to capture submit events and fires synthetic ng-submit events
1 parent 1a4d237 commit 5fc23ca

File tree

3 files changed

+77
-11
lines changed

3 files changed

+77
-11
lines changed

modules/angular2/src/forms/directives/form_model_directive.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {CONST_EXPR} from 'angular2/src/facade/lang';
22
import {List, ListWrapper} from 'angular2/src/facade/collection';
3+
import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
4+
35
import {Directive, onChange} from 'angular2/angular2';
46
import {FORWARD_REF, Binding} from 'angular2/di';
57
import {ControlDirective} from './control_directive';
@@ -57,11 +59,16 @@ const formDirectiveBinding = CONST_EXPR(
5759
selector: '[ng-form-model]',
5860
hostInjector: [formDirectiveBinding],
5961
properties: ['form: ng-form-model'],
60-
lifecycle: [onChange]
62+
lifecycle: [onChange],
63+
hostListeners: {
64+
'submit': 'onSubmit()',
65+
},
66+
events: ['ngSubmit']
6167
})
6268
export class FormModelDirective extends ControlContainerDirective implements FormDirective {
6369
form: ControlGroup = null;
6470
directives: List<ControlDirective>;
71+
ngSubmit = new EventEmitter();
6572

6673
constructor() {
6774
super();
@@ -94,6 +101,11 @@ export class FormModelDirective extends ControlContainerDirective implements For
94101
c.updateValue(value);
95102
}
96103

104+
onSubmit() {
105+
ObservableWrapper.callNext(this.ngSubmit, null);
106+
return false;
107+
}
108+
97109
_updateDomValue() {
98110
ListWrapper.forEach(this.directives, dir => {
99111
var c: any = this.form.find(dir.path);

modules/angular2/src/forms/directives/template_driven_form_directive.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {PromiseWrapper} from 'angular2/src/facade/async';
1+
import {PromiseWrapper, ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
22
import {StringMapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
33
import {isPresent, CONST_EXPR} from 'angular2/src/facade/lang';
44
import {Directive} from 'angular2/src/core/annotations/decorators';
@@ -15,11 +15,16 @@ const formDirectiveBinding = CONST_EXPR(new Binding(
1515

1616
@Directive({
1717
selector: 'form:not([ng-no-form]):not([ng-form-model]),ng-form,[ng-form]',
18-
hostInjector: [formDirectiveBinding]
18+
hostInjector: [formDirectiveBinding],
19+
hostListeners: {
20+
'submit': 'onSubmit()',
21+
},
22+
events: ['ngSubmit']
1923
})
2024
export class TemplateDrivenFormDirective extends ControlContainerDirective implements
2125
FormDirective {
2226
form: ControlGroup;
27+
ngSubmit = new EventEmitter();
2328

2429
constructor() {
2530
super();
@@ -34,36 +39,44 @@ export class TemplateDrivenFormDirective extends ControlContainerDirective imple
3439

3540
get value(): any { return this.form.value; }
3641

42+
get errors(): any { return this.form.errors; }
43+
3744
addControl(dir: ControlDirective): void {
3845
this._later(_ => {
39-
var group = this._findContainer(dir.path);
46+
var container = this._findContainer(dir.path);
4047
var c = new Control("");
4148
setUpControl(c, dir);
42-
group.addControl(dir.name, c);
49+
container.addControl(dir.name, c);
50+
c.updateValidity();
4351
});
4452
}
4553

4654
getControl(dir: ControlDirective): Control { return <Control>this.form.find(dir.path); }
4755

4856
removeControl(dir: ControlDirective): void {
4957
this._later(_ => {
50-
var c = this._findContainer(dir.path);
51-
if (isPresent(c)) c.removeControl(dir.name)
58+
var container = this._findContainer(dir.path);
59+
if (isPresent(container)) {
60+
container.removeControl(dir.name) container.updateValidity();
61+
}
5262
});
5363
}
5464

5565
addControlGroup(dir: ControlGroupDirective): void {
5666
this._later(_ => {
57-
var group = this._findContainer(dir.path);
67+
var container = this._findContainer(dir.path);
5868
var c = new ControlGroup({});
59-
group.addControl(dir.name, c);
69+
container.addControl(dir.name, c);
70+
c.updateValidity();
6071
});
6172
}
6273

6374
removeControlGroup(dir: ControlGroupDirective): void {
6475
this._later(_ => {
65-
var c = this._findContainer(dir.path);
66-
if (isPresent(c)) c.removeControl(dir.name)
76+
var container = this._findContainer(dir.path);
77+
if (isPresent(container)) {
78+
container.removeControl(dir.name) container.updateValidity();
79+
}
6780
});
6881
}
6982

@@ -74,6 +87,11 @@ export class TemplateDrivenFormDirective extends ControlContainerDirective imple
7487
});
7588
}
7689

90+
onSubmit() {
91+
ObservableWrapper.callNext(this.ngSubmit, null);
92+
return false;
93+
}
94+
7795
_findContainer(path: List<string>): ControlGroup {
7896
ListWrapper.removeLast(path);
7997
return <ControlGroup>this.form.find(path);

modules/angular2/test/forms/integration_spec.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,25 @@ export function main() {
7474
});
7575
}));
7676

77+
it("should emit ng-submit event on submit",
78+
inject([TestBed], fakeAsync(tb => {
79+
var form = new ControlGroup({});
80+
var ctx = MyComp.create({form: form, name: 'old'});
81+
82+
var t =
83+
`<div><form [ng-form-model]="form" (ng-submit)="name='updated'"></form></div>`;
84+
85+
tb.createView(MyComp, {context: ctx, html: t})
86+
.then((view) => {
87+
var form = view.querySelector("form");
88+
89+
dispatchEvent(form, "submit");
90+
tick();
91+
92+
expect(ctx.name).toEqual("updated");
93+
});
94+
})));
95+
7796
it("should work with single controls", inject([TestBed, AsyncTestCompleter], (tb, async) => {
7897
var control = new Control("loginValue");
7998
var ctx = MyComp.create({form: control});
@@ -473,6 +492,23 @@ export function main() {
473492
});
474493
})));
475494

495+
it("should emit ng-submit event on submit",
496+
inject([TestBed], fakeAsync(tb => {
497+
var ctx = MyComp.create({name: 'old'});
498+
499+
var t = `<div><form (ng-submit)="name='updated'"></form></div>`;
500+
501+
tb.createView(MyComp, {context: ctx, html: t})
502+
.then((view) => {
503+
var form = view.querySelector("form");
504+
505+
dispatchEvent(form, "submit");
506+
tick();
507+
508+
expect(ctx.name).toEqual("updated");
509+
});
510+
})));
511+
476512
it("should not create a template-driven form when ng-no-form is used",
477513
inject([TestBed], fakeAsync(tb => {
478514
var ctx = MyComp.create({name: null});

0 commit comments

Comments
 (0)