angularJs - update range and number input simultaniously fails - angularjs

I would like to change a range and an input box simultaneously using AngularJs but getting this error: "http://errors.angularjs.org/1.3.11/ngModel/numfmt?p0=0.6"
I think the cause is the range updating the model with strings instead of numeric values but this doesn't get me closer to the solution.
<html ng-app="app">
<div ng-controller="controller">
<input type="number" min="0" max="1" step="0.1" ng-model="value" />
<input type="range" min="0" max="1" step="0.1" ng-model="value"/>
</div>
</html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
<script>
var app = angular.module('app', []);
app.controller('controller', function($scope) {
$scope.value = 0.5;
});
</script>
How can I make the changes of the range applied on the input box without the error?
note: the obvious solution is to change the type of the input box to "text", but I would NOT like to allow non-numeric values there.

You can use parseFloat:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.js"></script>
</head>
<body ng-app="boltlandApp">
<div ng-controller="controller">
<input type="number" min="0" max="1" step="0.1" ng-model="value" />
<input type="range" min="0" max="1" step="0.1" ng-model="range"/>
</div>
</body>
<script>
var app = angular.module('boltlandApp', []);
app.controller('controller', function($scope) {
$scope.value = 0.5;
$scope.range = 0.5;
$scope.$watch('range', function (newVal, oldVal) {
$scope.value = parseFloat(newVal);
});
$scope.$watch('value', function (newVal, oldVal) {
$scope.range = newVal;
});
});
</script>
</html>

seems to be a bug:
https://github.com/angular/angular.js/issues/5892
A workaround is:
$scope.$watch('value', function() {
$scope.value = parseFloat($scope.value);
});

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>

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

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 :)

angularjs fetch value from textbox after clicking a button only

This is my code
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('myController', function ($scope) {
$scope.getName = function () {
$scope.name = fname;
$scope.lastName = lastName;
};
})
</script>
</head>
<body ng-app="myApp" >
<div >
<input type="text" ng-model="name"/> <br>
<input type="text" ng-model="lastName" />
</div>
<div ng-controller="myController">
<input type="button" value="click" ng-click="getName()" />
<br>
Hello FirstName {{name}}<br>
Last Name {{lastName}}
</div>
</body>
</html>
values are coming while typing into textbox but i want values only after clicking the button.Please help me.
I tried in both ways simple as well as by using service or factory method but no success
You must separate the ng-models of the input texts and destination field. They are updating real-time because of having the same models.
I have created the correct version for you:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('myController', function ($scope) {
$scope.getName = function () {
$scope.nameToSet = $scope.name;
$scope.lastNameToSet = $scope.lastName;
};
})
</script>
</head>
<body ng-app="myApp" >
<div >
<input type="text" ng-model="name"/> <br>
<input type="text" ng-model="lastName" />
</div>
<div ng-controller="myController">
<input type="button" value="click" ng-click="getName()" />
<br>
Hello FirstName {{nameToSet}}<br>
Last Name {{lastNameToSet}}
</div>
</body>
</html>
UPDATE: Here is another version with using a factory:
var myApp = angular.module('myApp', []);
myApp.factory('container', function() {
var model = {
name: '',
lastName: ''
};
return {
model: model,
setName: function(nameToSet) {
model.name = nameToSet;
},
setLastName: function(lastNameToSet) {
model.lastName = lastNameToSet;
}
};
});
myApp.controller('myController', function ($scope, container) {
$scope.$watch('name', function(newvalue,oldvalue) {
container.setName(newvalue);
});
$scope.$watch('lastName', function(newvalue,oldvalue) {
container.setLastName(newvalue);
});
$scope.onNameType = function(value) {
container.setName(value);
};
$scope.onLastNameType = function(value) {
container.setLastName(value);
};
$scope.getName = function () {
debugger;
$scope.nameToSet = container.model.name;
$scope.lastNameToSet = container.model.lastName;
};
})
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
</head>
<body ng-app="myApp" >
<div >
<input type="text" ng-model="name" ng-change="onNameType(name)"/> <br>
<input type="text" ng-model="lastName" ng-change="onLastNameType(lastName)" />
</div>
<div ng-controller="myController">
<input type="button" value="click" ng-click="getName()" />
<br>
Hello FirstName {{nameToSet}}<br>
Last Name {{lastNameToSet}}
</div>
</body>
</html>

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>

Angularjs watch a object in a form doesn't work

Can you explain me why this simple code doesn't work
I want see the change of user object in the controller.
<!doctype html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
</head>
<body>
<div data-ng-controller="MainCtrl">
<h1>User Info</h1>
<form novalidate id="my-frm" name="myFrm">
<label>Last name</label>
<input type="text" ng-model="user.lastName">
<label>First name</label>
<input type="text" ng-model="user.firstName">
<p ng-click="add()">add</p>
</form>
</div>
<script src="http://code.angularjs.org/1.0.8/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('MainCtrl',function($scope,$log){
$scope.user = {};
$scope.add = function(){
$log.info($scope.user);
};
$scope.$watch(
function(){
return $scope.user;
},
function(n,o){
$log.info(n);
$log.info(o);
}
);
});
</script>
</body>
</html>
Try this:
$scope.$watch("user", function(n, o) {
...
}, true);
Hopefully it is usable in Angular 1.0.8.
What this does is to instruct Angular to do a "deep watch" to your object. Also, since the user is in the $scope, you can specify the dependency using just a string. This is optional, you can still use the function instead of "user" as the first argument to $watch.

Resources