-
Notifications
You must be signed in to change notification settings - Fork 27.5k
More states for form validation #583
Comments
People have been struggling with premature validation, where the form inputs are marked as invalid before the user even touches the form. I recommended that they use It appears there are no class changes to the form when a submit of the form is attempted (regardless of fail or pass). I have created a demo that shows a simple fix for this: http://plnkr.co/edit/172Vlv?p=preview and caters to both scenarios (premature validation and skipping validation altogether) from a visual perspective. tl;drRemove the |
I've been struggling with this as well; ng-pristine / NgModelController.$pristine, as implemented, isn't especially useful. The user needs at least some chance to enter information correctly before being scolded. A state which is set once the user has interacted with, but then left, the control would be appropriate. (i.e. |
I agree with the above. $dirty is too aggressive - users shouldn't be shown an error UI state until after they've blurred out of the element. |
+1 |
A useful state would be $attemped. |
can't you already use the dirty state for that? |
Not sure how this issue came up again, but... We've already planned this out and the solution is to have a few extra states:
The forms themselves are pretty good, but there needs to be more control over when messages are displayed. These flags should fill that hole. |
Not actually @caitp, i'm addressing the case when a user sees a Form and instantly presses the submit button having no interaction with any of its components. There, the way I see it, it would desirable to point out which fields are required for example. That's why an $attempted state would be very adequate. @matsko what you are calling $submitted is very close to what I'm thinking of.
Thanks to both of you for your replies, regards. |
In that particular case, it still sounds like something which could be accomplished with ng-submit + $pristine, since the FormController's $pristine should be true if all of its controls are pristine, or even just iterating over all of the forms controls. It might be possible to make implementing this more elegant, but it should already be quite possible (of course, this requires the submit event to happen, but I guess you could bind a click event to the submit button also to make whatever changes happen that need to happen) Note, I'm not saying we shouldn't try to make this nicer, I'm just saying you might be able to solve your problem adequately already |
You are right @caitp, it is possible to achieve the way you described. I actually used this directive http://code.realcrowd.com/on-the-bleeding-edge-advanced-angularjs-form-validation/ |
Here is @matsko's design doc for improving forms: https://docs.google.com/a/google.com/document/d/192dCUnoIBQ7-vurvPeS9BElGdxfk0Ddcof2KzDDi1Mc/edit |
@jeffbcross @matsko So honestly, the @angular-ui team tried to tackle simplifying form validation a few different times with ui-input:
The gist was that you would create a template snippet which would switch between all the different input types, automatically generating labels, surrounding html ( Example:<script type="text/ng-template" id="vert-form">
<div class="form-group" ng-class="{error:$input.error}">
<ng-switch on="$input.type">
<textarea ng-switch-when="textarea" name="{{$input.name}}"></textarea>
...
</ng-switch>
<div class="help" ng-repeat="(errorName, error) in $input.$errors" ng-switch="errorName">
<span ng-switch-when="required">The {{$input.name}} field cannot be left empty</span>
...
</div>
</div>
</script>
<form name="vert-form">
<!-- or <div ng-form="vert-form"> -->
<ui-input type="textarea" ng-model="data.item" required max-length="3" />
<!-- or <ui-input template="vert-form" ...> to override/specify on a field-by-field basis -->
</form> The The Problem:The big issue we ran into however was that we wanted to transclude to a few different places in the resultant template, AND we weren't able to use |
@ProLoser let's figure out the naming system first so that all the new features can actually be possible. |
#5888 I've send a PR for adding a $dirtyAfter state for controls, which could greatly improve the decision to display or not inline validation messages. For example, an inline validation message can be shown using the condition "myForm.myField.$dirty || myForm.myField.$dirtyAfter". I also think a form level "attempted" state would be a great idea, and it would work well along $dirtyAfter by using the following condition for showing/hiding inline validation messages "myForm.$attempted || myForm.myField.$dirty || myForm.myField.$dirtyAfter" |
add $dirtyAfter state to form controls to help with inline form validation contribute to issue angular#583
I love the approach to not let user type letters in field that is expected to be digits only etc. This, combined with visual and/or audio feedback (don't forget the disabled people) saved me a lot of time on typing validations. How about ng-accept and ng-reject? Like <input ng-accept='/\d/'> also enhanced by characters sets constants, like <input ng-accept='navigation, digits'> |
Any idea on when input.$blurred and others are coming? |
We're almost done releasing the AngularDart forms. For this release, we're prototyping some of the new features including submit flags, touched/untouched (blurred), subforms, resetting and possibly multi-error message controls. Once this is all said and done this will be ported over to the JS side. |
hi, when $blurred is coming up in angularjs??? i'm waiting.. |
@matsko Any updates on when that will get ported over to the JS side? |
@daviesgeek I would guess Angular 2.0 |
@2ix okay |
touched (blurred) is simple to implement https://gist.github.com/guzart/e4ecea64f509f9d5062d |
@guzart sorry I've been very busy refactoring the validators for ngModel. Could you put together a Pull Request for that and then I can review it? Remember to include the docs + tests. |
@matsko I'll take a stab at it this weekend |
Excellent. Remember that |
@guzart @matsko, I've a pending pull request with an $attempted status. I didn't used the word $submitted cause the submision can be prevented due to validations. @IgorMinar asked for another name instead of $attempted, I believe he doesn't like the idea of $submitted. |
@matsko I would've thought that Personally I prefer |
Sets the ngModel controller property $touched to True and $untouched to False whenever a 'blur' event is triggered over a control with the ngModel directive. Also adds the $setTouched and $setUntouched methods to the NgModelController. References #583
validation on blur would be very nice |
@coli that can be done using |
@matsko Thanks, learned something new today. |
Should a call to setPristine on NgModelController also set the controller to untouched? In RC1 it does not. So a reset function that calls setPristine and empties the model clears a form but validation error messages (required errors) still appear. |
@mdsauer the required error on empty inputs is always set, even if the form hasn't been touched yet. When a user leaves (blurs) the input, the ng-touched class is added to it and $touched is set to true. You can use this in your error display logic - only display when error is set and touched is true. When you reset the form, call $setUntouched on it. |
Thanks @Narretz . My initial thought was to call a $setUntouched method but I do not see that method on the form in 1.3 RC1. Is it being added? |
Oh, true. It's only available on the ngModelController. We should probably add it. |
For now, $touched is set to true on blur event. Why not set $touched to true only if the value has been changed ? var ngModelDirective = function() {
// ... snip...
post: function(scope, element, attr, ctrls) {
// ... snip...
var lastValue = element.val();
element.on('blur', function(ev) {
if (lastValue === element.val()) return;
lastValue = element.val();
if (modelCtrl.$touched) return;
scope.$apply(function() {
modelCtrl.$setTouched();
});
});
}
}; |
@marmotz: Isn't that what |
Yes, you're right. At the beggining of this issue, someone said that show errors while user type is a bad thing.
You see what I mean? |
$touched was specifically implemented for the case that a user tabs through a form and leaves inputs invalid. It happens far more often that you blur an input and leave it invalid, then accidentially clicking an input, then blurring it. |
Ok, so i don't understand the use case. On the other hand, display an error while you just begin to type an email "Invalid email !!!" is a bad practice. |
It sounds like the condition you need is
|
@shahata: This won't work for the particular scenario @marmotz described: When the user clicks on the element, clicks away then clicks again and edits. It will be Nonetheless, it is a very far-fetched and "corner-case-y" scenario and adding states to identify every possible weird user interraction with form-controls would create a mess with very small benefit (imo). |
@gkalpak thanks for the demo but I already did my own directive like yours :) In fact, i think it's not a "corner-case-y" scenario. Demo: http://jsfiddle.net/marmotz/orcsjyLs/2/
It's a "corner-case-y" scenario ? |
@marmotz: There a probably a dozen different use-cases that different people might want to support. Adding 2 properties ( Hm...reading your comments again seems like you are not suggesting a new property, but a change in when the |
I'm going to close this issue since I believe that we added the states that we initially wanted to add. If there are any left over issues please open new issues. thanks! |
Can someone confirm that there was never any implementation of $attempted? $submitted not so useful to me so I'll continue using custom code like @nicoabie based on: http://code.realcrowd.com/on-the-bleeding-edge-advanced-angularjs-form-validation/ ...Actually perhaps they are really the same thing, just a different name? As in it $submitted gets set just before calling the ng-submit handler? I probably need to keep what I have anyway for other reasons. |
@darrenshrwd No, $attempted was never implemented. Depending on your use case, $pristine together with $submitted might be the way to go. |
After reading this: http://www.alistapart.com/articles/inline-validation-in-web-forms/
In order to implement on blur, there needs to be more states to forms then just pristine and dirty. The gold standard should be to validate all the time, but updating the UI only when user navigates away from the widget.
The text was updated successfully, but these errors were encountered: