I validate my angular form using below code
<div class="form-group">
<input type="text" minlength="12" maxlength="12" name="accountno" #accountNo="ngModel" required class="form-control" pattern="^[0-9]*$"
[(ngModel)]="registerUser.accountNo" [class.is-invalid]="accountNo.invalid && accountNo.touched"
placeholder="Account No.">
<div [class.d-none]="accountNo.valid || accountNo.untouched">
<small *ngIf="accountNo.errors?.required" class="text-danger">Account No. is required</small>
<small *ngIf="accountNo.hasError('pattern')" class="text-danger">Accout No. should be 12 numbers</small>
<small *ngIf="accountNo.hasError('minlength')" class="text-danger">Accout No. must be at least 12 Numbers.</small>
</div>
</div>
When I typing letters in the textbox, two validations fire in same time. please check below image
how i load my validations one by one.. thanks
This is the correct behavior, since the text you provided is not a valid number and it has less than 12 characters.
Use NgSwitch instead of ngIf and some function call that returns the first key of formControl.errors object I think it can help
Related
Is there a class which I can use for representing !invalid-feedback? What I am trying to do is, I want to have a placeholder under my form input and tell the user that this field needs to only have 3 characters and if the validation fails, I will add a a div with a class of invalid-feedback. I want them to be mutually exclusive so it's either the placeholder or the invalid-feedback.
So for example,
<form:input path="ac" required="required"
class="form-control text-uppercase" maxlength="3" />
<small class="form-text text-muted">Only three characters are allowed</small>
<div class="invalid-feedback">AC is required</div>
in the following block, if the user is either entering the data or if the value is valid, I want to show what's in the <small> tag, if the form is submitted and if there is a validation error, I want to show what's in the invalid-feedback div.
So, is there a class in Bootstrap which is basically !invalid-feedback? Is it valid-feedback? isValid? Can this be done with just using styles and not Javascript/jQuery?
There are Bootstrap classes to indicate a field has an error but since you're asking to display errors in a non-Bootstrap way (i.e. by hiding and showing different tags) you'll have to roll your own validation using Javascript.
Here is one way that monitors the status of the input field and hides/shows the <small> and div.invalid-feedback elements. (Note that this is just a proof-of-concept, and doesn't deal well with all possible ways of the user interacting with the input field.)
$('input').on('input', function() {
if ($(this).val().length == 3) {
$('.invalid-feedback').hide()
$('small').show()
} else {
$('.invalid-feedback').show()
$('small').hide()
}
})
<script src="https://code.jquery.com/jquery-3.6.1.js" integrity="sha256-3zlB5s2uwoUzrXK3BT7AX3FyvojsraNFxCc2vC/7pNI=" crossorigin="anonymous"></script>
<form>
<input path="ac" required="required"
class="form-control text-uppercase" maxlength="3" />
<small class="form-text text-muted">Only three characters are allowed</small>
<div class="invalid-feedback">AC is required</div>
</form>
I cant seem to figure out what the issue is I have a form input like so..
<div class="form-group">
<label class="form-label" for="password">Change Password</label>
<input type="password" class="form-control" id="password" name="password" [(ngModel)]="password" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$#$!%*?&])[A-Za-z\d$#$!%*?&]{8,}">
</div>
and then below it I have..
<div *ngIf="!password.valid && (password.dirty || password.touched)" class="password-reminder">
<p>Your password must be over 8 characters and include an uppercase letter, a number and a special character</p>
</div>
now if I dont have a valid password and its been touched nothing happens, but I do know the validation is working because the button on my form is disabled until I put the password In correctly..
Not sure what I'm doing wrong? why wont the div show itself??
EDIT
It works if I take away && (password.dirty || password.touched) but I only want to show the message If they enter a not valid password and untouch..
I can see in my dev tools that the classes are being applied
but it doesnt dissapear when my password is valid..
EDIT 2
I am using template driven forms
Any help would be appreciated.
Create a template reference variable on your Input field.
<input #passwordField="ngModel" type="password" class="form-control" id="password" name="password" [(ngModel)]="password" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$#$!%*?&])[A-Za-z\d$#$!%*?&]{8,}">
Make sure to update the references to password with passwordField in your template.
<div *ngIf="!passwordField.valid && (passwordField.dirty || passwordField.touched)" class="password-reminder">
<p>Your password must be over 8 characters and include an uppercase letter, a number and a special character</p>
</div>
Since you are using template driven forms, there is no corresponding password property in your component, and hence most use a template reference variable. You can find a demonstration of this method here.
Try this.
Add this part to the input field(a template reference variable)
#passwordField="ngModel"
<div class="form-group">
<label class="form-label" for="password">Change Password</label>
<input type="password" class="form-control" id="password" name="password" [(ngModel)]="password" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$#$!%*?&])[A-Za-z\d$#$!%*?&]{8,}" #passwordField="ngModel">
</div>
<div *ngIf="!passwordField.valid && (passwordField.dirty || passwordField.touched)" class="password-reminder">
<p>Your password must be over 8 characters and include an uppercase letter, a number and a special character</p>
</div>
Then it should work. Read more about template driven forms in here.
As Others said You should use an element variable like #passwordElement="ngModel"
have a look at stackblitz
As others have said, you need to provide the template reference in your password div:
#password=ngModel
Also add required to your password tag like so:
<input type="password" class="form-control" id="password" name="password" [(ngModel)]="password" #password=ngModel pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$#$!%*?&])[A-Za-z\d$#$!%*?&]{8,}" required>
I just tested it out and it works on my end.
Create a temp reference variable. something like
<input #password=ngModel />
then use #password to do validation. Also make sure you are applying touched and dirty class correctly.
I have Custom input component with validation with ngMessages,FormController and ng-required:
<div class="col-sm-9 col-xs-12">
<input
id="{{$ctrl.fieldName}}"
name="{{$ctrl.fieldName}}"
class="form-control"
type="text"
minlength="{{$ctrl.minLength}}"
maxlength="{{$ctrl.maxLength}}"
ng-required="{{$ctrl.isRequired === 'true'}}"
ng-model="$ctrl.value"
ng-change="$ctrl.form.$submitted = false;"
>
<div
ng-messages="$ctrl.form[$ctrl.fieldName].$error"
ng-if="$ctrl.form.$submitted"
>
<span class="help-block" ng-message="required">
Field is required
</span>
<span class="help-block" ng-message="minlength">
Minimum length of field: {{$ctrl.minLength}}
</span>
<span class="help-block" ng-message="maxlength">
Maximum length of field: {{$ctrl.maxLength}}
</span>
</div>
</div>
Which is used in this way:
<act-text-field
form="heroAddForm"
field-name="name"
min-length="3"
max-length="15"
is-required="true"
errors="$ctrl.errors.name"
ng-model="$ctrl.hero.name">
</act-text-field>
What I want to achieve is validation fires when user clicks submit button. And it works, validation fires also for required field name, but also for field description which is not required:
<act-text-field
form="heroAddForm"
field-name="description"
max-length="50"
is-required="false"
errors="$ctrl.errors.description"
ng-model="$ctrl.hero.description"
></act-text-field>
Also for this field validation messages are visible, although field description is valid, cause I add class has-error to invalid fields:
<div class="form-group"
ng-class="{'has-error': $ctrl.form.$submitted && (!$ctrl.form[$ctrl.fieldName].$valid)}"
>
<!-- rest of code -->
You can easily reproduced this wrong behaviour in my Plunker: Custom input demo app with validation states (I know it has other mistakes). I think ng-message="required" should not be visible, because field description is not required. I know I can add some ng-ifs to code to by-pass it, but I think I make a mistake somewhere which I can't see. Do you see where I made a mistake? Thank you in advance for every help.
I found a solution, again I forgot to include ngMessages. Without it, my code went crazy, I apologize for wasting your time :)
I am trying to validate an auto-generated form (via AngularJS v1.3) which inputs' names are in format:
form_name[field_name]
The very basic example would be:
<form name="morgageCalculator">
<input type="text" class="form-control"
name="morgageCalculator[homeValue]" value="0"
data-ng-model="data.homeValue" required="required"/>
</form>
As you can see, the input name is morgageCalculator[homeValue]. Now I would like to add an error message below it:
<div class="error"
data-ng-show="!morgageCalculator.morgageCalculator[homeValue].$pristine && morgageCalculator.morgageCalculator[homeValue].$invalid">
Please enter a number
</div>
For very obvious syntax reasons this expression is not valid:
morgageCalculator.morgageCalculator[homeValue].$pristine
But this one also does not work:
morgageCalculator["morgageCalculator[homeValue]"].$pristine
So, the question, is there any sane way of accessing those fields? I wouldn't mind moving the validation to some controller function, but I was faced with same issue of inability to access field object.
Any help/hint would be greatly appreciated.
With help of #dfsq from comment section, I was able to find the error. Unlike my SO question, my code was missing data-ng-model.
Validation will not fire at all if input was not bound to model....
The correct snippet:
<form name="morgageCalculator">
<input type="text" class="form-control"
name="morgageCalculator[homeValue]" value="0"
data-ng-model="data.homeValue" required="required"/>
<div class="error"
data-ng-show="!morgageCalculator['morgageCalculator[homeValue]'].$pristine && morgageCalculator['morgageCalculator[homeValue]'].$invalid">
Please enter a number
</div>
</form>
THE SITUATION:
I have many forms in my angular app and i need an effective error messages system. I find ngMessages useful.
But i would like that the error messages appears only when the user blur out of a field, in order to be less 'aggressive'.
ATTEMPT:
Attempt using debouncing at 1000ms
<label class="item item-input">
<span class="input-label"> Email alternative </span>
<input type="email" name="email_alternative" ng-model="profile_edited.email2" ng-model-options="{ debounce: 1000 }">
</label>
<!-- Error messages for ALTERNATIVE EMAIL -->
<label class="item item-input" ng-show="profile_edit_form.email_alternative.$error.email">
<div class="form-errors" ng-messages="profile_edit_form.email_alternative.$error" role="alert" ng-if='profile_edit_form.email_alternative.$dirty'>
<div class="form-error" ng-message="email">Your email address is invalid</div>
</div>
</label>
In this way it will properly appears the error message if the user is not typing anything for one second.
Is the closest i get to what i want.
But sometimes for some users it may take a bit more than 1 second to type the character #. The error message may then suddenly appear and confuse the user.
But if i set the debouncing time 2 or 3 seconds is way too much. It may appear when the user is already writing in another field.
I need that the error messages fire ONLY AFTER the user blur out of the field.
THE QUESTION:
How can i fire ngMessages on blur?
$dirty will evaluate to true if the text is changed in the input box. To check for the blur you can use the $touched property of the input field.
Checkout the forms documentation to see all form (input) properties: https://docs.angularjs.org/guide/forms
You can use $dirty and ng-show to display messages when input is dirty.
<input type="text" name="modelName" ng-model="modelName" required />
<div ng-messages="myForm.modelName.$error" ng-show="myForm.modelName.$dirty">
<div ng-message="required">Please Fill this model.</div>
</div>