ng-maxlength not working for a variable - angularjs

I'm trying to use ng-maxLength directive to give a variable max-length for my inputs.
function ValidatorCtrl($scope, $timeout) {
$scope.name = "Star";
$scope.$metadata={};
$scope.$metadata.isRequired = true;
$scope.$metadata.maxLength=5;
}
<input type="text" ng-model="name" ng-maxlength="$metadata.maxLength"
ng-required="$metadata.isRequired" name="name" />
But it doesn't seems to be working as expected. When it is applied the model binding for the same variable is not working. Here is my plunker
If I remove ng-maxLength ng-required is going to work as expected , otherwise ng-required is also not working.

ng-maxlength does not take scope values.
Traditionally ng-maxlength is used as such ng-maxlength="3".
You can either add curly braces around your scope value or create a directive that binds scope value inside ng-maxlength.

Related

Few queries about form validation by Angular js

i am new in angular and trying to learn it.
https://scotch.io/tutorials/angularjs-form-validation
https://scotch.io/tutorials/angularjs-form-validation-with-ngmessages
i was reading article on form validation by angular js and i stumble in few area which i would like to discuss here.
1) what is difference between $pristine and $dirty. both looks same.
2) need to understand $touched? what it does ?
3) see the below code
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" ng-model="name" required>
</div>
<!-- USERNAME -->
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="form-control" ng-model="user.username" ng-minlength="3" ng-maxlength="8">
</div>
for first one ng-model="name" and second one ng-model="user.username"
why some time only property name declared for ng-model and why some time we have to write username dot property name ?
4) <input type="email" name="email" class="form-control" ng-model="email">
type="email" is anything specific to angular or html5?
5) <p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">You name is required.</p>
they check $invalid and $pristine. can they use $invalid and $dirty instead of $pristine here ?
6) see the code
angular
.module('app', ['ngMessages'])
.controller('MainCtrl', MainCtrl);
function MainCtrl() {
}
are they injecting other directive into app module....this is the way to inject
.module('app', ['ngMessages'])
please see my points and guide me with answer for my each points if possible. your answer would help me to understand and learn angular js.thanks
1) $pristine is for indicating that the field has not been modified, whereas $dirty is for telling it has been modified.
$pristine: It will be TRUE, if the user has not interacted with the form yet.
$dirty: It will be TRUE, if the user has already interacted with the form.
2) $touched tells you whether the user has merely been there/visited.
$touched: True if control has lost focus.
3) because for ng-model="name", name property is directly bound to $scope, and for ng-model="user.username", user is bound to $scope and user has a property username.
Think of it as:- user is an object and username is its property.
4) Not sure, but i think not anything specific.
5) Yes
6) Yes here you are injecting ngMessages in your angular module
$pristine is the inverse of $dirty.
The documentation says: A model is considered to be touched when the user has first focused the control element and then shifted focus away from the control (blur event)..
Because some time you want to bind the control to a variable in the scope, and sometimes you want to bind it to a field of an object that is in the scope. The latter is recommended. In particular, the former causes problems when used inside a directive (like ng-if or ng-repeat) that has its own scope, because it would set the field in the child directive scope instead of the controller scope. As a rule of thumb, always use the latter, and always initialize the object (i.e. user) in the controller.
it's both. It's specified in the HTML5 spec, and angular validates that the entered string is indeed a valid email address.
yes, since $dirty is the inverse of $pristine
That doesn't inject anything. 'ngMessages' is the name of a module. This declaration says that the module 'app' depends on the module 'ngMessages'. So all the directives, services, controllers and filters defined in the ngMessages module will be available in the app module.

Angular : Put in ng-model a value set in scope

In the ng-model, i want to set a default value defined in my scope but the value is not recognized.
Here's my controller :
$scope.defaultRole = "Admin";
My view :
<input type="text"
class="form-control" ng-model="user.role='{{defaultRole}}'">
but i have {{defaultRole}} instead of Admin in my input text. Maybe it's a problem of formating but i dont know how to make it work.
Note : i can put ng-model="user.role='Admin'" directly, but i want it from the scope.
Thank you for your help !
You don't understand how ngModel works. ngModel expects an assignable angular expression. The expression is bound two way. That means that
to populate the input field, angular evaluates the expression
when the value entered in the input field changes, the variable that the ngModel expression refers to is set to the entered value
So, all you need is
<input type="text" class="form-control" ng-model="defaultRole">
That will read the defaultRole variable and populate the field with its value, and vice versa.
If you want, instead, to populate user.role with the entered value, and the field to have the defaultRole value by default, then it should be
<input type="text" class="form-control" ng-model="user.role">
and the controller should do
$scope.user.role = $scope.defaultRole;
or, if user doesn't exist yet
$scope.user = {
role: $scope.defaultRole
};
to initialize user.role to its default value.
You can do that by using ng-init. ng-model isn't suppose to deal with affectation. This will be done directly by angular.
<input type="text" class="form-control" ng-model="user.role" ng-init="user.role = defaultRole">
Working Fiddle

Why is that the state of an ng-form within a directive does not propagate to an outer ng-form?

I have a myInputText directive that dynamically generates its template within the link function. It contains an input that has a ng-form around it. The input has the ng-required attribute set to true. The state of the input (e.g. ng-invalid-required) propagates to the ng-form inside the directive, but not to the ng-form outside of the directive.
Consider the case when the input is empty, therefore its class attribute has a value of ng-invalid ng-invalid-required, and so does the innerForm, but the outerForm is oblivious of that, being ng-pristine ng-valid.
<ng-form name="outerForm" id="outerForm">
<my-input-text form-name="myForm0" field="myField0" app-model="myAppModel></my-input-text>
</ng-form>
Here's a plnkr to demonstrate the behavior:
http://plnkr.co/edit/8vGKRN4cJHs224uN2k9T?p=preview

validate input with name containing brackets in AngularJS

I have a form input with names containing brackets, e.g.:
<form name="my_form">
<input type="text" name="my_form[email]" ng-model="email" ng-class="'mycssclass': my_form.my_form[email].$invalid">
</form>
So, the problem is that Angular is not applying that css class because of the name of my input (my_form[email]), is that the correct notation to reference my input in Angular.
Here's is a plunk:
http://plnkr.co/edit/t7PEilV9maNYGnVYnTDc?p=preview
The way to reference an input with a name containing brackets is using brackets notation, like this:
my_form['my_form[email]'].$invalid
You need to use the ng-model attribute in your input. It bind the content of a field with a value in the $scope. You also need to pass a Javascript Object to the ng-class directive. In your example it would be :
<form name="my_form">
<input type="text" ng-model="my_form.email" ng-class="{'mycssclass': my_form.email.$invalid}">
</form>
Don't hesitate to look at the examples in the ng-model and ng-class directive documentation.

AngularJS: How do I bi-directionally bind to the parent scope property without using an attribute?

So I want to do what I did in this question:
AngularJS: Two way data binding fails if element has ngModel and a directive with a local scope
but without using an attibute value to bind. I've tried using just an equals sign
scope: {bindToParent: '='},
but it doesn't seem to work? Can someone change this jsfiddle: http://jsfiddle.net/ews7S/1/ to show me how I can directly bind to the parent property without having to use an attribute in the element?
You have in your fiddle:
<input type="text" ng-model="testModel" dir="123">
If you want dir to not have a value, well, dir doesn't need a value. This works as well in your fiddle:
<input type="text" ng-model="testModel" dir>

Resources