New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

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

Comments

Projects
None yet
4 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

This comment has been minimized.

Show comment
Hide comment
@KillerCodeMonkey

KillerCodeMonkey Apr 21, 2016

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

KillerCodeMonkey commented Apr 21, 2016

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

This comment has been minimized.

Show comment
Hide comment
@Meligy

Meligy Apr 21, 2016

Contributor

@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.

Contributor

Meligy commented Apr 21, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@kara

kara Oct 17, 2016

Contributor

@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.

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.

@DzmitryShylovich

This comment has been minimized.

Show comment
Hide comment
@DzmitryShylovich

DzmitryShylovich Feb 26, 2017

Contributor

@Meligy could you update your plunkr please?

Contributor

DzmitryShylovich commented Feb 26, 2017

@Meligy could you update your plunkr please?

@ngbot ngbot bot added this to the Backlog milestone Jan 23, 2018

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