I am implementing a functionality in AngularJS.
When the user enters 1.5, In view, it should show as 01:30, but when I fetch this scope value in the controller it should return as 1.5.
I have added code in plunker. Please find here.
Index.html:
<!DOCTYPE html>
<html ng-app="wbTimeConverter">
<head>
<link rel="stylesheet" href="style.css">
<script src="https://code.angularjs.org/1.5.8/angular.js"></script>
<script src="script.js"></script>
<script src="wbNumberToTime.js"></script>
</head>
<body ng-controller="AppController">
<h1>Hello Plunker!</h1>
<input type="text" md-maxlength="5" wb-number-to-time-convert ng-model="task" placeholder="task" ng-blur="onDataChange();" />
<input type="text" md-maxlength="5" wb-number-to-time-convert ng-model="project" placeholder="project" ng-blur="onDataChange();" />
<br>
<label>Task : {{task}}</label><br>
<label>Project : {{project}}</label><br>
<label>TotalResult : {{totalHours}}</label>
</body>
</html>
Controller - Script.js
var app = angular.module('wbTimeConverter', []);
app.controller('AppController', function($scope) {
$scope.onDataChange = onDataChange;
function onDataChange(){
console.log("res");
$scope.totalHours= parseFloat($scope.task) + parseFloat($scope.project, 10);
}
});
directive:
// 'use strict';
// /**
// * This directive is convert number into hours and minutes format-HH:MM
// * This will trigger when we change value in input element and gives respective value in time format
// */
app.directive('wbNumberToTimeConvert', function ($filter, $browser) {
return {
require: 'ngModel',
link: function ($scope, $element, $attrs, ngModelCtrl) {
var listener = function () {
var value = $element.val();
var result = convertToTime(value);
$element.val(result.timeFormat);
$element.attr('attr-hrs', result.decimalFormat);
};
// This runs when we update the text field
ngModelCtrl.$parsers.push(function (viewValue) {
return viewValue;
});
$element.bind('change', listener);
$element.bind('keydown', function (event) {
var key = event.keyCode;
// FIXME to handle validations
});
$element.bind('paste cut', function () {
$browser.defer(listener);
});
function convertToTime(value) {
var res = { 'timeFormat': '', 'decimalFormat': '' };
var inputValue = value;
if (inputValue.indexOf(':') > -1) {
inputValue = convertToNumberFormat(inputValue);
res.decimalFormat = inputValue;
} else {
res.decimalFormat = value;
}
inputValue = inputValue.split('.');
var hoursValue = inputValue[0];
if (inputValue.length > 1) {
var hrs = parseInt(hoursValue, 10);
hrs = isNaN(hoursValue) ? 0 : hrs;
hrs = (hrs < 10) ? '0' + hrs : hrs;
var minutesValue = inputValue[1];
var mins = parseInt(minutesValue, 10);
mins = (minutesValue.length < 2 && (mins < 10)) ? Math.round(mins * 6) : Math.round(mins * 0.6);
mins = (mins < 10) ? ('0' + mins) : mins;
inputValue = hrs + ':' + mins;
res.timeFormat = inputValue;
} else {
inputValue = (parseInt(inputValue, 10) < 10) ? '0' + parseInt(inputValue, 10) : parseInt(inputValue, 10);
inputValue = inputValue + ':' + '00';
res.timeFormat = inputValue;
}
return res;
}
function convertToNumberFormat(inputValue) {
var timeValue = inputValue.split(':');
var hours = parseInt(timeValue[0], 10);
var mins = parseInt(timeValue[1], 10);
if (isNaN(hours)){
hours = '00';
}
if (isNaN(mins)) {
mins = '00';
}
mins = Math.round(mins / 0.6);
if (mins < 10) {
mins = '0' + mins;
}
var number = hours + '.' + mins;
return number;
}
}
};
});
Here is the plunker link:
https://plnkr.co/edit/76lwlnQlGC0wfjixicCK?p=preview
On textbox blur, it is working fine of value differ in View and Controller on first time and from second time on blur in textbox, it is showing same value 01:30 in both view and controller. How can I resolve it?
You can keep your input inside the ng-model myValue and call a function format(value) to display what you need
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.myValue = "1.5";
$scope.format = function(value) {
var hrs = parseInt(Number(value));
var min = Math.round((Number(value) - hrs) * 60);
return hrs + ':' + min;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<input type="text" ng-model="myValue">
<br>Formatted Value : {{format(myValue)}}
<br>Base value : {{myValue}}
</div>
It's really easy using a directive! Take this as an example: JSFiddle
If you have a directive that requires ngModelController you can manipulate the viewValue really easily.
ngModelController has two properties that we're interested in, $modelValue and $viewValue. $modelValue is the value that you use on the scope and $viewValue is the one the user sees.
ngModelController also has a property $formatters which is an array of formatters that convert a modelValue to viewValue. So if the modelValue changes on the side of the controller it will go through the formatters until the end, and this will change the viewValue. If you want to create your own formatter, simply add it the array!
//This formatter will convert the modelValue to display as uppercase in the viewValue
ngModelController.$formatters.push(function(modelValue) {
if (modelValue) {
return modelValue.toUpperCase();
}
});
but the $formatters property only works for when the modelValue gets changed, so if the user is typing something into the input field, the viewValue is getting changed, the easiest way to handle this is to attach to the onBlur event in which we will alter the viewValue using another function provided by the ngModel controller. $setViewValue(value) will change the viewValue. If you change the viewValue in the directive, the view won't automatically update, so you need to call the $render function provided by the ngModelController
element.on('blur', function() {
ngModelController.$setViewValue(convertDoubleToTimeString(ngModelController.$modelValue));
ngModelController.$render();
});
For more information about this you can read this.
EDIT:
In this example I haven't written a parser that converts a viewValue (1:30) to a modelValue (1,5). So let's add one. I also have an updated JSFiddle
ngModelController.$parsers.unshift(function(viewValue) {
if (viewValue && viewValue.indexOf(':') < 0) {
return viewValue;
} else {
return convertTimeStringToDouble(viewValue)
}
});
Unshifting the parsers onto the $parsers array means it will be the first one to execute, this isn't really necessary, but why not, eh?
There are other ways of not changing the modelValue when the viewValue changes, but this one is the most correct one.
An alternative would be to just set the $viewValue directly without going through $setViewValue().
//ngModelController.$setViewValue(ngModelController.$modelValue.toUpperCase());
ngModelController.$viewValue = ngModelController.$modelValue.toUpperCase();
In that last line, it wont go through the usual steps of going through all the parsers and validators, so it's the less ideal solution.
You can declare a function in controller to return the calucalted value and in html you can call that function and pass the scope variable.
$scope.calculate = function(value){
var calculatedValue = /*Your operation*/;
return calculatedValue;
}
<input type="text" ng-model="value"\>
<p>{{calculate(value)}}</p>
If you want real time update of the calculated value with respect to the input value then you can use another scope variable to store the calculate value.
$scope.calculate = function(value){
$scope.calculatedValue = /*Your operation*/;
}
<input type="text" ng-model="value" ng-change="calculate(value)"\>
<p>{{calculatedValue}}</p>
Related
I have an input field of type text and bound to a property in a scope.
<input type=text= ng-model="vm.someProperty">
If someProperty has a value of 4.32, I want the input to display 4.32%. I don't want someProperty to equal 4.32%. The value stays the same. Only the display changes. When the page renders, the % character shows up after the value. When the user is changing the input value, only the number shows and when the input loses focus, the % shows again.
I know this can be done using a directive but I am not sure how. I am not proficient in AngularJS.
Use this
angular
.module("docsSimpleDirective", [])
.controller("Controller", [
"$scope",
function($scope) {
$scope.text = '';
}
])
.directive("percent", function() {
return {
restrict: "A",
transclude: true,
scope: {},
link: function(scope, element, attr) {
element.on("focusout", function() {
var str = element.val();
element.val(str + "%");
});
element.on("focus", function() {
var str = element.val();
element.val(str.substring(0, str.length - 1));
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="docsSimpleDirective">
<input type "text" id="someProperty" percent ng-model="text"> {{text}}
</div>
vm.percentSymbol = function (type) {
vm.someProperty = vm.replace(/\%/g, '') + '%';
};
<input type=text= ng-model="vm.someProperty" ng-blur = "vm.percentSymbol()">
In your html
<input ng-focus="onFocus(someProperty)" ng-blur="onBlur(someProperty)" ng-model="someProperty" />
in your controller
$scope.someProperty= '';
$scope.onFocus = function(someProperty) {
$scope.someProperty = (someProperty.length >0)? someProperty.split("%")[0] : '';
}
$scope.onBlur = function(someProperty) {
$scope.someProperty = (someProperty.length >0)? someProperty+'%' : '';
}
This working fine.. Hope this will help.
I previously write this [question][1], Inow I have the problem that the model.$viewValue it's not the same of the value the i see in the input box.
<div amount-input-currency="" ng-model="data.amount" ></div>
This is my directive (isNumeric and similar is not important that works weel):
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.data = { amount: ''};
});
app.directive('amountInputCurrency', function () {
return {
restrict: 'EA',
require: 'ngModel',
templateUrl: 'inputCurrency.tmpl.html',
scope: {
model: '=ngModel',
},
link: function (scope, elem, attrs, ngModelCtrl) {
scope.model2 = ngModelCtrl;
console.log("I am in the directive!");
var myAmountCurrencyType = elem.find('.cb-amount-input-currency');
scope.onFocus = function() {
removeThousandSeparator();
};
scope.onBlur = function() {
renderValue();
ngModelCtrl.$render();
};
//format text going to user (model to view)
ngModelCtrl.$formatters.push(function(value) {
return parseValue(value);
});
//format text from the user (view to model)
ngModelCtrl.$parsers.push(function(value) {
var num = Number(value);
if(isNumeric(num)) {
var decimal = 2;
return formatAmount();
} else {
return value;
}
});
function isNumeric(val) {
return Number(parseFloat(val))==val;
}
}
}
});
And this is my template:
scope.model: {{model}}<br>
viewValue: {{model2.$viewValue}}<br>
modelValue: {{model2.$modelValue}}<br>
<input type="text" class="amount-input-currency form-control" x-ng-model="model" ng-focus="onFocus()" ng-blur="onBlur()"></input>
Set the viewValue using ngModelCtrl.$setViewValue() in order to update the model instead of setting $viewValue field directly. But I am not sure what is the point of using NgModelController in this case at all.
If the only purpose is to format the value of the textbox, manipulate the input element value instead of NgModelController fields.
function renderValue() {
var myAmountCurrencyType = elem.find('input');
var value = myAmountCurrencyType.val();
var decimal = 2;
if (value != undefined && value !="") {
myAmountCurrencyType.val(formatAmount());
}
}
This way it does not update the model. If you want to have full control over the data binding you can consider removing the binding from the input element x-ng-model="model" and implementing it using NgModelController in your directive.
If you can do what you need to do without formatters and parsers it's better because that you work more in the angular way, and if you can avoid requiring ng-model in directives if you can manage without it because that cause a lot of mess too.
As for your problem I will show a solution that does not need the formatters and parsers and I hope that this what you wanted, if you must use the formatters and parsers you can, but it will essentially do the same as the following solution:
index.html:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="http://code.angularjs.org/1.2.15/angular.js" data-semver="1.2.15"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<!--<div amount-input-currency="" ng-model="data.amount" ></div>-->
<amount-input-currency model="data.amount"></amount-input-currency>
</body>
</html>
amountInputCurrency.tmpl.html:
scope.model: {{model}}<br>
viewValue: {{model2.$viewValue}}<br>
modelValue: {{model2.$modelValue}}<br>
<input type="text" class="cb-amount-input-currency form-control" ng-model="model" ng-focus="onFocus()" ng-blur="onBlur()">
app.js:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.data = { amount: ''};
});
app.directive('amountInputCurrency', function () {
var isAllowedKey = function (k, v) {
return (
k === 8 || k === 9 || k === 46 ||
(k > 47 && k < 58) ||
(k > 95 && k < 106) ||
(k > 36 && k < 41) ||
(k === 188 && (!v || v.search(/(\.|\,)/)<0)) ||
((k === 190 || k === 110) && (!v || v.search(/(\.|\,)/)<0))
);
};
return {
restrict: 'E',
// require: 'ngModel',
templateUrl: 'amountInputCurrency.tmpl.html',
scope: {
model: '=',
},
link: function (scope, elem, attrs) {
// scope.model2 = ngModelCtrl;
console.log("I am in the directive!");
var myAmountCurrencyType = elem.find('.cb-amount-input-currency');
myAmountCurrencyType.on('keydown', function (e) {
//if (!isAllowedKey(e.which, scope.model)) {
if (!isAllowedKey(e.which, scope.model)) {
e.preventDefault();
}
});
scope.onFocus = function() {
removeThousandSeparator();
};
scope.onBlur = function() {
renderValue();
// ngModelCtrl.$render();
// scope.model = ngModelCtrl.$viewValue;
};
// //format text going to user (model to view)
// ngModelCtrl.$formatters.push(function(value) {
// return parseValue(value);
// });
// //format text from the user (view to model)
// ngModelCtrl.$parsers.push(function(value) {
// var num = Number(value);
// if(isNumeric(num)) {
// var decimal = 2;
// return formatAmount(Number(num).toFixed(decimal), decimal, ',', '.');
// } else {
// return value;
// }
// });
function isNumeric(val) {
return Number(parseFloat(val))==val;
}
function renderValue() {
var value = String(scope.model || '');
var decimal = attrs.cbAmountDecimal || 2;
if (value != undefined && value !="") {
scope.model = formatAmount(value, decimal, ',', '.');
// ngModelCtrl.$render();
}
}
function formatAmount(amount, c, d, t) {
if (amount.indexOf(',') !== -1) {
if (amount.indexOf('.') !== -1) {
amount = amount.replace(/\./g,''); //remove thousand separator
}
amount = amount.replace(/\,/g,'.');
}
c = isNaN(c = Math.abs(c)) ? 2 : c;
d = d === undefined ? "." : d;
t = t === undefined ? "," : t;
var n = amount,
s = n < 0 ? "-" : "",
i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
j = (j = i.length) > 3 ? j % 3 : 0;
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
}
function removeThousandSeparator() {
if(scope.model != undefined && scope.model !="") {
scope.model = scope.model.replace(/\./g,'');
// ngModelCtrl.$render();
// scope.model = ngModelCtrl.$viewValue;
}
}
function parseValue(viewValue) {
var num = 0;
if(isNumeric(viewValue)) {
num = viewValue;
} else {
num = viewValue ? viewValue.replace(/,/g,'.') : viewValue;
}
return num;
}
}
}
});
If this is not what you want then I'm truly sorry and please comment what is the problem in my solution for and I will try my best to see if I can help.
Checkout Formatters and Parser, it's how to do what you want, but you have to require ngModel to hook append formatter or parser.
A good article about them : https://alexperry.io/angularjs/2014/12/10/parsers-and-formatters-angular.html
Regards.
I need to display star rating dynamically based on response.
I am able to display values from 1 to 5 but if rating is 0 then no empty stars are displaying.
If rating = 0.4 also it's showing 1 star filled.
My controller:
(function() {
'use strict';
angular
var app = angular
.module('app')
app.directive('starRating', function () {
return {
restrict: 'A',
template: '<ul class="rating">' +
'<li ng-repeat="star in stars" ng-class="star" ng-click="toggle($index)">' +
'\u2605' +
'</li>' +
'</ul>',
scope: {
ratingValue: '=',
max: '='
},
link: function (scope, elem, attrs) {
var updateStars = function () {
scope.stars = [];
for (var i = 0; i < scope.max; i++) {
if(i == 0) {
scope.stars = [];
scope.stars.push({
empty: i = 0
});
} else {
scope.stars.push({
filled: i < scope.ratingValue
});
}
}
};
scope.$watch('ratingValue', function (oldVal, newVal) {
if (newVal) {
updateStars();
}
});
}
}
});
app.controller('Controller', Controller);
Controller.$inject = ['UserService', '$location', '$rootScope', '$scope', 'fileUpload', 'FlashService', '$cookieStore', '$timeout', '$window'];
function Controller(UserService, $location, $rootScope, $scope, fileUpload, FlashService, $cookieStore, $timeout, $window) {
$scope.selectTestSubject = function() {
$scope.rating = 0;
console.log(levels.length);
for(var k=0; k<levels.length; k++) {
var respRating = levels[k].rating;
// var respRating = 1.5;
console.log(respRating);
$scope.ratings = [{
current: respRating,
max: 5
}];
if(respRating == 0) {
$scope.defaultRating = true;
} else {
$scope.defaultRating = false;
}
}
}
}
}) ();
My HTML page:
<div><span ng-repeat="rating in ratings">
<div star-rating rating-value="rating.current" max="rating.max"></div>
</span>
</div>
One problem with your solution is your $watch expression. Where you have the following:
scope.$watch('ratingValue', function (oldVal, newVal) {
if (newVal) {
updateStars();
}
});
oldVal and newVal are actually the wrong way around, the $watch function first takes in the new value followed by the old value. Secondly, the condition if (newVal) doesn't work for 0, because 0 is a falsey value.
Instead, you should have:
scope.$watch('ratingValue', function(value, previousValue) {
// Only update the view when the value has changed.
if (value !== previousValue) {
updateStars();
}
});
Your updateStars function also always reinitialises the scope.stars variable and appends onto it. Doing this can have some unwanted side effects and results in the view not reflecting the model value. It's best to initialise the array, then append the item if it doesn't yet exist or update the existing value. So you'll have something like this:
// Initialise the stars array.
scope.stars = [];
var updateStars = function() {
for (var i = 0; i < scope.max; i++) {
var filled = i < Math.round(scope.ratingValue);
// Check if the item in the stars array exists and
// append it, otherwise update it.
if (scope.stars[i] === undefined) {
scope.stars.push({
filled: filled
});
} else {
scope.stars[i].filled = filled;
}
}
};
Since the $watch expression only updates the stars when the value has changed, you'll now need to trigger the update the first time your link function fires. So this is simply:
// Trigger an update immediately.
updateStars();
Your template also does not correctly utilise the filled property on the star, it should instead contain the appropriate ng-class like so:
<ul class="rating">
<li class="star"
ng-repeat="star in stars"
ng-class="{ filled: star.filled }"
ng-click="toggle($index)">
\u2605
</li>
</ul>
With a simple style,
.star {
cursor: pointer;
color: black;
}
.star.filled {
color: yellow;
}
You can also improve this rating system by listening to mouseenter and mouseleave effects, so that the stars appear yellow when the user is selecting a new value. This is pretty common functionality. You can achieve this by making a few modifications.
To begin with, the template should be updated to listen for these events:
<ul class="rating">
<li class="star"
ng-repeat="star in stars"
ng-class="{ filled: star.filled }"
ng-mouseenter="onMouseEnter($event, $index + 1)"
ng-mouseleave="onMouseLeave($event)"
ng-click="toggle($index)">
\u2605
</li>
</ul>
Next, we want to make a small adjustment to the updateStars function to take in a rating parameter:
var updateStars = function(rating /* instead of blank */ ) {
for (var i = 0; i < scope.max; i++) {
var filled = i < Math.round(rating); // instead of scope.ratingValue
// Check if the item in the stars array exists and
// append it, otherwise update it.
if (scope.stars[i] === undefined) {
scope.stars.push({
filled: filled
});
} else {
scope.stars[i].filled = filled;
}
}
};
// Trigger an update immediately.
updateStars(scope.ratingValue /* instead of blank */ );
scope.$watch('ratingValue', function(value, previousValue) {
// Only update the view when the value changed.
if (value !== previousValue) {
updateStars(scope.ratingValue /* instead of blank */ );
}
});
Now we can add in our event callbacks from the view,
// Triggered when the cursor enters a star rating (li element).
scope.onMouseEnter = function (event, rating) {
updateStars(rating);
};
// Triggered when the cursor leaves a star rating.
scope.onMouseLeave = function (event) {
updateStars(scope.ratingValue);
};
And that's it! Full demo here.
$scope.total < ng-min, $scope.total is undefined.
But i need to get that value to shown as change.
for example : if change -50, then cashier can easy to talk to customer if he need 50 more.
angular.module('app', [])
.controller('MainCtrl', function($scope) {
$scope.pay = null;
$scope.total = 1000;
$scope.change = 0;
$scope.check = function() {
$scope.change = $scope.pay - $scope.total;
console.log('pay = ' + $scope.pay + ' , total = ' + $scope.total + ' , change = ' + $scope.change);
};
});
<body ng-app="app" ng-controller="MainCtrl">
Total = {{ total }}
<input type="number" ng-model="pay" ng-min="total" ng-change="check()">
Change = {{ change }}
</body>
here my plunkr http://plnkr.co/edit/4C9AuBI4q97VXXvXM59B?p=preview
You don't need to use ng-min at all, because of this directive will pass only correct values, just add a condition to change-function. E.g
if($scope.change < 0){
//do something
}
Also, better to change $scope.pay = null; to $scope.pay = 0; if You want to avoid the type-errors
I have a value which i get from a controller and two input box.
I need that whenever i enter any value in one input box. difference of the value retrieved from controller and input box get displayed in the other input box using angularJs.
e.g:-
{{sum}} --> is the value which I get from controller.
<input type="number" ng-model="firstnumber" />
<input type="number" ng-model="secondnumber"/>
What I tried was making service for setting and getting the sum value and watch to change the value every time a value is changed.
My service is :-
angular.module('myapp').service("cmModalService", function($scope){
var sum= ={};
getSum = function(){
return sum;
}
setSum = function(value){
sum=value;
};
});
In a controller I have defined
$scope.$watch('firstnumber', function(newValue, oldValue) {
var sum=cmModalService.getSum();
if(newValue!=null)
{ secondnumber = sum -firstnumber;
}
});
$scope.$watch('secondnumber', function(newValue, oldValue) {
var sum=cmModalService.getSum();
if(newValue!=null)
{ firstnumber = sum -secondnumber;
}
});
But whenever i change values in input box the flow never goes to watch method, and the values doesn't change.
Is there any other method also to achieve this.?
I have tried using ng-change also but still not able to get the exact result.
And inside controller i have defined the change methods as
$scope.changefirstnumber=function(firstnumber, sum){
$scope.secondnumber = sum- firstnumber;
};
$scope.changesecondnumber=function(secondnumber, sum){
$scope.firstnumber= sum- secondnumber;
};
and in html
[Plunker link]
You are not setting the scoped variable. Try this.
$scope.$watch('firstnumber', function(newValue, oldValue) {
var sum=cmModalService.getSum();
if(newValue!=null)
{ $scope.secondnumber = sum -$scope.firstnumber;
}
});
$scope.$watch('secondnumber', function(newValue, oldValue) {
var sum=cmModalService.getSum();
if(newValue!=null)
{ $scope.firstnumber = sum - $scope.secondnumber;
}
});
Working Plunkr
EDIT
With some new information you provided, is this what you're after? http://jsfiddle.net/37gv1kbe/
var app = angular.module('myApp',[]);
app.controller('MyController', function($scope,cmModalService)
{
$scope.firstnumber = 5;
$scope.secondnumber = 10;
$scope.$watch('firstnumber', function()
{
$scope.total = cmModalService.getSum() - $scope.firstnumber
});
$scope.$watch('secondnumber', function()
{
$scope.total = cmModalService.getSum() - $scope.secondnumber;
});
});
app.controller('MySecondController', function($scope,cmModalService)
{
$scope.rand = Math.round(Math.random() * 100);
cmModalService.setSum($scope.rand);
});
app.service('cmModalService', function()
{
var sum;
return {
getSum: function()
{
return sum;
},
setSum: function(value)
{
sum = value;
}
}
});
ORIGINAL ANSWER
regarding my comment, if you need to access the total in your controller, you can just save the val of firstnumber and secondnumber like so
http://jsfiddle.net/pvqm4tcw/
var app = angular.module('myApp',[]);
app.controller('MyController', function($scope)
{
$scope.firstnumber = 5;
$scope.secondnumber = 10;
$scope.$watch('firstnumber', function()
{
$scope.total = $scope.firstnumber + $scope.secondnumber;
});
$scope.$watch('secondnumber', function()
{
$scope.total = $scope.firstnumber + $scope.secondnumber;
});
});
html:
<body ng-app="myApp">
<div ng-controller="MyController">
<input type="number" ng-model="firstnumber" />
<br>
<input type="number" ng-model="secondnumber"/>
<br>
{{total}}
</div>
</body>
If you're using Angular 1.3+ they have a $watchGroup which can make the code even smaller
var app = angular.module('myApp',[]);
app.controller('MyController', function($scope)
{
$scope.firstnumber = 5;
$scope.secondnumber = 10;
$scope.$watchGroup(['firstnumber','secondnumber'], function()
{
$scope.total = $scope.firstnumber + $scope.secondnumber;
});
});