I've got the following div, which I want to add the bootstrap's class "has-error" if the input length is over 50 characters. This is the HTML:
<div class="form-group" ng-class="{has-error:[formData.titulo.$error]}">
<label for="inputTitulo">Título</label>
<input type="titulo" class="form-control" id="inputTitulo"
maxlength="50" ng-maxlength="50" ng-model="formData.titulo">
</div>
How can I make this work? I guess when you reach 50 characters, ng-maxlength throws a error, like the $error object, but I have no clue on what object is, how to access it, and if I have to do some more work in the controller or directive.
Any help here? I can't find any "easy" info regarding this issue and Angular validators.
edit 1:
I've seen all your responses, learned something new thanks to you, but this is still somehow not working. It currently is this way:
<div class="form-group" ng-class="{'has-error': formData.titulo.$error.maxlength}">
<label for="inputTitulo">Título</label>
<input type="titulo" class="form-control" id="inputTitulo" maxlength="50" ng-maxlength="50" ng-model="formData.titulo">
</div>
Also tested checking the length directly, as one of you suggested. But none of these solutions seem to work: it never adds the has-error class. Why?
To have the errors published on the scope, a form directive is required.
<div ng-form="form1" ng-class="{'has-error': form1.text1.$error.maxlength}">
<input name="text1" ng-model="formData.foo" ng-maxlength="50">
</div>
(Notice that the above uses the name attribute of the input to publish the form data - really, the ngModelController - on the scope)
So, the above works, and it's preferable if you do form validation. But, if you just need to check the length of some input, you don't have to use form validation - you could just check the model directly:
<div ng-class="{'has-error': formData.foo.length > 50}>
<input ng-model="formData.foo">
</div>
as you are using ng-model to make validations ,, this class ng-invalid will be added to your input
docs : https://docs.angularjs.org/api/ng/directive/ngModel
to use $error you need to access it using forms and names not ng-model ,, and the ng-class should be bound to the $error.maxlength not $error only
tutorial : https://scotch.io/tutorials/angularjs-form-validation
If you use the maxlength, a user will never be able to enter more characters than that, so you will never get the ng-maxlength error. It doesn't make sense to use maxlength and ngMaxlength together IMHO.
See the example on docs.angularjs.org/api/ng/directive/ngMaxlength (open the example in plunker and add maxlength attribute)
Related
I have a directive with the following template
<div>
<span class="label">My Label</span>
<input ng-model="name" required>
</div>
I want the label to be painted red when the input field is invalid.
How can I do that?
Currently I have another directive to sync all the errors from ngModelCtrl to the wrapping div
<div add-all-errors>
...
</div>
And the directive's link function does something like this:
const ngmodel = $element.find('[ng-model]').controller('ngModel');
$scope.$watch(()=>ngmodel.$error, addAllClasses, true);
Where addAllClasses simply makes sure the correct classes appear on the element..
I also tried just adding the same ng-model
<div ng-model="name">
...
</div>
But did not see the classes there..
any better way to do this?
This is why we use the angularjs form... I'm really not sure why people are against using a very handy feature.
I've made a plunker for you.
https://plnkr.co/edit/bGOcQjWzlRq2aTYZUYNm?p=preview
<form name="form">
<span ng-class="{red: form.name.$invalid}">Name:</span>
<input name="name" ng-model="name" required>
</form>
A little more insight of what's going on. form is added to the scope auto magically by angularjs by it's name. In this case, I named it form, however it can be any name.
Now form is an ngForm Object and adds all input field into it by their name attributes. This way we can do form.name to get another object similar to the ngForm Object. We can then use $invalid or $valid properties with ng-class.
ngForm is pretty powerful and is loaded with many cool properties and methods. Just call console.log(scope.form); You will need to put in a method and add it to ng-change to see updates.
I have an input field that is nested within another <div> element, and I am trying to use ngMessages on that inside input field, but I can't seem to get it to validate correctly.
<div class="form-group" ng-model="object.idnumber" ng-hide="condition.userObjectsHidden">
<label class="form-control-label col-lg-12">ID Number</label>
<div class="col-lg-12">
<input type="text" name="idnumber" placeholder="111001111"
ng-model="user.idnumber"
ng-pattern="idpattern"
class="form-control input-lg"
required="required"></input>
<div ng-messages="idnumber.$error" ng-if="idnumber.$dirty">
<p ng-message="pattern">You are wrong!</p>
</div>
</div>
</div>
I'm not sure if it matters in terms of functionality where the <div ng-messages...> tag is, but I have also tried having it completely outside of this element with the same results. If I understand Angular and ngMessages correctly, I need to assign ng-messages to a directive--$error in this case--that I get to by dot-walking across name assignments. As far as I know, I have done this with idnumber.$error, although to be fair, I have also tried a more extensive dot-walk by using kiosk-form.uin.$error, where kiosk-form is the name of the entire form.
I have tried both ng-message="pattern" as well as ng-message="required". Also, just for clarity, idpattern is defined in my Javascript file as a regex string. It is defined correctly.
Rename your form as kioskFormand then ng-messages ="kioskForm.idnumber.$error"
I have searched for a solution all over, so here is my first question to this site:
I am trying to have some nice validation in angular (ionic) page where the logic is I want to show a "Required" message under label when either there is a validation error ($error.required) OR the field has not been touched and is empty (like a first time load). I can use pristine to check if it is not been modified, but if the form loads values from the model subsequently (like when restoring from localstorage), it still shows the "required" validation message.
I have tried the following:
<form name="wdform" novalidate>
<label class="item item-input item-stacked-label">
<span class="input-label green-small">ID</span>
<div class="validation" ng-show="wdform.userid.$error.required ||
(wdform.userid.$pristine && wdform.userid.length < 1)" >
Required
</div>
<input name="userid" ng-model="input.UserID" type="text" required>
</label>
... rest of form...
</form>
Also have tried:
<div class="validation" ng-show="wdform.userid.$error.required ||
(wdform.userid.$pristine && input.UserID.length < 1)" >
and various other permutations such as:
(wdform.userid.$pristine && input.UserID == '')
(wdform.userid.$pristine && wdform.userid.$invalid)
etc. ad nauseum.
On a separate but related note, I have also found that the built in validation is pretty brittle when it comes to form and field names... it only seems to work at all if the form name is only lowercase and/or contains no special characters ("DumbForm" and "dumb-form" fails, but "smartform" works).
Anyway, does anyone have any thoughts?
I feel like your two scenarios, (1) $error.required and (2) pristine and empty, might be redundant. Anytime #2 would be true, so would #1. I think you could use just #1.
Look at this example:
http://plnkr.co/edit/PgQ3vEIOKkfA38dDWjhp?p=preview
<body ng-controller="myController as vm">
<h1>Hello Plunker!</h1>
<form name="wdform">
<input type="text" name="userid" ng-model="userId" required/>
<div ng-show="wdform.userid.$error.required">Required</div>
</form>
</body>
However, it sounds like you are populating your form on page load some times from localStorage and somehow this is not causing the $error.required property to be changed to true, but it should. So your real problem I think lies in need to call $scope.$apply() or something to tell angular to run validations again.
I found that the issue was related to where the validation div was placed.
If the validation div was placed before the input field (so that it displayed the validation message beneath the field label), I encountered the error specified in this question.
By placing it after the input tag, it works as expected (with the validation message beneath the input field).
I would consider this a bug either in Angular or Ionic. Hopefully it will be corrected in the upcoming version 2 of both.
<button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="f3.form.reset()">
Just add the click in the button.so form loads values from the model in reset().Once click the button form will reset. You get new form with no errors.
I really struggling with this. I need to force the user to write the first and last name, in only one textbox.
I using AngularJS, and I want to validate text field using ng-pattern. The field should accept all characters, and require 2 words.
This is input:
<input name="fistname_lastname" ng-model="fistname_lastname" ng-pattern='my_pattern' type="text">
I have the my pattern in the controller, like this:
$scope.my_pattern = /^\s*\w*\s*$/;
Is there another better way do it.
Yes, you can do it by directive too, but just for validating just text contains two characters or not ng-pattern would be better way to do.
Here your html would be using (.*?[a-zA-Z]){2,} this pattern.
HTML
<input type="text" ng-model="fistname_lastname" max-length="30"
ng-pattern="/^(.*?[a-zA-Z]){2,}$/" placeholder="add new todo here"/>
Working Fiddle
Update
If you want to stop your form from submitting,, then you need to no worry about it. Angular internally manages this for you. Whenever you mention ng-pattern against any form field, angular creates object for that field (field should have name and ng-model attribute), that object is responsible for the validity of particular field. As as ng-pattern regx doesn't gets satisfied, angular make that field as invalid, means it append ng-invalid-pattern & ng-invalid class. Resultant the form also gets invalid. and now if you can look at form object you will find that form gets invalid by using syntax form.$valid on html.
HTML
<form name="form" ng-submit="submit()">
<input type="text" ng-model="firstname_lastname" size="30" ng-pattern="/^(.*?[a-zA-Z]){2,}$/" placeholder="add new todo here"/>
<button type="submit">Submit</button>
</form>
Controller
$scope.submit = function(){
if($scope.form.$invalid) //here you can stop use from submitting for by checking validity
alert('Form is invalid'); //form is invalid
else
alert('Form is valid');//here you can do actual submit to server
}
Updated Fiddle
Hopefully this could help you, Thanks.
Thanks, for all your help. But what really worked was this regular expression.
\b([A-Z]{1}[a-z]{1,30}[- ]{0,1}|[A-Z]{1}[- \']{1}[A-Z]{0,1}
[a-z]{1,30}[- ]{0,1}|[a-z]{1,2}[ -\']{1}[A-Z]{1}[a-z]{1,30}){2,5}
I am writing custom form validation, using ng-class to highlight required field, the syntax is:
<div class="form-group"
ng-class="{'has-error': dc.{{fname}}.nedatt({{fname}}.username)}">
<input class="form-control" name="username" type="text" placeholder="Username"
ng-required="true" ng-model="f1username"/>
<span class="help-block" ng-show="{{fname}}.username.$error.required">Required</span>
</div>
For ng-class I am getting:
Error: [$parse:syntax]
http://errors.angularjs.org/1.3.3/$parse/syntax?p0=.&p1=not%20a%20primary%20expression&p2=1&p3=.username.%24error.required&p4=.username.%24error.required
For help block am getting:
SyntaxError: Unexpected token ;
Actually fname is name of form to be replaced so am using inside {{}}. Please help, I am stuck.
You can not bind an angular expression in ng-class like that. You should use javascript notation instead. That means:
<div class="form-group"
ng-class="{'has-error': dc[fname].nedatt(getFormObject(fname).name)">
</div>
It looks that you are trying to dynamize the object that you use to check the name property. Unfortunately you can't do it like this, the object "must" be fixed, not a string. For that reason I would suggest calling a function in your controller or directive that returns the right object, and then, do whatever you need with it.
For the ng-show I would implement something similar. Just keep in mind that it will not be string-parsed, but directly evaluated (and in javascript {{foo}} is not right syntax)