What is recommended approach to validation and enable/disable form submission

2,923 views
Skip to first unread message

Johan Steenkamp

unread,
Mar 30, 2012, 3:16:35 AM3/30/12
to ang...@googlegroups.com
I know there was a thread earlier discussing options to deal with this issue (such as adding ng-model-instant on form etc.) however I am still unclear on what the current recommended approach is to deal with enable/disable of form submission. Recap:

Prior to 1.0.0rcX and ng-model-instant it was easy to enable/disable button like this

<button type="submit" disabled="{{myForm.$invalid}}">Submit</button>

and as soon as form was valid it would be enabled. To do the same in 1.0.0.rcX I have to add ng-model-instant since model is only updated on blur. 

Using blur to update model means a user could submit an invalid form. Complete form so it is valid (submit button would be enabled), then clearing a required field and immediately click submit button (button not disabled at that point).

So I am wondering how the angular team deal with this issue.

Thanks

Johan


Eric Jain

unread,
Mar 30, 2012, 1:29:55 PM3/30/12
to AngularJS
On Mar 30, 12:16 am, Johan Steenkamp <johan.steenk...@gmail.com>
wrote:
> Using blur to update model means a user could submit an invalid form.
> Complete form so it is valid (submit button would be enabled), then
> clearing a required field and immediately click submit button (button not
> disabled at that point).

...or just hit return...

> So I am wondering how the angular team deal with this issue.

I ended up putting ng-model-instant everywhere; would like to know
what the proper way (TM) is, too.

Igor Minar

unread,
Mar 30, 2012, 2:28:00 PM3/30/12
to ang...@googlegroups.com
ng-model-instant was supposed to improve performance of the app by preventing unnecessary digests, but as we learned from our own apps as well as from the feedback from the community it is just causing more  problems than its solving - especially in situations involving form validation.

We brainstormed about how we could fix the situation and the only viable solution that we see in the 1.0 timeframe is making ng-model behave just like ng-model-instant and remove ng-model-instant altogether (so basically reverting to how ng-model behaved prior to rc1).

I'm curious if you or somebody else has any other suggestions.

/i




Johan


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To view this discussion on the web visit https://groups.google.com/d/msg/angular/-/7u-vNDnJM0kJ.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/angular?hl=en.


Eric Jain

unread,
Mar 30, 2012, 2:37:18 PM3/30/12
to ang...@googlegroups.com
On Fri, Mar 30, 2012 at 11:28, Igor Minar <ig...@angularjs.org> wrote:
> I'm curious if you or somebody else has any other suggestions.

Why not have an ng-model-delayed for cases where instant does cause
performance issues?

Johan Steenkamp

unread,
Mar 30, 2012, 3:04:14 PM3/30/12
to ang...@googlegroups.com
Hi Igor

I do not heave any ideas other than those suggested in previous thread on the topic of which easiest from developer point of view is to add ng/model-instant to the form tag and not form fields. Alternative is retain previous behavior and add "ng-model-delayed" on form or fields.

Thanks

Johan
To unsubscribe from this group, send email to angular+unsubscribe@googlegroups.com.

bkc

unread,
Mar 31, 2012, 11:11:50 AM3/31/12
to ang...@googlegroups.com
I like the idea of being able to have 'instant' enabled on only a few fields. I get the impression that enabling 'instant' all the time combined with many bindings will slow down the client a lot.

Would it be reasonable to do something on the submit button by adding an onclick handler that first "recalculates" the model, checks the $valid state and if it's not valid stops propagation of the onclick event?

Maybe form onsubmit (via enter) would also have to be checked in a similar way.

Sorry I'm probably not using the correct phrasing or terms. The objective is to move the overhead of model recalculation to the form submit or button click handlers rather than have every binding recalculate the model on every change.

Peter Bacon Darwin

unread,
Mar 31, 2012, 11:19:56 AM3/31/12
to ang...@googlegroups.com
I was wondering if enabling/disabling the form submission should be done through some kind of change event.  The idea would be that instead of putting ng-model-instant on the fields you have a change event on each input element, which is handled by the enclosing form, this in turn would trigger its own change event which the application developer would handle.  Then you can wrap up any general form validation inside this event: enabling/disabling form submission and so on.  The changed event would be triggered on every change (i.e. instantly) which would give us the opportunity to handle the change before anything else happened, just as ng-model-instant does, but since it is decoupled/isolated from the scope watching mechanism, it wouldn't trigger a mass $digest across the whole application on every change.
Thoughts?
Pete

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To view this discussion on the web visit https://groups.google.com/d/msg/angular/-/MgjuyeFcIicJ.

Johan Steenkamp

unread,
Mar 31, 2012, 3:46:50 PM3/31/12
to ang...@googlegroups.com
You could do that anyway by adding validation test logic in the submit handler. My point it I do not want to enable the button if the form is invalid. So I could use a $watcher but that makes me think I am doing what angular was do for me automatically before (or when using ng-model-instant). Since CRUD (and hence forms) are a key application area for Angular that does not makes sense - it should make it easy.

Johan Steenkamp

unread,
Mar 31, 2012, 3:48:31 PM3/31/12
to ang...@googlegroups.com
An option is to use a $watcher the form/data which would be same as a change event in that it responds to the form/model changes.
Pete

To unsubscribe from this group, send email to angular+unsubscribe@googlegroups.com.
Pete

To unsubscribe from this group, send email to angular+unsubscribe@googlegroups.com.

Eric Jain

unread,
Mar 31, 2012, 3:52:47 PM3/31/12
to ang...@googlegroups.com
On Sat, Mar 31, 2012 at 12:46, Johan Steenkamp
<johan.s...@gmail.com> wrote:
> You could do that anyway by adding validation test logic in the submit
> handler.

Can I set the form's (and input's) $valid property from a submit
handler? How does that look like?

Peter Bacon Darwin

unread,
Mar 31, 2012, 4:18:23 PM3/31/12
to ang...@googlegroups.com
Hi Johan

I don't think I was clear enough or may be I am missing something.  My idea was to have the core angular library altered so that the following would happen...
  • On any change to an input control, there would be an instantaneous "changed" event triggered ny the input element - similar to what ng-model-instant does but without causing a $digest loop.
  • Any enclosing form would catch this and then trigger its own "changed" event, again not causing any watches to be evaluated.
  • The application developer (i.e. you or me) could then choose to listen for this form "changed" event and have the opportunity to update the scope instantaneously - such as disabling the submit button.  In other words not having to wait for blur and normal watches to be evaluated.
This would be effective because you would get an instant opportunity to change the state of the buttons and so on, while being efficient as no watches are evaulated unless your handler changes something.

You cannot do this already.  Validation logic in the submit handler is run only after the submit has been triggered.  You could use a watcher and have ng-model-instant on everything but then performance is killed because every time you touch any input element the entire application's watches are evaluated.

Pete 



--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To view this discussion on the web visit https://groups.google.com/d/msg/angular/-/ZhdyacYboJ8J.

Johan Steenkamp

unread,
Apr 1, 2012, 3:19:35 PM4/1/12
to ang...@googlegroups.com
Hi Peter

Thanks for details. Could try your approach using standard events - easy with jQuery to use delegated events, say keyup on form.

My intention was that the button is enabled to allow the submit logic to perform the validation - which is not my preferred approach, I'd rather not enable the submit button. That said as Eric pointed out you could still hit return even with the button disabled - but that would only be a problem if you attach the submit handler to the form and not the button (I think - did not test).

Regards

Johan

Hi Johan
To unsubscribe from this group, send email to angular+unsubscribe@googlegroups.com.

Peter Bacon Darwin

unread,
Apr 1, 2012, 3:26:42 PM4/1/12
to ang...@googlegroups.com
It is definitely an issue that needs to be addressed.  I think a delegated event could work as long as the directives do not stop event bubbling.  I would prefer, though, to see an AngularJS standardized method for dealing with this.
Pete

To view this discussion on the web visit https://groups.google.com/d/msg/angular/-/oM89DTFtwIkJ.

To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.

Kai Groner

unread,
Apr 3, 2012, 8:49:40 AM4/3/12
to ang...@googlegroups.com
I've been thinking about this, here are a few thoughts:

It seems like validators should run even if the model isn't being updated right away.  A short timeout might help run the validator less often (maybe Angular does this already).

The model could be updated immediately without firing an ng-change event; this is what browsers do now.  Instead of reverting ng-change behavior, an ng-input event (like the html5 input event) could be used for immediate notifications.

This doesn't do anything to avoid frequent digests.  Peter's idea to limit the scope of a digest seems like a good one, but the use of event propagation here feels incomplete because an async event outside the form could still cause an update.  Having a copy of the form data and controlling when the changes are flushed might be better.  But then there are two copies of the data, bound, but not synchronously.  I don't know about this piece.


Kai

Misko Hevery

unread,
Apr 3, 2012, 1:00:47 PM4/3/12
to ang...@googlegroups.com
We are thinking about this, but right now it is on back burner until after 1.0. 

Johan Steenkamp

unread,
Apr 3, 2012, 6:08:36 PM4/3/12
to ang...@googlegroups.com
No problem - happy to wait for you to decide on the best solution given your broader view of the technical issues and trade-offs.

New Angular logo and site look great :)

To unsubscribe from this group, send email to angular+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/angular?hl=en.

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/angular?hl=en.

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+unsubscribe@googlegroups.com.

Robert B. Weeks

unread,
Apr 3, 2012, 6:35:48 PM4/3/12
to ang...@googlegroups.com
Hey Misko - 

On Apr 3, 2012, at 1:00 PM, Misko Hevery wrote:

We are thinking about this, but right now it is on back burner until after 1.0. 

Does having it on the back burner until after 1.0 include what Igor was saying below? Or will we have to ng-model-instant for 1.0 release? 

Thanks.



On Fri, Mar 30, 2012 at 2:28 PM, Igor Minar <ig...@angularjs.org> wrote:
ng-model-instant was supposed to improve performance of the app by preventing unnecessary digests, but as we learned from our own apps as well as from the feedback from the community it is just causing more  problems than its solving - especially in situations involving form validation.

We brainstormed about how we could fix the situation and the only viable solution that we see in the 1.0 timeframe is making ng-model behave just like ng-model-instant and remove ng-model-instant altogether (so basically reverting to how ng-model behaved prior to rc1).

I'm curious if you or somebody else has any other suggestions.

/i



--
Robert B. Weeks

Misko Hevery

unread,
Apr 4, 2012, 1:54:13 PM4/4/12
to ang...@googlegroups.com
It has already been removed in the master, and will be in the next release.

--

Johan

unread,
Apr 5, 2012, 5:25:25 AM4/5/12
to ang...@googlegroups.com
Thanks for confirmation. 
To unsubscribe from this group, send email to angular+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages