Bind to a property which is a formula exposing another - angularjs

In Angular (1.3), I want to be able to enter a dob field of my person object and this has another property called age which calculates the age based on the dob.
So I have the field to enter dob as:
<div class="form-group">
<input class="form-control" type="date" ng-model="player.dob" placeholder="DD/MM/YYYY" />
</div>
and I display some of the information that the user types, as they type (name, sex, description etc) but when the user enters the dob, I want to automatically display age like this:
<div>{{player.age}}</div>
How can I do that?
Thanks

I don't know if it's what you're looking for, but if I'm correct you can create a custom filter to display the age based on the dob input, as below:
angular.module('app', [])
.controller('mainCtrl', function($scope) {
$scope.player = {};
})
.filter('ageFilter', function() {
return function(dob) {
var ageDifMs = Date.now() - new Date(dob).getTime();
var ageDate = new Date(ageDifMs);
return Math.abs(ageDate.getUTCFullYear() - 1970);
};
});
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<div class="form-group">
<input class="form-control" type="date" ng-model="player.dob" placeholder="DD/MM/YYYY" />
</div>
<hr>
<div ng-if="player.dob" ng-bind="player.dob | ageFilter"></div>
</body>
</html>

you can use ngChange
<div class="form-group">
<input class="form-control" type="date" ng-model="player.dob" ng-change="calculateAge()" placeholder="DD/MM/YYYY" />
and then in your controller:
$scope.calculateAge = function(){
//do the calculations you want
}

Related

Writing an adding function in AngularJS

I'm new to AngularJS and I am doing some tutorials to get in touch with it. While I'm doing the tutorials I have modified the code a bit to get a better feeling of what's behind. My code consists of two parts, which have nothing to do with each other.
The first one is a simple user input and based on that a list gets filtered. This is working fine.
However, in the second part I was trying to implement a simple adding function where the user can give an input and based on that the sum of two numbers is calculated. This part is not working at all. The numbers are being recognised as strings. The code is basically from this source here. When I copy the whole code and run it, it works fine, but when I modify it a bit it doesn't.
I want to understand why my code isn't working. To me there is nearly no difference. So I think that I eventually misunderstood the concept of angularjs. But I can't figure out where the error could be.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script type="text/javascript">
function TodoCtrl($scope) {
$scope.total = function () {
return $scope.x + $scope.y;
};
}
</script>
</head>
<body data-ng-app>
<input type="text" ng-model="name">{{name}}
<div data-ng-init="Names=['Arthur', 'Bob', 'Chris', 'David', 'EDGAR']">
<ul>
<li data-ng-repeat="naming in Names | filter: name ">{{naming}}</li>
</ul>
</div>
<div data-ng-controller="TodoCtrl">
<form>
<input type="text" ng-model ="x">{{x}}
<input type="text" ng-model ="y"> {{y}}
<input type="text" value="{{total()}}"/>
<p type= "text" value="{{total()}}">value</p>
</form>
</div>
</body>
</html>
Several things to change...
First you need to create a module:
var app = angular.module("myApp", []);
Then you need to define a module e.g. myApp on the ng-app directive.
<body data-ng-app="myApp">
Then you need to add TodoCtrl to the module:
app.controller("TodoCtrl", TodoCtrl);
Also check that both $scope.x and $scope.y have values, and make sure that they are both parsed as integers, otherwise you will get string concatenation ("1"+"1"="11") instead of addition (1+1=2)!
$scope.total = function () {
return ($scope.x && $scope.y)
? parseInt($scope.x) + parseInt($scope.y)
: 0;
};
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script type="text/javascript">
(function(){
var app = angular.module("myApp", []);
app.controller("TodoCtrl", TodoCtrl);
function TodoCtrl($scope) {
$scope.total = function () {
return ($scope.x && $scope.y)
? parseInt($scope.x) + parseInt($scope.y)
: 0;
};
}
}());
</script>
</head>
<body data-ng-app="myApp">
<input type="text" ng-model="name">{{name}}
<div data-ng-init="Names=['Arthur', 'Bob', 'Chris', 'David', 'EDGAR']">
<ul>
<li data-ng-repeat="naming in Names | filter: name ">{{naming}}</li>
</ul>
</div>
<div data-ng-controller="TodoCtrl">
<form>
<input type="text" ng-model ="x">{{x}}
<input type="text" ng-model ="y"> {{y}}
<input type="text" value="{{total()}}"/>
<p type= "text" value="{{total()}}">value</p>
</form>
</div>
</body>
</html>
As mentioned in the above two answers adding TodoCtrl as controller instead function will make the snippet work.
REASON:
Angularjs framework above 1.3 does not support global function which means declaring controller as function wont work.
In your code snippet, you are using angular version 1.5, which needs the controller to be defined.
DEMO
angular.module("app",[])
.controller("TodoCtrl",function($scope){
$scope.x = 0;
$scope.y = 0;
$scope.total = function () {
return parseInt($scope.x) + parseInt($scope.y)
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" >
<input type="text" ng-model="name">{{name}}
<div data-ng-init="Names=['Arthur', 'Bob', 'Chris', 'David', 'EDGAR']">
<ul>
<li data-ng-repeat="naming in Names | filter: name ">{{naming}}</li>
</ul>
</div>
<div data-ng-controller="TodoCtrl">
<form>
<input type="text" ng-model ="x">{{x}}
<input type="text" ng-model ="y"> {{y}}
<input type="text" value="{{total()}}"/>
<p type= "text" value="{{total()}}">value</p>
</form>
</div>
</div>
you need to define the TodoCtrl as controller instead function
.controller("TodoCtrl",function($scope){
$scope.x = 0;
$scope.y = 0;
$scope.total = function () {
return parseInt($scope.x) + parseInt($scope.y)
};
})
Demo
angular.module("app",[])
.controller("TodoCtrl",function($scope){
$scope.x = 0;
$scope.y = 0;
$scope.total = function () {
return parseInt($scope.x) + parseInt($scope.y)
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" >
<input type="text" ng-model="name">{{name}}
<div data-ng-init="Names=['Arthur', 'Bob', 'Chris', 'David', 'EDGAR']">
<ul>
<li data-ng-repeat="naming in Names | filter: name ">{{naming}}</li>
</ul>
</div>
<div data-ng-controller="TodoCtrl">
<form>
<input type="text" ng-model ="x">{{x}}
<input type="text" ng-model ="y"> {{y}}
<input type="text" value="{{total()}}"/>
<p type= "text" value="{{total()}}">value</p>
</form>
</div>
</div>

Cannot find module with name 'my'. Cannot find controller with name 'mycontroller'

Hi I am getting the following error:
Error : Cannot find module with name "my".
And also
Multiple annotations found at this line:-
Cannot find module with name my. Cannot find module with name my.
Cannot find controller with name mycontroller
Please help. Thanks But I am able to run the code perfectly though the error exists.
My code is as below:
<!DOCTYPE html>
<html ng-app="my">
<head>
<script src="angular.js"></script>
<script>
var validation = angular.module('my', []);
validation.controller('mycontroller' , function($scope) {
$scope.firstName = "madhuri";
$scope.email = "madhuri#gmail.com";
$scope.age = "24";
$scope.pattern = /^\d*$/;
});
</script>
</head>
<body >
<div ng-controller="mycontroller">
<form name="form1">
<label>Name :</label> <input type="text" name="name" ng-model="firstName" required>
<span style="color: red" ng-show="form1.name.$error.required"> please provide the name</span>
<br>
<br>
<label>Email: </label> <input type="email"
name="email" ng-model="email">
<span style="color: red" ng-show="form1.email.$error.email"> please provide the valid email address </span>
<p style= "color: red" ng-show="form1.email.$error.email">please provide the valid email address</p>
<label>age :</label>
<input type="text" name="age" ng-model="age" ng-pattern="pattern">
<span style="color: red" ng-show="form1.age.$error.pattern"> please provide the correct age
</span>
</form>
</div>
</body>
</html> -->`
Try changing how your instantiating your controller. Try this:
<script>
var validation = angular.module('my', []);
angular.module('my').controller('mycontroller' , function($scope) {
$scope.firstName = "madhuri";
$scope.email = "madhuri#gmail.com";
$scope.age = "24";
$scope.pattern = /^\d*$/;
});
</script>
Alternatively you could also instantiate it like this:
<script>
var validation = angular.module('my', []).controller('mycontroller' , function($scope) {
$scope.firstName = "madhuri";
$scope.email = "madhuri#gmail.com";
$scope.age = "24";
$scope.pattern = /^\d*$/;
});
</script>
I have also added a JSFIDDLE that works both ways to show that they work
jsFiddle

Angularjs repeat form fields

I've built a shopping cart for a training site. People can purchase a number of 'seats' for each training session. What I need to add is a form requiring the name and email for each seat(attendee). So if someone purchases 3 seats, then I will need to generate form fields for each attendee.
I'm assuming there's something in the following code that plays a part in solving this problem but I'm not skilled enough in Angular to work it out.
ng-repeat="i in quantity track by $index"
look at this codepen
it works fine :)
var app = angular.module('myapp',[]);
app.controller('ctrlParent',function($scope){
$scope.myNumber=1;
$scope.range = function(count){
var output = [];
for (var i = 0; i < count; i++) {
output.push(i)
};
return output;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp">
<div ng-controller="ctrlParent">
<input ng-model="myNumber" type="text" placeholder="Quantity"/>
<form ng-repeat="i in range(myNumber) track by $index">
<input type="text" placeholder="Name"/>
<input type="text" placeholder="Name"/>
<input type="text" placeholder="Name"/>
<input type="button" value="Ok"/>
</form>
</div>
</div>
First, get the number of seats, in the form (send the seats number by events OR shared service if the form are in another angular controller) So, let say $scope.nbrSeats (initial value = 0) in forms controller.
Second, using ng-repeat :
<form ng-repeat="i in nbrSeats">...</form>
Here is a working example for you:
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.quantity = '1';
$scope.availableQuantity = '10';
$scope.range = function(num) {
num = parseInt(num);
return new Array(num);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<form name="myForm">
<select ng-model="quantity">
<option ng-repeat="option in range(availableQuantity) track by $index">{{$index + 1}}</option>
</select><br/><br/>
<div ng-repeat="customer in range(quantity) track by $index">
Customer {{$index + 1}} name: <input type="text" ng-model="customer_$index"><br/>
</div><br/><br/>
<button type="submit">Purchase</button>
</form>
</div>

angular removes ng-model variable if ng-required is true

as in the title.. how to prevent such operations to happen? Here is a link to the official site, see the example. The variable user.name is bound to the first input userName and if the input is empty the object user.name is removed. How can I disable this functionality of angularjs?
Try ng-model-options="{allowInvalid: true}" to update the model even for invalid entries.
<input ng-model="user.name" required ng-model-options="{allowInvalid: true}">
You've got 2 option
remove required from input tag it allows you to send back empty string to your backend
var app = angular.module('app', []);
app.controller('MyCtrl', function($scope) {
$scope.params = {
user: "John"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<input name="userName" ng-model="params.user" />
<hr/>
<pre>{{params| json}}</pre>
</div>
Option two validate your form before you send it to backend.
var app = angular.module('app', []);
app.controller('MyCtrl', function($scope) {
$scope.user = {
name: "John"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<form name="someForm">
<input name="userName" ng-model="user.name" required name="userName" />
<span ng-show="someForm.userName.$error.required">User Name required</span>
<br/>{{user | json}}
<br/>
<button type="submit" ng-disabled="someForm.$invalid">Submit</button>
</form>
</div>

map bind with ng-model not updating data

I called REST service which gives me an Object contains a map.
Map in java looks like Map
Following is my js
$scope.marks = {};
//get data from rest
StudentService.query().$promise.then(function(data)
{
$scope.students = data;
for(var i=0;i<$scope.students.length;i++){
var obj = $scope.students[i];
//marks (key=studentName, value=mark in decimal)
$scope.marks[obj["studentName"]]=0.0;
}
following is my html
<div class="row" ng-repeat="(key,value) in marks">
<input type="text" class="form-control" ng-model="key" disabled>
{{marks[key]}} <!-- Here it is not updating value from above model-->
<input type="number" class="form-control" ng-model="value">
</div>
When I update value in textfield it is not update value displayed just below textfiled ie {{marks[key]}} is not showing updated value. Please correct me if wrong. Thank you :)
What you are passing to the ng-model is just a string, which is immutable. You need to define the ng-model like this:
<input type="number" class="form-control" ng-model="marks[key]">
angular.module('app', [])
.controller('Ctrl', function($scope) {
$scope.marks = {
mark1: 1,
mark2: 2,
mark3: 3
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="Ctrl">
<div class="row" ng-repeat="(key,value) in marks">
<input type="text" class="form-control" ng-model="key" disabled>{{marks[key]}}
<!-- Here it is not updating value from above model-->
<input type="number" class="form-control" ng-model="marks[key]">
</div>
</div>

Resources