I have such part of form:
<div ng-messages="submittedFrgPwd && forgotForm.username.$error" multiple>
<div ng-message="pattern">{{ 'INVALID_EMAIL' | translate }}</div>
<div ng-message="required">{{ 'EMPTY_EMAIL' | translate }}</div>
<div ng-message="minlength">{{ 'SHORT_EMAIL' | translate }}</div>
<div ng-message="maxlength">{{ 'LONG_EMAIL' | translate }}</div>
</div>
<input type="email" id="username-remember" name="username" ng-model="username" ng-minlength="8" ng-maxlength="200" required ng-pattern="email_regexp" ng-class="{ 'has-error': submittedFrgPwd && forgotForm.username.$invalid || submittedError}"/>
and for example:
when i enter email of normal length, but with invalid pattern i see only:
{{ 'INVALID_EMAIL' | translate }}
and this is normall.
but!
when i enter something like a#a.a i get both errors:
<div ng-message="pattern">{{ 'INVALID_EMAIL' | translate }}</div>
<div ng-message="minlength">{{ 'SHORT_EMAIL' | translate }}</div>
but is this real, to skip pattern messages until my min length is valid?
i try it so:
data-ng-show="submittedFrgPwd && forgotForm.username.$error.pattern && !forgotForm.username.$error.minlength && !forgotForm.username.$error.maxlength"
seems to work, but it's to ugly)
You could do this by specifieng , separated error, Its like AND operation which you are specifying minlength && pattern both error should occur.
Markup
<div ng-message="minlength,pattern">{{ 'INVALID_EMAIL' | translate }}</div>
Demo Plunkr
Update
Seems like ng-message="minlength,pattern" is not working, I'd suggest you to use alternative solution by using ng-if="!forgotForm.username.$error.minlength"
<form name="forgotForm" ng-controller="mainCtrl">
<label>
Enter your name:
<div ng-messages="submittedFrgPwd && forgotForm.username.$error" multiple>
<div ng-message="required">{{ 'EMPTY_EMAIL' }}</div>
<div ng-message="minlength">{{ 'SHORT_EMAIL' }}</div>
<div ng-message="maxlength">{{ 'LONG_EMAIL'}}</div>
<div ng-if="!forgotForm.username.$error.minlength" ng-message="pattern">{{ 'INVALID_EMAIL' }}</div>
</div>
<input type="text" id="username-remember" name="username"
ng-model="username" ng-minlength="8" ng-maxlength="200"
required ng-pattern="email_regexp"
ng-class="{ 'has-error': submittedFrgPwd && forgotForm.username.$invalid || submittedError}"/>
</form>
Update Plunkr
if you are seeing the handlers, it probably means there was an error somewhere. My best best is that ngMessages was not injected.
angular.module('app',['ngTranslate', 'ngMessages'])
Additionally, you could make use of angularjs form default to check for submission i.e. forgotForm.$submitted.
<div class="form-group" ng-class="{ 'has-error': forgotForm.$submitted && forgotForm.username.$invalid }">
You also do not need to use pattern for type=email unless there are some specific scenarios you want to test (e.g. email domain). ng-message='email' should be able to handle whether email is valid or not.
<div ng-message="email">{{ 'INVALID_EMAIL' | translate }}</div>
In any case, I have attached the plunker link below
http://run.plnkr.co/Em2eBprmn74FqSYu/
I have included bootstrap css which i found is helpful when validating (and change the html code a lil bit).
hope this helps.
Related
I have been stuck at this silly angular 5 reactive forms error which i am not able to get rid of. While adding the validation message block in html, I am getting the error
"Cannot read property 'invalid' of undefined"
which is weird as there is a form control element with the same name and I am able to access the value of that feild. Below is the code
HTML file
<form [formGroup]='signUpForm'>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" formControlName='password'>
<div *ngIf="password.invalid && (password.dirty || password.touched)"
class="alert alert-danger">
<div *ngIf="password.errors.required">
Name is required.
</div>
</div>
</div>
</div>
</div>
</form>
ts code
signUpForm: FormGroup;
this.signUpForm = new FormGroup({
username:new FormControl('',Validators.required),
email:new FormControl('',[Validators.required]),
password:new FormControl('',Validators.required),
})
Please help. Thanks in advance
Try This Code.
<div *ngIf="signUpForm.controls['password'].invalid && (signUpForm.controls['password'].dirty || signUpForm.controls['password'].touched)"
class="alert alert-danger">
<div *ngIf="signUpForm.get('password').hasError('required')">
Name is required.
</div>
</div>
Where do you initialize the form?? If you do it in ngOnInit(), you should not be facing that problem.
If you are initializing the form under any other custom method of yours then you can use something like:
Use the safe navigation operator ?. This checks whether the first operator results to true or not. When the view is rendered it might be possible that the control is not initialized yet. So suppose if the component variable password is not defined when your view is rendered and you try to access a property invalid of password(which is undefined), you will get the error you get now..
for example:
<div *ngIf="password?.invalid && (password?.dirty || password?.touched)" class="alert alert-danger">
So your actual view could be like:
<form [formGroup]='signUpForm'>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" formControlName='password'>
<div *ngIf="password?.invalid && (password?.dirty || password?.touched)" class="alert alert-danger">
<div *ngIf="password?.errors?.required">
Name is required.
</div>
</div>
</div>
</div>
</div>
I am trying to simply replicate the walkthrough from the Angular website but cannot get length validation to work:
<input
style="display:inline-block;min-width:150px"
class="form-input"
id="phone"
required
minlength="4"
maxlength="24"
type="number"
name="phone"
[(ngModel)]="client.phone"
#phone="ngModel" />
<!-- required works, minlength and maxlength always false -->
{{ phone.hasError('required') }} {{ phone.hasError('minlength') }} {{ phone.hasError('maxlength') }}
<div *ngIf="phone.errors && (phone.dirty || phone.touched)"
class="alert alert-danger">
<div [hidden]="!phone.errors.required">
Name is required
</div>
<div [hidden]="!phone.errors.minlength">
Name must be at least 4 characters long.
</div>
<div [hidden]="!phone.errors.maxlength">
Name cannot be more than 24 characters long.
</div>
</div>
I must be missing something simple, but for some reason the required validation changes depending on input, but both minlength and maxlength are always false regardless of how long my input is.
Its because number type doesnt have length property
There is a bug for this https://github.com/angular/angular/issues/15053
You can work around it like:
[ngModel]="client.phone" (ngModelChange)="client.phone = $event + ''"
Plunker Example
Update
Since in 4.2.0-beta.0 (2017-05-04) were introduced min and max validators so you can have a look https://github.com/angular/angular/pull/15813/commits/52b0ec8062381e7285b5f66aa83008edfbf02af3
I went through lots of post, but did not find what I was looking for.
Basically,
I am showing user validation on form changes. My template looks like this:
<div class="form-group"
[class.error]="!loginForm.find('email').valid && loginForm.find('email').touched">
<div class="input-wrapper">
<input type ="email"
class="form-control"
id="email-input"
placeholder="Email"
formControlName="email">
</div>
<div *ngIf="loginForm.controls['email'].dirty && !loginForm.controls['email'].valid"
class="alert-msg">Email is invalid</div>
</div>
And, looking at other posts, my TS which debounces form is this:
this.loginForm.valueChanges.debounceTime(500).subscribe(form => {
console.log(form, this.loginForm);
});
Now, the console logs are actually debouncing. But, the validation message does not debounce. It shows up straight away the message.
Is there a way to overcome this issue?
Thanks, for stopping by,
I believe the debounceTime will only affect the code you have in the response form => { ... }.
So what you could do is set the validation there:
private loginFormIsValid:boolean;
private emailIsNotValid:boolean;
ngOnInit() {
this.loginForm.valueChanges.debounceTime(500).subscribe(form => {
this.loginFormIsValid = !loginForm.find('email').valid
&& loginForm.find('email').touched;
this.emailIsNotValid = loginForm.controls['email'].dirty
&& !loginForm.controls['email'].valid;
console.log(form, this.loginForm);
});
}
...And then you would use it in you template as follows:
<div class="form-group" [class.error]="!loginFormIsValid">
<div class="input-wrapper">
<input type ="email"
class="form-control"
id="email-input"
placeholder="Email"
formControlName="email">
</div>
<div *ngIf="emailIsNotValid"
class="alert-msg">Email is invalid</div>
</div>
You can take a look at a post on debouncing, it's a good example.
I have the following loop in which I'm trying to increment several fields based on the array index each time through the loop.
<div class="individualwrapper" ng-repeat="n in [] | range:4">
<div class="iconimage"></div>
<div class="icontext">
<p>Imagine that you are in a health care facility.</p>
<p>Exactly what do you think this symbol means?</p>
<textarea type="text" name="interpretation_1" ng-model="interpretation_1" ng-required="true"></textarea>
<p>What action you would take in response to this symbol?</p>
<textarea type="text" name="action_1" ng-model="action_1" ng-required="true"></textarea>
</div>
</div>
I'd like to do something similar to this"
ng-model="interpretation_{{$index + 1}}"
Angular is not rendering that value though? What would be the best way to go about adding this kind of logic in the mg-model field?
It becomes an invalid expression with the usage of interpolation with ng-model expression. You need to provide a property name there. Instead you can use an object and use bracket notation.
i.e in your controller:
$scope.interpretation = {};
and in your view use it as:
ng-model="interpretation[$index + 1]"
Demo
angular.module('app', []).controller('ctrl', function($scope) {
$scope.interpretation = {};
$scope.actions = {};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
{{interpretation}} {{actions}}
<div class="individualwrapper" ng-repeat="n in [1,2,3,4]">
<div class="iconimage">
</div>
<div class="icontext">
<p>Imagine that you are in a health care facility.</p>
<p>Exactly what do you think this symbol means?</p>
<textarea type="text" ng-attr-name="interpretation{{$index + 1}}" ng-model="interpretation[$index+1]" ng-required="true"></textarea>
<p>What action you would take in response to this symbol?</p>
<textarea type="text" name="action{{$index + 1}}" ng-model="actions[$index+1]" ng-required="true"></textarea>
</div>
</div>
</div>
I'm fairly new to angular, so hopefully this is a super simple question for someone to nail.
I have a form (cut down version below) that I want to be able to have a live preview being shown as the user fills in the form.
All was going well with standard fields, however I've hit a roadblock with <select> fields.
<div ng-app="jobcreate">
<div class="row fullWidth" ng-contoller="JobCtrl">
<div class="medium-6 columns">
<form method="POST" action="http://localhost:3030/job/create" accept-charset="UTF-8">
<label for="title">Enter a title</label>
<input placeholder="title" id="title" required="required" ng-model="job.title" name="title" type="text" />
<br />
<label for="title">Pick template</label>
<select ng-model="job.template" ng-options="template.Name for template in templates" name="template"></select>
</form>
</div>
<div class="medium-6 columns">
<div class='job-detail {{ job.template || "default" }}'>
<h2>{{ job.title || "Enter a title"}}</h2>
<h2>{{ job.template || "Pick a template"}}</h2>
<pre>Templates: {{templates | json}}</pre>
</div>
</div>
</div>
</div>
And here is the js:
angular.module('jobcreate', []).controller('JobCtrl', function($scope) {
$scope.templates = [
{ID:'default', name:'Default'},
{ID:'obnoxious', name:'Obnoxious'}
];
});
I have a jsfiddle here so you can see it in action: http://jsfiddle.net/2m8jm/4/
As you can see, entering something in the title field works as intended, but I'm struggling to get the contents of the $scope.colors to fill in the select field
In your fiddle : http://jsfiddle.net/2m8jm/4/, you have choosed templates as an data array for ng-options but there is not scope variable named templates in the controller JobCtrl. I have renamed $scope.colors to $scope.templates and modified the ng-options bit - ng-options="template.ID as template.name for template in templates".
Here is a working plunker : http://plnkr.co/edit/wsbxkjRqTEU2yfcHOV0D?p=preview
Update
Is there a way to not have the first empty value be in the select field?
Yes, Couple of ways.
1) Initialize job.template with some default value in your markup as :
<label for="title" ng-init="job.template='obnoxious'">Pick template</label>
<select ng-model="job.template" ng-options="template.ID as template.name for template in templates" name="template"></select>
2) Define controller as follows to set default value for job.template inside the controller :
.controller('JobCtrl', function($scope) {
// some other codes
$scope.job = {};
$scope.job.template = 'default';
});