[ngForm] does not raise (ngSubmit) like <form> does #7807

Open
Meligy opened this Issue Mar 29, 2016 · 3 comments

Projects

None yet

3 participants

@Meligy
Contributor
Meligy commented Mar 29, 2016

In the ngForm directive documentation, the page says that the directive can be used as an attribute ngForm (selector [ngForm]) and as a <form> element.

I tried to do that, and I failed to get it to work. I'm suspecting it's a bug.

Here's what I tried:

Plunk
(Look for the app/hello_world component)

Relevant Component Template:

<div>Try to edit the text, tab out, 
  then press Enter or click a button:</div>

<!-- 
  The #something="ngForm" is inspired by the thread
  https://github.com/angular/angular/issues/5997
  It's unlikely to be related to the issue
-->

<h3>Broken</h3>
<div ngForm #fBroken="ngForm"
  (submit)='log(["broken", "submit", newName, newTime])'
  (ngSubmit)='log(["broken", "ngSubmit", newName, newTime])'>

  <input type="text" [(ngModel)]="newName"
    (change)='log(["broken", "change (not [ng]Submit)", newName, newTime])'
    #nBroken="ngForm"
    ngControl="nBroken"
    placeholder="Enter a name here">

  <input type="submit" 
    #submitterBroken="ngForm"
    ngControl="submitterBroken"
    ngModel="'submit input'">

  <button type="submit">Submit button</button>
</div>


<h3>Working</h3>

<form #fWorking="ngForm"
  (submit)='log(["working", "submit", newName, newTime])'
  (ngSubmit)='log(["working", "ngSubmit", newName, newTime])'>

  <input type="text" [(ngModel)]="newName"
    (change)='log(["working", "change (not [ng]Submit)", newName, newTime])'
    #nWorking="ngForm"
    ngControl="nWorking"
    placeholder="Enter a name here">

  <input type="submit" 
    #submitterWorking="ngForm"
    ngControl="submitterWorking"
    ngModel="'submit input'">

  <button type="submit">Submit button</button>
</form>

  <hr>
  <!-- conditionally display `yourName` -->
  <pre>{{result}}</pre>

(The extra ngControl stuff etc are just several things I tried to get the first conceptual form to work. I probably could remove them from the working sample but I kept them to show that they are not the reason the first sample is broken)

Version Information

The plunker was created against Angular 2 beta 12, and tested on Chrome 51 for Mac.

Usage Scenario

Why would I want a non <form> element as a form at all?

A simple example is a table where each <tr> is a conceptual form.

Maybe this can be worked around with a parent <form> element around the table, IF the ngSubmit will be triggered from the submit triggers in each <tr ngForm> row (either pressing Enter/Return on a text input, or clicking a submit button), not from the outer table <form> itself (so that the event can be handled and prevented from propagation by the event handler in the row component).

But this stuff worked pretty well in Angular 1.x, and while I understand that this is a rewrite, it would be nice not to lose this when migrating to Angular 2.

Thanks for the awesome libraries by the way :)

Update

I added the working version just to show the difference when creating this issue. The broken version was still broken without it, so, the usage of the same variable for ngModel is not changing the results of the broken one (all the control identifiers are unique though, and again, the same behaviour happens if you delete the working version and only look at the broken one).

@KillerCodeMonkey
KillerCodeMonkey commented Apr 21, 2016 edited

I have a strange behaviour, too.

What i have

  • model-driven-form with ngFormModel
  • simple form with ngSubmit
  • the submit-function calls an async function, which returns an observable
  • in the subscribe-function i change some instance values

What is the problem

  • in my testcase i trigger a click on the submit-button
  • submit-function gets called
  • code coverage shows me, that everything is executed (also the subscription)
  • BUT: my expects are failing --> so the test is not waiting until async stuff finishes or does not recognize async changed values

Solution:

  • i changed ngSubmit to submit -> now it is working
@Meligy
Contributor
Meligy commented Apr 21, 2016 edited

@KillerCodeMonkey I don't think your problem is related to this issue. It could be related to how events are run async (so your ngSubmit handler is likely called async itself).

There is a good post about this behaviour in your own components but it also affects builtin directives.

The Angular team is changing this behaviour from async to sync soon, but it hasn't happened yet. It's tracked in #7421.

I'm not sure if that explains why the submit one works though. Maybe it works differently for some reason as well, which could be related to this issue.

@kara kara referenced this issue Jul 12, 2016
Closed

Support (ngSubmit) for [form] directives #9211

0 of 1 task complete
@kara kara added the comp: forms label Jul 12, 2016
@kara
Contributor
kara commented Oct 17, 2016

@Meligy Currently the ngSubmit event is emitted based on the native form submit event, so it wasn't really designed to work without form tags. That said, I think this would be nice to have, so we'll look into how we can make this work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment