Is there any way to pass an error message in custom form validation?
E.g. I have a directive that checks a username. There are three possible outcomes:
It is valid
It is invalid because it isn't a good username ("this.is-invalid")
It is invalid because it is already in use
I have a directive like (simplified pseudo-html):
<input type="text" namecheck></input><span ng-show="name.$error.namecheck">You had an error {{ error }}</span>
And in my custom directive, I can do
// check for a conflict and valid name here
ngModel.$setValidity("namecheck",false);
But how do I pass an error message that indicates if the problem was a conflict or invalid name? Is there anything like ngModel.$setValidityErrorMessage() ?
As I wrote in the comments, I just figured it out. I just need to use different validity flags. Nothing says that I have to use the same key in $setValidity() as the name of the directive!
<span ng-show="name.$error.nameinvalid">This is not a valid username, it must be alphanmueric</span>
<span ng-show="name.$error.nametaken">Sorry, the username {{ name }} is already taken</span>
And in the directive
// if I got a 409
ngModel.$setValidity("nametaken",false);
// if I got a 400
ngModel.$setValidity("nameinvalid",false);
The name of the $error is the error message!
No. Setting the validity on a form element just simply adds the appropriate class to the element, which can then be used to style the element to indicate an error. There aren't any error messages that indicate why the element is invalid. Angular doesn't provide that support.
You may have noticed error messages that pop up on required fields that are empty? In chrome they say something like: "Please fill out this field" or something. Those are browser-specific and aren't related to angular in any way.
You'd have to roll your own error messaging service. You can use the same ng-invalid classes to check when a form element is invalid and show the error messages based on that, but Angular doesn't provide that out of the box.
There is an example in the angular docs (found here) that shows one way you can do that.
UPDATE:
As of Angular 1.3, there is now support for the ngMessage and ngMessages directives. These new directives attempt to make form validation and error messaging less of a hassle. The angular docs for these directives are here. Check the link out for more details.
In my opinion, your three rules include both client and server validation. I'll validate the first two in client side, and the validate last rule in server side.
Because an username is duplicate or not, we get it until we post it to the server.
So, my practice is following:
<div class="col-md-offset-3 col-md-9" ng-show="detailForm.$error && detailForm.name.$invalid && (detailForm.name.$touched || detailForm.$submitted)"
ng-messages="detailForm.name.$error">
<div class="error-message" ng-message="required">the field is required </div>
<div class="error-message" ng-message="maxlength">you are too lang</div>
<div class="error-message" ng-message="pattern">your format is incorrect </div>
</div>
<div class="col-md-offset-3 col-md-9" ng-show="serverError && serverError.name">
<div class="error-message">{{serverError.name}}</div>
</div>
Related
I'm trying to learn forms in AngularJS 1.x. But I have error messages that are always on when it first loads. How to develop behaviour such that they are blank on load, and only red after a submit if fields were not entered? Seems to be a few states I have to use the built-in directives for.
All the elements are similar so let's just take apart this bit. Also if different for a radio and dropdown list maybe we can discuss that too.
<p>First Name:<input type="text" id="firstName" ng-model="firstName" required/>
<span style="background-color: red" ng-if="identification.firstName.$error.required">The first name is required.</span>
</p>
Do I chain a few directives with || or && ?
Behaviour I'm aiming for
How to keep the error messages off when it loads?
when I hit submit, and a field is blank, will it then activate the css red error messages?
I'd like the error messages to clear as I fill in the form without reloading.
Yeah, so any tips greatly appreciated. Doesn't have to be particularly pretty
Thanks
UPDATE 1
gist of current code
Well I took a stab at it. Still really a hot mess at this point. Don't know how to use submit to test for each field and then display the error message if blank. Also seems like a lot of duplication on the testing of field states. Is there a better way to break up that logic? Ugggghhhhh
UPDATE 2
This one's weird, the form now has all text boxes not buttons or checkboxes!? But the HTML hasn't changed. Sigh
ng-if="identification.firstName.$error.required && !$pristine"
Go search more on $pristine and $dirty validator
You can add some other property to your ng-if and set its value to true only when form is submitted.
in your html add this new property
<p>First Name:<input type="text" id="firstName" ng-model="firstName" required/>
<span style="background-color: red" ng-if="identification.firstName.$error.required && running">The first name is required.</span>
</p>
in your controller set this property to true when form is submitted
$scope.submit = function(){
$scope.running = true;
...
}
I'm having a problem with an md-input-container when I have two validations applied to my input tag. I'm using ng-model-options="{ updateOn: 'blur' }", but the problem occurs even without it. For example:
<md-input-container>
<label>Description:</label>
<input name="description" ng-model="list.description" type="text" ng-minlength="3" required />
<div ng-messages="listForm.description.$error">
<div ng-message="minlength">List description is too short</div>
<div ng-message="required">List description is required</div>
</div>
</md-input-container>
If I type "Te" and then press TAB, the ng-minlength validation message shows. But if then I leave the input empty, the required message does not shows (but the input is decorated, as it should be).
The same behavior is reproductible here (https://material.angularjs.org/latest/demo/input). In the Erros -> Description input, if I type more than 30 characters then empty the input, the message is not shown. But if I type a correct value and then empty the input, the message shows.
In my opinion minlength and required is kind of same thing. So you must either one of them. See the for the example link.
http://codepen.io/next1/pen/PNjdBz
Even if you don't specify ng-minlength in input it will show error in ng-message because it is the same thing. So I think you should use ng-message-exp to check both the condition. And the link you refered to material design docs in releated to maxlength and required while you are looking for minlength and required.
This is a known problem with Angular Material and ngMessages.
Subscribe to the following issue if you want to be notified about any progress. I do the same...
https://github.com/angular/material/issues/6767
If you must solve this immediately then you can make use of the workaround described over there but bear in mind that it's not aesthetically perfect.
I'm building a simple form using AngularJS Messages.
Basically what I want to happen is:
User submits form, all appropriate errors show and prevents
submission
User then completes fields and errors hide one by one after 'focus out' of field ($touched ?)
First point is working fine but I can't figure out the second part, I can't hide the error messages at all afterwards. I'm sure I'm missing something simple but other related questions aren't really helping too much.
Any ideas?
<form name="orderForm"
ng-submit="orderForm.$valid && placeOrder()" novalidate>
<input type="text"
ng-model="orderParams.delivery_address.full_name"
name="fullName" required />
<p ng-message="orderForm.fullName.$error"
ng-if="orderForm.fullName.$invalid && orderForm.$submitted">
This field is required</p>
<input type="submit" value="Submit" />
</form>
For me the problem was solved by adding ngMessgaes to my module dependencies.
I installed had it installed with bower before, but forgot to add it to module dependencies. For some reason it caused no errors. It only prevented my error messages from hiding.
you need to do three things:
1. add a boolean variable in your controller like: "showMessageBox" which is set to true.
2. when you submit you set "showMessageBox" to false.
3. on your message box you put the ng-show directive and bind it to "showMessageBox" variable
I actually just figured this out. I'm using Angular 1.4.2 and it would seem that Angular Messages is now part of the core build which I didn't pick up on before (I'd just forgotten to inject into the angular module), removed the angular-messages.js file (which was probably causing conflicts) and the above code works fine.
Anyone know why the seperate module is still available on code.angularjs.org? - https://code.angularjs.org/1.4.2/
I have the following code
<div class="form-group" show-errors ng-show="contact.ContactType === 'LegallyMarriedSpouse' || contact.ContactType === 'Self'">
<label class="control-label">Social Security Number</label>
<input type="text" class="form-control" ng-model="contact.SSN" ui-mask="999-99-9999" name="SSN" maxlength="50" required />
</div>
I would have thought that Angular would have made sure that the hidden field was no longer required however that is not the case. although the user can't see it it's clearly still stopping the form from being submitted because I see the following error in the console.
An invalid form control with name='SSN' is not focusable.
So - the question is how do I handle this? If it's displayed I want it to be required if not obviously we can't try and force the user to fill out the values.
2 solutions:
use ng-if rather than ng-show to remove the input from the form rather than hiding it
instead of required, use ng-required="contact.ContactType === 'LegallyMarriedSpouse' || contact.ContactType === 'Self'" to make it required only when the condition showing the field is true. You should put that complex condition in a scope function though, to avoid duplicating it.
Note however that even if the form is invalid, it can still be submitted, unless you're explicitely preventing it by disabling its submit button when the form is invalid. I don't think the error you're seeing has anything to do with the form being invalid.
Also note that the second solution will only deal with the field being required. If the value inside the field is too long or doesn't match with the mask, the field will stay invalid. So you should probably use the first solution.
I have searched and followed the angular code for a long time and cant find where this error message is coming from. I know the validation works but my code only has this:
<span class="error" ng-show="myForm.input.$error.required">
Required!</span>
<span class="error" ng-show="myForm.input.$error.email">
Not valid email!</span></br>
but this error comes up:
I cant even find where a concatenation might produce this. The word "Please" is not even in the angular code.
The browser is generating this message, because of HTML5 support of "type='email'".
you can add 'novalidate' in form to disable native HTML5 validation.
<form name="form" class="css-form" novalidate>
This is due to HTML5. If you don't want to show these messages, add the following to your css:
::-webkit-validation-bubble-message { display: none; }
However, at the moment this only works for WebKit implementations (Chrome).
More info