I have included ngMessages into my AngularJS application to do some form validation. It's pretty useful, however I've came across something that I can't really understand.
Let's say I have this code inside my Form that is named: testForm
<input type="text" name="test1" class="form-control" ng-model="test1" required>
<span class="help-block" ng-hide="testForm.test1.$error">Please enter the a test name</span>
<div ng-messages="testForm.test1.$error" ng-if="testForm.test1.$dirty">
<div class="text-danger" ng-message="required">This field is required</div>
</div>
I want to hide the helper message when there is an error in this textbox EXCEPT if the user hasn't started to type anything yet (on $dirty).
How is this possible? With this above code my testForm.test1.$error always gives me true value even if it's empty, therefore always hiding it.
What am I missing here?
EDIT:
I'm clarifying more what I want to achieve:
when typing, the helper message should be visible and the error message should be hidden
when there is an error, the helper message should be hidden and the error message should be visible
when nothing is touched yet, the helper message should be visible and the error message should be hidden
Have you tried ng-hide="testForm.test1.$error && testForm.test1.$dirty"? That way the message always displays when the input field is clean (not dirty).
Edit:
As far as I see it, you want the message to be visible when input field has focus.
In your controller, initialize hasFocus to false:
$scope.hasFocus = false;
In your HTML file:
<input type="text" name="test1" class="form-control" ng-model="test1"
ng-focus="hasFocus=true" ng-blur="hasFocus=false" required>
<span class="help-block" ng-hide="!hasFocus && testForm.test1.$error && testForm.test1.$dirty">Please enter the a test name</span>
<div ng-messages="testForm.test1.$error" ng-if="testForm.test1.$dirty">
<div class="text-danger" ng-message="required">This field is required</div>
</div>
You can replace ng-hide as follows if it suits you. It will hide the message when test1 is not empty and when it has error.
ng-hide="!hasFocus && testForm.test1.$error && test1"
Related
I have two ng-messages associated with one Text field but I want one Message as a default -
This field is Mandatory!
which loads with the page get refreshed/opened
but the second one i.e Username contains atleast 3 characters should only shown when atleast one text entered into the textbox.
Whenever the page is loaded the second message which didnt required is shown and then vanishes when the page is loaded completely,How can I remove this and make the page more prominent.
Here's my code what I am trying is
<div class="errormsg" ng-messages="loginForm.username.$error">
<div ng-message="required">This field is Mandatory!</div>
<div ng-message="minlength">Username contains atleast 3 characters</div>
</div>
Suggest me a way to achieve this in angular.
Thanks in advance.
You need to use $pristine alongwith $invalid. See below example. I am using help-block instead of ng-message. You can add additional validations like min length, max length etc as desired.
<form name="contactUsForm" ng-submit="sendContactUsMessage();" novalidate>
<div class="form-group" ng-class="{ 'has-error' : contactUsForm.name.$invalid && !contactUsForm.name.$pristine }">
<label for="name">Name<span class="glyphicon glyphicon-asterisk mandatory" aria-hidden="true" /></label>
<input type="text" name="name" class="form-control" placeholder="When were you born?" ng-model="message.name" ng-required="true">
<p ng-show="contactUsForm.name.$invalid && !contactUsForm.name.$pristine" class="help-block">Name is required.</p>
</div>
</form>
I am using ngTagsInput Angular plugin for getting multiple email ids. Below is my code:
<form name="contact_us" role="form" novalidate enctype="multipart/form-data">
<div class="form-group">
<label class="control-label" for="from_email">
From
</label>
<tags-input ng-model="contactUs.emails" type="email" id="from_email"
placeholder="From" name="from_email"
allowed-tags-pattern="^[A-Za-z0-9._%+-]+#(?:[A-Za-z0-9-]+.)+[A-Za-z]{2,}"
allow-leftover-text="false" ng-required="true" add-on-space="true">
</tags-input>
<p class="help-block" style="color:red"
ng-show="contact_us.from_email.$invalid && (contact_us.$submitted || contact_us.$dirty)">
Please enter proper email address
</p>
<button type="submit" class="btn btn-default" ng-click="Send(contact_us)">
Send
</button>
</form>
In above code 3 validation has been added those are as follows:
For Mandatory fields.
Field should accept only an email id.
It should not allow duplicate email id.
The above cases are working fine. But, I want to show the error message dynamically according to the above one of the case has occurred. Please help me out !!!
ngTagsInput supports attribute below for change to capture, it fires before adding to model
on-tag-adding="foo($tag)"
$scope.foo(function(tag){
// look for error
// if found return false
// change the text of tag
tag.text='what ever';
return tag;
})
For required:
<p class="help-block" style="color:red"
ng-show="contact_us.from_email.$error.required">
email address is required
</p>
For pattern & duplicate, I think no validation flag has been provided and you have to write your own to perform validation.
For duplicate, maybe this will help.
Angularjs - How to check for unique inputs and if there is a duplicate mark both as invalid
I have a form wherein I am displaying validation errors only on page submit as in the code below. This validation works fine but as soon as the user corrects the validation on the input field. The validation message goes away immediately. Is there a way to preserve this validation message until the user submits the page again? My requirement is that validation messages should appear and disappear only on page submits.
<span id="error" ng-if="addForm.$submitted">
<div class="ErrorMsgBox">
<ul>
<li ng-messages="addForm.startDate.$error">
<small id="startDate_req" ng-message="required">Date is mandatory.</small>
</li>
</ul>
</div>
</span>
For example, if the user does not give a date and submits the form, the user is presented with a validation message "Date is mandatory". Now when user enters any value, the message goes way. I need this validation message to be retained until the page submit again.
I tried ng-model-options but input field is not retaining the value until the page is submitted.
ng-model-options="{ updateOn: 'submit' }"
Please suggest.
You can add a ng-if in conjunction with form.$dirty or form.$submitted to your messages directive. Also you can create your own custom function
ng-if: showErrors()
See: https://www.sitepoint.com/easy-form-validation-angularjs-ngmessages/
<label>User Message:</label>
<textarea type="text" name="userMessage" ng-model="message"
ng-minlength="100" ng-maxlength="1000" required>
</textarea>
<div ng-messages="exampleForm.userMessage.$error"
ng-if="exampleForm.userMessage.$dirty">
<div ng-message="required">This field is required</div>
<div ng-message="minlength">Message must be over 100 characters</div>
<div ng-message="maxlength">Message must not exceed 1000 characters</div>
</div>
I am doing some validation on text boxes. Once the user enters a valid input, the text box should become green and a tick mark should appear at the rightmost corner. Similarly, if the user has entered an invalid data, text box should become red and a cross should appear instead.
For this, I'm using bootstrap's 'has-error has-feedback' and 'has-success has-feedback' css classes.
My problem is that the textbox is green and has a tick even when the page is loaded for the first time. I need the validation feedback to appear only after the user has entered an input. And the same applies when the form is used to edit the existing records. How can I achieve this ? (I'm not sure if I could use $dirty and '$pristine` to solve this problem)
Below is my Markup.
<div class="form-group" ng-class="(Form.emailAddress.$valid) ? 'has-success has-feedback': 'has-error has-feedback'">
<label for="emailAddress">Email address</label>
<span ng-show="!Form.emailAddress.$valid">Please enter a valid address</span>
<input type="email" class="form-control" id="emailAddress" name="emailAddress" ng-model="Data.emailAddress" ng-pattern="validationPattern" ng-maxlength="20">
<span ng-show="Form.emailAddress.$valid" class="glyphicon glyphicon-ok form-control-feedback"></span>
<span ng-show="!Form.emailAddress.$valid" class="glyphicon glyphicon-remove form-control-feedback"></span>
</div>
A few more questions regarding this topic.
I would like to check the maxlength of the email as well, and if it exceeds 20, I would want to show a different message. I tried Form.emailAddress.$maxlength but couldn't get it working. Does it maxlength work on 'email' types as well ?
How can I show the feedback after the user moves to the next textbox instead of showing it while typing ? May be something similar to jquery's 'focusout()'.
I've used a validation pattern in the controller because email is not a required field, but when entered it has to be valid. Could I please know if there are better ways than doing this ?
Any help would be much appreciated. Thanks
You have to use $valid && $dirty for green and in a separate check, use $invalid and $dirty for red.
Here's an example:
http://plnkr.co/edit/k8X5NSeUrBb2nqA9yD9F
<form name="myform">
Valid: {{myform.myinput.$valid}}<br/>
Dirty: {{myform.myinput.$dirty}}<br/>
<input type="text"
name="myinput"
required
ng-model="myvalue"
ng-class="{'has-success has-feedback': \
myform.myinput.$valid && myform.myinput.$dirty, \
'has-error has-feedback': \
myform.myinput.$invalid && myform.myinput.$dirty}"></input>
</form>
the code below is part of signin.html. when i visit that page, nick and password is surely empty, so the myForm.nick.$error.required is true. the error message is displayed. What i want is, when i visited the page, there's no error message on the page. What should i do? Thanks
<form ng-submit="signin()" name="myForm">
<input type="text" name="nick" ng-model="data.nick" required>
<span class="error" ng-show="myForm.nick.$error.required">Required</span><br>
<input type="password" name="password" ng-model="data.password" required>
<span class="error" ng-show="myForm.password.$error.required">Required</span><br>
</form>
You should add a $dirty condition to prevent the required field message being displayed at the beginning of page.
myForm.nick.$error.required && myForm.nick.$dirty
myForm.password.$error.required && myForm.password.$dirty
$dirty===true means that user has already interacted with the form.
Here is a jsfiddle demo
Hope this helpful.