How to make ngMessage for required fields only show when dirty or submitting a form?
Asked Answered
H

12

43

I'm using AngularJS 1.3.0 RC0 and angular-messages. ng-messages dutifully shows error messages for those "required" fields when a form is initially loaded and pristine. So the newly loaded form page is filled up with error messages. This is not what I want. How to make ngMessage for required fields only show when those fields are dirty or submitting a form?

I have read the official doc, no clue. And tried to put "ng-show = "fieldName.$dirty"" in the ng-messages div, did not work. Any help would be highly appreciated!

Haematogenous answered 3/9, 2014 at 0:26 Comment(0)
L
91

Use the ng-if attribute to check for $dirty on the tag that has ng-messages.

Example :

<div ng-messages='myForm.myControl.$error' ng-if='myForm.myControl.$dirty'>
    <div ng-message='required'>Required field</div>
</div>
Laynelayney answered 30/10, 2014 at 9:31 Comment(4)
hey, for me this works only for required, but e.g. for input[type=email] the validation switches to invalid as soon the user starts typingSheriff
@Sheriff have you tried using ng-model-options="{ debounce: 500 }"?. See https://docs.angularjs.org/guide/forms, "Non-immediate (debounced) model updates" section.Forty
If the user enters the field but doesn't provide input, $dirty isn't triggered. However, $touched will be. This is useful for required fields.Comfort
ng-if and ng-messages together cause some strange behavior in Angular Material. If you ever see duplicate messages, switch to ng-show.Rhizobium
C
21

The best way to do this is with $touched:

<div class="help-block" ng-messages="userForm.name.$error" ng-show="userForm.name.$touched">
    ...
</div>
Clubby answered 22/9, 2015 at 6:23 Comment(0)
C
14

Only if dirty:

<div ng-messages="myForm.myField.$dirty && myForm.myField.$error">
    <div ng-message='required'>Required field</div>
</div>

Only if form is submitted:

<div ng-messages="myForm.$submitted && myForm.myField.$error">
    <div ng-message='required'>Required field</div>
</div>
Collaborationist answered 28/12, 2015 at 21:26 Comment(2)
The thing is, if we validate when the form is submitted, then it will submit with the error data and we don't want that. But if we submit only if the form is valid, then the submit won't occur in case of an error and then the validation message won't show, but that is when we need it. Kind of funny :)Kenna
You don't want to submit an invalid form. Your ng-submit should check if form is $valid before calling the appropriate function on your scope/controller.Collaborationist
A
11

Instead of using the ng-if suggested you could do something like...

<div ng-messages='myForm.myControl.$error' ng-if='submitted'>
   <div ng-message='required'>Required field</div>
</div>

And on your submit button add:

ng-click="submitted=true"

You'd probably want to change '$scope.submitted' back to false when you type again, so you could add this to your text/email input:

ng-keyup="submitted=false"

That way only the submit button will change '$scope.submitted' to true and everything else you do will set it to false, therefore hiding your error message until you click the submit button.

Av answered 23/4, 2015 at 12:44 Comment(5)
only issue is if you're displaying multiple errors they all get hidden onkeyup, but great solution I'm just trying to figure out how to make it work with multiple errors displayedVeda
I actually need to work on a new project showing multiple errors so I'll get back on this once I've figured something clean out. If you haven't already? @VedaAv
If setting submitted=true on ng-click then how to call controller method at ng-click eg: ng-click="$ctrl.login()"?Stratfordonavon
@MicrosoftDeveloper ng-click="$crl.login(); submitted=true" This should work, if not try a comma between them. I can't remember exactly which one is correct.Av
@MicrosoftDeveloper You could also just make a submitted variable in your controller and add submitted=true in your $ctrl.login() function.Eve
T
5

I did not want to show my message until there is any error or user tried to submit the page, and none of the above solution worked.

Finally I ended up successfully with this:

<form name='frmUser'>
..........
..........
<div ng-messages="frmUser.firstName.$error" 
     ng-show='frmUser.$submitted || frmUser.firstName.$dirty' role="alert">
      <div ng-message="required" class="err">Required</div>
      <div ng-message="maxlength" class="err">Maximum 50 characters.</div>
</div>
<input ng-model="model.first"
       name="firstName"
       type="text"
       ng-required="true"
       ng-maxlength="50"
       placeholder="Enter your first name" />

</form>

If you type anything which is not valid, then show the error

If you try to submit the page and you have not provided the required field it will show error.

Though answered 15/1, 2016 at 18:10 Comment(0)
D
3

Do the error messages still appear after you have satisfied their conditions? In that case, have you remembered to take a dependency on ngMessages in your angular module? E.g.:

angular.module("exampleModule", ["ngMessages"]);
Dedicate answered 10/9, 2014 at 14:37 Comment(1)
Thanks for the response. The error message disappear when I type something correct in the input box. That's like expected, no problem. The problem is: Those "required" fields are correctly empty when the page is just loaded. At this point of time, I do not want to see the error message. The error message "This field is required, please enter value!!!" should only appear when the user tries to submit, not when loading the page.....Haematogenous
G
2

I found this answer helpful, but it didn't solve the problem of the error message hanging around forever. I came up with a slightly more complex use of show and hide as follows:

<div class="help-block"
    ng-messages="addPlanForm.planName.$error"
    ng-show="addPlanForm.$submitted || addPlanForm.planName.$dirty || (addPlanForm.planName.$invalid && addPlanForm.planName.$touched)">
    <p ng-message="required" ng-hide="addPlanForm.planName.$valid">Your name is required.</p>
</div>

By adding ng-hide on the message generated when an error occurs, the message disappears when the user corrects the error. Way cool. I LOVE angular.

Gesticulatory answered 15/4, 2016 at 4:13 Comment(0)
D
2

Just Try this

<div ng-messages='myForm.fieldName.$error && (myForm.fieldName.$dirty || myForm.$submitted)' >
    <div ng-message='required'>Required field</div>
</div>
Disaffection answered 19/6, 2017 at 11:46 Comment(0)
C
1

I was struggling with this and what was happening was my ng-messages were not appearing because the default browser behavior was not allowing invalid form submission with ng-required="true". To solve this you can decorate the form with novalidate. Here is the full working example for me:

<form name="myForm" novalidate ng-submit="myForm.$valid && controllSideSubmitHandle()">
  <input type="text" name="name" ng-model="myScope.name" ng-required="true">
  <div ng-messages="myForm.$error || myForm.$submitted" style="color:maroon" role="alert" ng-if="myForm.name.$dirty || myForm.$submitted">
    <div ng-message="required">Name is required.</div>
  </div>
  <input type="submit" value="Submit"/>
</form>
Corallite answered 13/12, 2016 at 5:54 Comment(0)
H
1

I solved this problem with a css rule

[ng-messages] { display: none; color:red; } 
.ng-dirty [ng-messages] { display:block }

That's it..

Works like a charm for me.

Here is a plunker

Angular's use of classes is amazing, you can do so many things with it!

Haymo answered 13/1, 2017 at 14:41 Comment(0)
L
1
<input required type="text" ng-model="model" name="field" ng-maxlength="13" ng-minlength="10">     
<div ng-messages="form.field.$error" ng-if='form.$submitted'>
            <p ng-message="required">Required</p>
            <p ng-message="maxlength">not a valid field. Length exceeds.</p>
            <p ng-message="minlength">not a valid field. Length is shorter.</p>
</div>

button type should be submit and this will work.

Lipp answered 24/6, 2017 at 10:43 Comment(1)
I have edited the answer. Hopefully it will help you with validations in angularJsLipp
C
1

If you're using AngularJS Material, a lot of this functionality comes out of the box! Just remember to put everything inside an <md-input-container>.

Here's a codepen example so you can see how it looks. This not only hides the error before the input has been clicked, it'll add some nice red styling and an animation for when it does show up!

Here's the actual code:

  <form name="books" novalidate>
    <md-input-container>
      <input ng-model="title" name="title" required/>
      <div ng-messages="books.title.$error">
        <div ng-message="required">Title is required</div>
      </div>
    </md-input-container>
  </form>
Conversable answered 26/7, 2017 at 17:22 Comment(1)
Is it possible to display this message outside md-input-cointainer?Health

© 2022 - 2024 — McMap. All rights reserved.