how to call a method when change in field using angular JS? - angularjs

I am entering numbers in two fields and showing another field using arithmetic calculation.In that I wanna one call and that calculation and want to calculate using input type=" text" only not a number.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
First Name:
<input type="text" ng-model="firstvalue">
<br> Last Name:
<input type="text" ng-model="lastvalue">
<br>
<br>
<br> Total:
<input type="text" ng-model="total=firstvalue + lastvalue" ng-change="changed()" disabled="disabled">
<br>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.changed = function() {
alert("Total" + $scope.total);
};
});
</script>
</body>
</html>
i want to sum those two value.want show the sum in third field and also when change the third field need to call one function like ng-change that field need to disable.

You have very weird and unclear requirement. But this should help - https://jsfiddle.net/4qohy46L/
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
First Name:
<input type="text" ng-model="firstName" ng-change="recalculate()">
<br> Last Name:
<input type="text" ng-model="lastName" ng-change="recalculate()">
<br>
<br>
<br> Total:
<input type="text" ng-model="total">
<br>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.recalculate = function() {
var tempFirst = 0, tempSecond = 0
if($scope.firstName)
tempFirst = $scope.firstName;
if($scope.lastName)
tempSecond = $scope.lastName;
$scope.total = parseInt(tempFirst) + parseInt(tempSecond);
};
});
</script>
</body>
</html>
Please feel free to tell me if I have not correctly understood your question. And always prepare a fiddle or a plunker when you post a question on SO it makes it easier for people who want to help you :)

Related

How to set default decimal value to input in angularjs

I want to bind input value 0.00 to text box
then, if I changed input to 20 then on blur set 20.00
<input type="text" valid-decimal-number style="text-align:right" ng-model="Amount" ng-blur="ConvertToDecimal(Amount)">
angular script :
//converting value to decimal
$scope.ConvertToDecimal = function (val) {
$scope.Amount = eval(val).toFixed(2);
}
I am getting by using this code but, for every time I'm writing,
how to create custom directive for this
I tried like this also but not working.
<input type="text" valid-decimal-number style="text-align:right" ng-model="Amount" ng-blur="'Amount=(Amount).toFixed(2)'">
use a filter in ng-blur
ng-blur="Amount = (Amount | number : 2 )"
Demo
angular.module("app",[])
.controller("ctrl",function($scope){
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<input type="text" style="text-align:right" ng-model="Amount" ng-blur="Amount = (Amount | number : 2 )" >
</div>
You can apply toFixed(2) to numbers only
<html ng-app="myApp">
<head>
<title></title>
</head>
<body ng-controller="myCtrl">
<input type="text" valid-decimal-number style="text-align:right" ng-model="Amount" ng-blur="ConvertToDecimal()">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller('myCtrl', ['$scope', function ($scope) {
$scope.ConvertToDecimal = function (val) {
if(isNaN($scope.Amount)){
alert("given input is not a number");
return;
}
$scope.Amount = Number($scope.Amount).toFixed(2);
}
}]);
</script>
</body>
</html>

$watch running once instead of twice

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="abc">
<p>Input something in the input box:</p>
<p>Name : <input type="text" ng-model="name" placeholder="Enter name here"></p>
<h1>Hello {{name}}</h1>
</div>
<script>
var app=angular.module('myApp',[]);
app.controller('abc',
['$scope',function($scope) {
$scope.name='xyz';
var count=-1;
$scope.$watch('name',function(nv,ov){
console.log('OV',ov);
console.log('NV',nv);
$scope.name=nv;
count++;
console.log(count);
})
}]
)
</script>
</body>
</html>
Here $watch is running only once instead of twice minimum. If I assign ov to $scope.name $watch is running 11 times and in this case the value of name shouldn't change.
Try below code, below one is showing proper o/p for me may be you want the same one
<script>
var app=angular.module('myApp',[]);
app.controller('abc',['$scope',function($scope){
$scope.name='xyz';
var count=-1;
$scope.$watch('name',function(data){
console.log('data', data);
$scope.name=data;
count++;
console.log(count);
})
}])
</script>

The controller doesn't work when I use 'ng-app'

Here is a snippet:
<!document html>
<html ng-app>
<head>
<title>First</title>
<script src="D:\Coding\angular.min.js" type="text/javascript"></script>
</head>
<body>
<div ng-controller="FirstController">
<input id="Text1" type="text" ng-model="user.name" />
<div>{{user.name}}</div>
</div>
<script>
function FirstController($scope){
$scope.user = {name: ""};
};
</script>
</body>
</html>
Open the .html file with Chrome, the '{{user.name}}' shows on the screen. I think the {{}} position should be the same with the textbox content, what's wrong?
You need to use like this :
<ng-app="Your Module Name ">
In controller write
var app=angular.module("your module name (can be anything)",[]).controller("myCtrl", function("your dependencies "){});
Hope it will work
In the ng-app attribute you need to add app name like as ng-app="myApp"
<div ng-app="myApp" ng-controller="myCtrl">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>
If you are using angular version below 1.3 it should work
DEMO
<!DOCTYPE html>
<html ng-app>
<head>
<script src="https://code.angularjs.org/1.2.3/angular.js"></script>
</head>
<body>
<div ng-controller="FirstController">
<input id="Text1" type="text" ng-model="user.name" />
<div>{{user.name}}</div>
</div>
<script>
function FirstController($scope){
$scope.user = {name: "test"};
};
</script>
</body>
</html>
You need to add like this
ng-app="yourappname"
Refer ng-app directive in documentation

Not being able to iterate through inputs within scope

I'm trying to iterate through an array created using angular, so I can add them up and then show them, but the problem is, I'm getting an error saying that property '1' of undefined even if I fill out the input field, why is this?
My code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<title>jQueryForm</title>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div id="form" ng-init="dataSet = [{},{},{},{},{}]">
<div ng-repeat="data in dataSet">
<input type="checkbox" ng-model="data.checked" />
<label>Data:</label>
<input type="number" ng-model="data.number" />
<br/>
</div>
<span>{{result}}</span>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
for (var i = 1; i < 5; i++) {
$scope.result += $scope.dataSet[i];
}
});
</script>
</div>
</div>
</span>
</body>
</html>
As ng-init is special kind of directive which evaluates expression provided to it in preLink function of directive.
PreLink function: - this function gets evaluates after scope has been
created for that element
By reading above line you will come to know that it has evaluated for loop before $scope.dataset getting available. Which is obiviously going to get fail.
I'd say don't use ng-init for such cases. Place that initialization data inside controller itself.
Code
//remove ng-init directive from UI
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
function init(){
for (var i = 1; i < 5; i++) {
if($scope.dataSet[i].checked)
$scope.result += $scope.dataSet[i].number;
}
}
//init
$scope.dataSet = [{},{},{},{},{}]
init();
});
You have to initialize dataSet differently this time around. Just add it to the controller's scope instead of using ng-init.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<title>jQueryForm</title>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div id="form">
<div ng-repeat="data in dataSet">
<input type="checkbox" ng-model="data.checked" />
<label>Data:</label>
<input type="number" ng-model="data.number" />
<br/>
</div>
<span>{{result}}</span>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.dataSet = [{},{},{},{},{}];
for (var i = 1; i < 5; i++) {
$scope.result += $scope.dataSet[i];
}
});
</script>
</div>
</div>
</span>
</body>
</html>
To make the code work, though, you'll have to change a few things. The loop in which you try adding the numbers will be called only once - at instantiation time of the controller. At that time, no number has been entered, yet. You could solve it with a button. (Also add up the numbers, not the objects in dataSet)
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<title>jQueryForm</title>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div id="form">
<div ng-repeat="data in dataSet">
<input type="checkbox" ng-model="data.checked" />
<label>Data:</label>
<input type="number" ng-model="data.number" />
<br/>
</div>
<button ng-click="calculate()">calculate</button>
<span>{{result}}</span>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.dataSet = [{},{},{},{},{}];
$scope.calculate = function() {
$scope.result = 0;
for (var i = 0; i < $scope.dataSet.length; i++) {
if(angular.isNumber($scope.dataSet[i].number) && $scope.dataSet[i].checked)
$scope.result += $scope.dataSet[i].number;
}
};
//Edit. Doesn't have the best performance, keep dataSet small
$scope.$watch('dataSet', function(newValue, oldValue) {
$scope.calculate();
}, true);
});
</script>
</div>
</div>
</span>
</body>
</html>
I fixed a few more things here and there. I assumed, you wanted to add only those numbers that were checked - also, the ng-models without a value were causing problems, that's why the check for being a number was introduced.
edit:
As you wanted to do it without the button: You can use a deep $scope.$watch.
https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch
Thanks to #Pankaj Parkar and #JanS, I finally made what I wanted to, everytime the input is changed I call the function calculate(); and everytime a checkbox is clicked on I call it as well.
Code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<title>jQueryForm</title>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div id="form">
<div ng-repeat="data in dataSet">
<input ng-click="calculate()" type="checkbox" ng-model="data.checked" />
<label>Data:</label>
<input ng-change="calculate()" type="number" ng-model="data.number" />
<br/>
</div>
<span>{{result}}</span>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.dataSet = [{}, {}, {}, {}, {}];
$scope.calculate = function() {
$scope.result = 0;
for (var i = 0; i < $scope.dataSet.length; i++) {
if (angular.isNumber($scope.dataSet[i].number) && $scope.dataSet[i].checked)
$scope.result += $scope.dataSet[i].number;
}
}
});
</script>
</div>
</div>
</span>
</body>
</html>

Clone Elements in Angular

I got this code from Vladyslav Babenko from this post over here (Clone elements in angularjs):
var App = angular.module('App', []).controller('Test', ['$scope',
function($scope) {
$scope.inputCounter = 0;
$scope.inputs = [{
id: 'input'
}];
$scope.add = function() {
$scope.inputTemplate = {
id: 'input-' + $scope.inputCounter,
name: ''
};
$scope.inputCounter += 1;
$scope.inputs.push($scope.inputTemplate);
};
$scope.teste = function (pergunta) {
console.log("in");
}
}
])
<!DOCTYPE html>
<html ng-app="App">
<head lang="en">
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body ng-controller="Test">
<form ng-submit="teste()">
<div class="pure-g entry" ng-repeat="input in inputs track by input['id']">
<div class="pure-u-1-5">
<input type="text" class="pure-input-1" id="input" name="input-1">
</div>
<div class="pure-u-1-5">
<input type="text" class="pure-input-1" id="date" name="date">
</div>
<div class="pure-u-1-5">`enter code here`
<input type="text" class="pure-input-1" id="input-2" name="input-2">
</div>
</div>
</form>
<button type="button" id="add" ng-click="add()">Add</button>
<button type="submit">teste</button>
</body>
</html>
It works fine, but when a add multiples forms, how can I get the values from each form?
Give every input a ng-model:
<input type="text" class="pure-input-1" id="input-2" ng-model="user.name" name="input-2">
Now you can adress the input value in your controller with:
$scope.user.name
Read more about this topic: https://docs.angularjs.org/guide/forms

Resources