Angular ngApp directive - angularjs

<div ng-app="">
<form>
First Name: <input type="text" ng-model="firstname">
</form>
<h1>You entered: {{firstname}}</h1>
</div>
The above code will fine. But if the ng-app="" directive if moved to form element then it won't work. Any idea why is this. Why the form element will not take ng-app directive and bootstrap the application.
// This will not work
<div>
<form ng-app="">
First Name: <input type="text" ng-model="firstname">
</form>
<h1>You entered: {{firstname}}</h1>
</div>
Thanks

Ideally ng-app should be at root level. but in your code, some part is outside the ng-app which angular don't take care of
e.g.the h1 tag
you may write it within the form element or take ng-app to the root level
<div>
<form ng-app="">
First Name: <input type="text" ng-model="firstname">
<h1>You entered: {{firstname}}</h1>
</form>
</div>

It will work, the problem with that the scope of the app. You defined ng-app on <form ng-app=""> so the scope is limited only to the start to end of the tag. Now you placed <h1>You entered: {{firstname}}</h1> outside the boundaries of ng-app so it won't work.
Check the working plnkr - http://plnkr.co/edit/zaTdGCouFrAXJywUSpcl?p=preview
<form ng-app="">
First Name: <input type="text" ng-model="firstname">
<h1>You entered: {{firstname}}</h1>
</form>

From the docs for ng-app:
Use this directive to auto-bootstrap an AngularJS application. The
ngApp directive designates the root element of the application and is
typically placed near the root element of the page - e.g. on the
or tags.
In this code, the ng-app directive is at top level and the angular expression {{firstname}} will take its value from the model.
<div ng-app="">
<form>
First Name: <input type="text" ng-model="firstname">
</form>
<h1>You entered: {{firstname}}</h1>
</div>
In this code, the angular expression {{firstname}} can't resolve to its model since it lies out of the angular ng-app. Thus it acts simply as plain text.
<div>
<form ng-app="">
First Name: <input type="text" ng-model="firstname">
</form>
<h1>You entered: {{firstname}}</h1>
</div>

ng-app is directive which is use to initialize the application
so mostly it is used on <body> tag or main tag of application
Like :-
<body ng-app="myApp"></body>
OR
<div ng-app="myApp">
<form>
// add other elements
</form>
</div>
So this type of directive is not applicable for child elements, even if you apply it will not work because by doing this app will not consider parent element so obviously child element also will not worked
In your case if you are using <form> tag on top level then you can use it like :-
<body>
<form ng-app="myApp">
</form>
</body>

Related

How to validate AngularJS form input while is using ng-repeat

I have a form which has input fields that is dynamically built using ng-repeat. How I can validate these fields are greater than another input field. Please look at this sample code.
<html ng-app>
<head>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body ng-init="weekDays = ['monday', 'tuesday', 'wednesday','thursday', 'friday', 'saturday','sunday']">
<h1>Fun with Fields and ngModel</h1>
<p>days: {{weekDays}}</p>
<h3>Binding to each element directly:</h3>
<div ng-repeat="weekday in weekDays">
Value: {{weekday}}
{{day='day_'+weekday; ""}}
<input name="{{day}}" ng-model="val">
</div>
<div>
Number to validate : <input name="numToValidate">
</div>
</body>
I am very new to angularJS and still learning. However I couldn't able to think through this simple validation. Please help.
Html:
<form name="form">
<div ng-repeat="weekday in weekDays">
Value: {{weekday}}
{{day='day_'+weekday; ""}}
<input name="{{day}}" ng-model="val" required>
</div>
<div>
Number to validate : <input name="numToValidate" required>
</div>
</form>
Script:
if($scope.form.$valid){
// You can write your code here what you want to do after validate.
}
You can use html form element with min attribute to check validity
<input name="{{day}}" ng-model="weekday.val" min="{{numToValidate}}">
you will need seperate model for each of your inputs in your ng-repeat therefore I changed your ng-model with the following
ng-model="weekday.val"
if you do not want to use form you can check the validity of your value with ng-blur directive (triggered when input loses focus).
html
<input name="{{day}}" ng-model="weekday.val" ng-blur="checkValid(weekday.val)">
js
$scope.checkValid = function(value){
if(value > $scope.numToValidate){
alert("please enter a valid number");
}
}

AngularJS - ng-maxlength

I've been through all of similar/relative topics on ng-maxlength on StackOverflow, but still could not find an answer. My problem is the following snippet of code:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<div class="form-group field keywords-input-block">
<label>Keywords</label>
<form name="keywords">
<input class="form-control searchKeywordValidator"
type="text"
placeholder="Enter keywords..."
ng-maxlength="5"
name="keywordInput"
ng-model="vm.jobList.keywords">
<h1 ng-if="!keywords.keywordInput.$valid">The value is too long</h1>
</form>
</div>
The error message, which should be displayed only if the input is invalid, is constantly shown! Any advise on what it the reason for that and how could I get rid of it would be highly appreciated!
All angularjs applications must have a root element in order to allow angularjs to be able to effective on your view. And that is ng-app directive. This directive is to auto-bootstrap an AngularJS application
You must add it somewhere to the root element
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<div class="form-group field keywords-input-block" ng-app="">
<label>Keywords</label>
<form name="keywords">
<input class="form-control searchKeywordValidator"
type="text"
placeholder="Enter keywords..."
ng-maxlength="5"
name="keywordInput"
ng-model="vm.jobList.keywords">
<h1 ng-if="!keywords.keywordInput.$valid">The value is too long</h1>
</form>
</div>
Read more about it here

Cannot access form from Scope AngularJS

I have the following
<form id="myForm" class="form-inline" >
<div class="container-fluid ">
<input ng-class="{'requiredError':programNameError}" name="first" ng-model="ProgramDetail.ProgramName" placeholder="Name" class="form-control input-xs" type="text" style="width:70%" />
</div>
</form>
This page is being called by the ngRoute when I navigate to a specific route and I specify the controller in the route configuration, buen when I try to access the $scope.myForm i get undefined.
Am I missing something here?
Give the form a name attribute to expose it on the $scope
<form id="myForm" name="myForm" class="form-inline" >
</form>
From the docs:
If the name attribute is specified, the form controller is published
onto the current scope under this name.
Argh, not enough reputation to write a comment, so writing as an answer.. :(
try defining the attribute name for the form.. I have a similar case and it worked only with this..
<form id="myForm" class="form-inline" name="myForm">
</form>

Angular validator, pass data along with error code to be displayed in ngMessages

Is that possible to store some additional data along with the error flag itself, using standard Angular mechanism?
i.e. I'm manually setting ngModel.$setValidity, I'd like to pass some data along with the error flag, to be displayed in ngMessages directive.
For example let's assume the min/max length of the field depends upon some external factors, thus is computed & validated server-side. The server respons with customlength error code along with max and min properties, which I'd like to display to the user.
Currently I'm simply setting ngModel.$setValidity("customlength", false); but I'd like to pass {max: response.max, min: response.min} along, to be interpolated in the template like <div ng-message="customlength">the length should be between {{ data.min }} and {{ data.max }}
I'd like to pass {max: response.max, min: response.min} along, to be interpolated in the template like the length should be between {{ data.min }} and {{ data.max }}
Use the root scope to store the value(s) intended to be output within the message string:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular-messages.js"></script>
<script>
angular.module('ngMessagesExample',['ngMessages']);
</script>
<body ng-app="ngMessagesExample">
<form name="myForm" id="{{$root.$id}}">
<label>
<p>Enter Min:<input type="text" ng-model="form_min">
<p>Enter Max:<input type="text" ng-model="form_max">
<p>Enter your name:
<input type="text"
name="myName"
ng-model="name"
ng-minlength="form_min"
ng-maxlength="form_max"
required />
</label>
<p>
<input type="radio" required name="foo" ng-model="foo" value="1">Yes
<input type="radio" required name="foo" ng-model="foo" value="2">No
</p>
<p>
Foo: <input type="text" ng-model="myForm.foo.$modelValue">
</p>
<p>
<input type="submit" value="{{myForm.foo.$error.required ? 'No' : 'Yes'}}">
</p>
<pre>myForm.myName.$error = {{ myForm.myName.$error | json }}</pre>
<div ng-messages="myForm.foo.$error" style="color:maroon" role="alert">
<div ng-message="required">Pick one</div>
</div>
<div ng-messages="myForm.myName.$error" style="color:maroon" role="alert">
<div ng-message="required">Your value should be between {{form_min}} and {{form_max}} characters long</div>
<div ng-message="minlength" id="{{$id}}">Your value is less than {{form_min}}</div>
<div ng-message="maxlength" id="{{$id}}">Your value is greater than {{form_max}}</div>
</div>
</form>
</body>
References
Easy Form Validation in AngularJS with ngMessages — SitePoint
AngularJS: Developer Guide: Migrating from Previous Versions
Explicitly providing ng-model to DOM elements | TO THE NEW Blog
Using NgModelController with Custom Directives

Why those 3 fields don't get updated together?

Following this video tutorial, I am trying to bind three text inputs together.
But only the first get updated.
Here is my JsFiddle attempt
the index.html relevant part :
<body ng-app="">
<input type="text" placeholder="Your text" ng-model="data.message"></input>
<h2>{{data.message}}</h2>
<div ng-controller="FirstController">
<input type="text" placeholder="Your text" ng-model="data.message"></input>
<h2>{{data.message}}</h2>
</div>
<div ng-controller="SecondController">
<input type="text" placeholder="Your text" ng-model="data.message"></input>
<h2>{{data.message}}</h2>
</div>
</body>
script.js
function FirstController($scope){
}
function SecondController($scope){
}
What did I miss ?
Please also notice, that I do need the nested div tags and controller, as the purpose is to use scope inheritance.
Also, these global function definitions for the controllers are a choice, as I wanted to keep the video author method for now, in my real projects I will use the best practise which consist of using a module var controller() method).

Resources