feat(forms): changed forms to capture submit events and fires synthetic ng-submit events
This commit is contained in:
		
							parent
							
								
									1a4d23742b
								
							
						
					
					
						commit
						5fc23caef7
					
				@ -1,5 +1,7 @@
 | 
				
			|||||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
 | 
					import {CONST_EXPR} from 'angular2/src/facade/lang';
 | 
				
			||||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
 | 
					import {List, ListWrapper} from 'angular2/src/facade/collection';
 | 
				
			||||||
 | 
					import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {Directive, onChange} from 'angular2/angular2';
 | 
					import {Directive, onChange} from 'angular2/angular2';
 | 
				
			||||||
import {FORWARD_REF, Binding} from 'angular2/di';
 | 
					import {FORWARD_REF, Binding} from 'angular2/di';
 | 
				
			||||||
import {ControlDirective} from './control_directive';
 | 
					import {ControlDirective} from './control_directive';
 | 
				
			||||||
@ -57,11 +59,16 @@ const formDirectiveBinding = CONST_EXPR(
 | 
				
			|||||||
  selector: '[ng-form-model]',
 | 
					  selector: '[ng-form-model]',
 | 
				
			||||||
  hostInjector: [formDirectiveBinding],
 | 
					  hostInjector: [formDirectiveBinding],
 | 
				
			||||||
  properties: ['form: ng-form-model'],
 | 
					  properties: ['form: ng-form-model'],
 | 
				
			||||||
  lifecycle: [onChange]
 | 
					  lifecycle: [onChange],
 | 
				
			||||||
 | 
					  hostListeners: {
 | 
				
			||||||
 | 
					    'submit': 'onSubmit()',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  events: ['ngSubmit']
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class FormModelDirective extends ControlContainerDirective implements FormDirective {
 | 
					export class FormModelDirective extends ControlContainerDirective implements FormDirective {
 | 
				
			||||||
  form: ControlGroup = null;
 | 
					  form: ControlGroup = null;
 | 
				
			||||||
  directives: List<ControlDirective>;
 | 
					  directives: List<ControlDirective>;
 | 
				
			||||||
 | 
					  ngSubmit = new EventEmitter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor() {
 | 
					  constructor() {
 | 
				
			||||||
    super();
 | 
					    super();
 | 
				
			||||||
@ -94,6 +101,11 @@ export class FormModelDirective extends ControlContainerDirective implements For
 | 
				
			|||||||
    c.updateValue(value);
 | 
					    c.updateValue(value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onSubmit() {
 | 
				
			||||||
 | 
					    ObservableWrapper.callNext(this.ngSubmit, null);
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _updateDomValue() {
 | 
					  _updateDomValue() {
 | 
				
			||||||
    ListWrapper.forEach(this.directives, dir => {
 | 
					    ListWrapper.forEach(this.directives, dir => {
 | 
				
			||||||
      var c: any = this.form.find(dir.path);
 | 
					      var c: any = this.form.find(dir.path);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
 | 
					import {PromiseWrapper, ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
 | 
				
			||||||
import {StringMapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
 | 
					import {StringMapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
 | 
				
			||||||
import {isPresent, CONST_EXPR} from 'angular2/src/facade/lang';
 | 
					import {isPresent, CONST_EXPR} from 'angular2/src/facade/lang';
 | 
				
			||||||
import {Directive} from 'angular2/src/core/annotations/decorators';
 | 
					import {Directive} from 'angular2/src/core/annotations/decorators';
 | 
				
			||||||
@ -15,11 +15,16 @@ const formDirectiveBinding = CONST_EXPR(new Binding(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@Directive({
 | 
					@Directive({
 | 
				
			||||||
  selector: 'form:not([ng-no-form]):not([ng-form-model]),ng-form,[ng-form]',
 | 
					  selector: 'form:not([ng-no-form]):not([ng-form-model]),ng-form,[ng-form]',
 | 
				
			||||||
  hostInjector: [formDirectiveBinding]
 | 
					  hostInjector: [formDirectiveBinding],
 | 
				
			||||||
 | 
					  hostListeners: {
 | 
				
			||||||
 | 
					    'submit': 'onSubmit()',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  events: ['ngSubmit']
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class TemplateDrivenFormDirective extends ControlContainerDirective implements
 | 
					export class TemplateDrivenFormDirective extends ControlContainerDirective implements
 | 
				
			||||||
    FormDirective {
 | 
					    FormDirective {
 | 
				
			||||||
  form: ControlGroup;
 | 
					  form: ControlGroup;
 | 
				
			||||||
 | 
					  ngSubmit = new EventEmitter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor() {
 | 
					  constructor() {
 | 
				
			||||||
    super();
 | 
					    super();
 | 
				
			||||||
@ -34,12 +39,15 @@ export class TemplateDrivenFormDirective extends ControlContainerDirective imple
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  get value(): any { return this.form.value; }
 | 
					  get value(): any { return this.form.value; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get errors(): any { return this.form.errors; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  addControl(dir: ControlDirective): void {
 | 
					  addControl(dir: ControlDirective): void {
 | 
				
			||||||
    this._later(_ => {
 | 
					    this._later(_ => {
 | 
				
			||||||
      var group = this._findContainer(dir.path);
 | 
					      var container = this._findContainer(dir.path);
 | 
				
			||||||
      var c = new Control("");
 | 
					      var c = new Control("");
 | 
				
			||||||
      setUpControl(c, dir);
 | 
					      setUpControl(c, dir);
 | 
				
			||||||
      group.addControl(dir.name, c);
 | 
					      container.addControl(dir.name, c);
 | 
				
			||||||
 | 
					      c.updateValidity();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -47,23 +55,28 @@ export class TemplateDrivenFormDirective extends ControlContainerDirective imple
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  removeControl(dir: ControlDirective): void {
 | 
					  removeControl(dir: ControlDirective): void {
 | 
				
			||||||
    this._later(_ => {
 | 
					    this._later(_ => {
 | 
				
			||||||
      var c = this._findContainer(dir.path);
 | 
					      var container = this._findContainer(dir.path);
 | 
				
			||||||
      if (isPresent(c)) c.removeControl(dir.name)
 | 
					      if (isPresent(container)) {
 | 
				
			||||||
 | 
					        container.removeControl(dir.name) container.updateValidity();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  addControlGroup(dir: ControlGroupDirective): void {
 | 
					  addControlGroup(dir: ControlGroupDirective): void {
 | 
				
			||||||
    this._later(_ => {
 | 
					    this._later(_ => {
 | 
				
			||||||
      var group = this._findContainer(dir.path);
 | 
					      var container = this._findContainer(dir.path);
 | 
				
			||||||
      var c = new ControlGroup({});
 | 
					      var c = new ControlGroup({});
 | 
				
			||||||
      group.addControl(dir.name, c);
 | 
					      container.addControl(dir.name, c);
 | 
				
			||||||
 | 
					      c.updateValidity();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  removeControlGroup(dir: ControlGroupDirective): void {
 | 
					  removeControlGroup(dir: ControlGroupDirective): void {
 | 
				
			||||||
    this._later(_ => {
 | 
					    this._later(_ => {
 | 
				
			||||||
      var c = this._findContainer(dir.path);
 | 
					      var container = this._findContainer(dir.path);
 | 
				
			||||||
      if (isPresent(c)) c.removeControl(dir.name)
 | 
					      if (isPresent(container)) {
 | 
				
			||||||
 | 
					        container.removeControl(dir.name) container.updateValidity();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -74,6 +87,11 @@ export class TemplateDrivenFormDirective extends ControlContainerDirective imple
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onSubmit() {
 | 
				
			||||||
 | 
					    ObservableWrapper.callNext(this.ngSubmit, null);
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _findContainer(path: List<string>): ControlGroup {
 | 
					  _findContainer(path: List<string>): ControlGroup {
 | 
				
			||||||
    ListWrapper.removeLast(path);
 | 
					    ListWrapper.removeLast(path);
 | 
				
			||||||
    return <ControlGroup>this.form.find(path);
 | 
					    return <ControlGroup>this.form.find(path);
 | 
				
			||||||
 | 
				
			|||||||
@ -74,6 +74,25 @@ export function main() {
 | 
				
			|||||||
             });
 | 
					             });
 | 
				
			||||||
       }));
 | 
					       }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it("should emit ng-submit event on submit",
 | 
				
			||||||
 | 
					       inject([TestBed], fakeAsync(tb => {
 | 
				
			||||||
 | 
					                var form = new ControlGroup({});
 | 
				
			||||||
 | 
					                var ctx = MyComp.create({form: form, name: 'old'});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var t =
 | 
				
			||||||
 | 
					                    `<div><form [ng-form-model]="form" (ng-submit)="name='updated'"></form></div>`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                tb.createView(MyComp, {context: ctx, html: t})
 | 
				
			||||||
 | 
					                    .then((view) => {
 | 
				
			||||||
 | 
					                      var form = view.querySelector("form");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                      dispatchEvent(form, "submit");
 | 
				
			||||||
 | 
					                      tick();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                      expect(ctx.name).toEqual("updated");
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					              })));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it("should work with single controls", inject([TestBed, AsyncTestCompleter], (tb, async) => {
 | 
					    it("should work with single controls", inject([TestBed, AsyncTestCompleter], (tb, async) => {
 | 
				
			||||||
         var control = new Control("loginValue");
 | 
					         var control = new Control("loginValue");
 | 
				
			||||||
         var ctx = MyComp.create({form: control});
 | 
					         var ctx = MyComp.create({form: control});
 | 
				
			||||||
@ -473,6 +492,23 @@ export function main() {
 | 
				
			|||||||
                      });
 | 
					                      });
 | 
				
			||||||
                })));
 | 
					                })));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it("should emit ng-submit event on submit",
 | 
				
			||||||
 | 
					         inject([TestBed], fakeAsync(tb => {
 | 
				
			||||||
 | 
					                  var ctx = MyComp.create({name: 'old'});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  var t = `<div><form (ng-submit)="name='updated'"></form></div>`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  tb.createView(MyComp, {context: ctx, html: t})
 | 
				
			||||||
 | 
					                      .then((view) => {
 | 
				
			||||||
 | 
					                        var form = view.querySelector("form");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        dispatchEvent(form, "submit");
 | 
				
			||||||
 | 
					                        tick();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        expect(ctx.name).toEqual("updated");
 | 
				
			||||||
 | 
					                      });
 | 
				
			||||||
 | 
					                })));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it("should not create a template-driven form when ng-no-form is used",
 | 
					      it("should not create a template-driven form when ng-no-form is used",
 | 
				
			||||||
         inject([TestBed], fakeAsync(tb => {
 | 
					         inject([TestBed], fakeAsync(tb => {
 | 
				
			||||||
                  var ctx = MyComp.create({name: null});
 | 
					                  var ctx = MyComp.create({name: null});
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user