Addition of two numbers in angularJS onclick - javascript

I am trying to add two numbers and want to display its result only when I click a button. Here is my code below:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<h2>Calculator</h2>
a: <input type="number" ng-model="a">
b: <input type="number" ng-model="b">
<button ng-click="addFunc()">Sum</button>
Sum : {{sum}}
<!-- <p><b>Summation:</b> {{sum = a + b}}</p> -->
<br/><br/><br/>
c: <input type="number" ng-model="c">
d: <input type="number" ng-model="d">
<p><b>Subtraction:</b> {{c - d}}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.sum = 0;
$scope.addFunc = function() {
$scope.sum=a+b;
}
});
</script>
</body>
</html>

If you try to access a and b from this function, it will look into the lexical scope of this function. Since you don't have the variables declared over there it won't work. You neither have the variables declared anywhere up in the scope chain as its inside the custom $scope(just a javascript Object) maintained by angular. Angular uses its own $scope which is injected into the controller, to access that scope you have to access via $scope. itself. The idea is to share this between template(view) and function(controller)
$scope.addFunc = function() {
$scope.sum=a+b;
}
In your template a + b works because angular uses $scope internally for all variables used in your template, so you don't have to add $scope over there.
<p><b>Summation:</b> {{sum = a + b}}</p>
In your case you can use $scope like:
$scope.addFunc = function() {
$scope.sum= $scope.a + $scope.b;
}
or use this as the function is called with $scope and will have implicit reference.
$scope.addFunc = function() {
this.sum= this.a + this.b; //when calling $scope.addFunc() this will be $scope
}
or use with statement (although not recommended due to some edge cases)
$scope.addFunc = function() {
with($scope) sum = a + b;
}

The moment you wrote a & b as ng-model, They are automatically connected to $scope object.
So if you want to add them, you simply have to write
$scope.a + $scope.b

Try this code
Calculator
a: <input type="number" ng-model="a">
b: <input type="number" ng-model="b">
<button ng-click="addFunc()">Sum</button>
Sum : {{sum}}
<!-- <p><b>Summation:</b> {{sum = a + b}}</p> -->
<br/><br/><br/>
c: <input type="number" ng-model="c">
d: <input type="number" ng-model="d">
<p><b>Subtraction:</b> {{c - d}}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.sum = 0;
$scope.addFunc = function() {
$scope.sum=$scope.a+$scope.b;
}
});
</script>
</body>
</html>

a and b are in $scope:
$scope.addFunc = function() {
$scope.sum = $scope.a + $scope.b;
}

Pass the values to controller
<button ng-click="addFunc(a, b)">Sum</button>
controler
$scope.addFunc = function(a, b) {
$scope.sum=a+b;
}
OR
HTML:
<button ng-click="addFunc()">Sum</button>
Controller:
$scope.addFunc = function() {
$scope.sum=$scope.a+$scope.b;
}

Here is solution
jsfiddle
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.sum = 0;
$scope.addFunc = function() {
$scope.sum=$scope.a+$scope.b;
}

Try this code: We need to type cast our variable i.e., ng-model value to number else it will return string.
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body ng-app="MyApp" ng-controller="myctrl">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"> </script>
<script>
var app=angular.module("MyApp",[]);
app.controller("myctrl",function($scope){
$scope.value=0;
$scope.add=function(){
$scope.value=Number($scope.fnum)+ Number($scope.snum);
};
});
</script>
firstname:<input type="text" ng-model="fnum" placeholder="Enter value" /><br>
lastname:<input type="text" ng-model="snum" placeholder="Enter value" /><br>
<input type="button" value="Click" ng-click="add() " /><br>
<div ng-repeat="a in res()">{{a}}</div>
<div>{{value}}</div>
</body>
</html>

Related

How to pass data from input to a custom service?

I am new to AngularJS and I have a problem: how to display the hex equivalent of the number inserted into the input box?
I am using ng-change to see if the input is modified and the output should also change according to the input.
This is the code:
<div ng-app="myApp" ng-controller="myCtrl">
<input type="number" ng-model="in" ng-change="hex(in)">
{{in}} <br>{{hex}}
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
<script>
var app = angular.module('myApp', []);
app.service('hexafy', function() {
this.myFunc = function (x) {
return x.toString(16);
}
});
app.controller('myCtrl', function($scope, hexafy) {
$scope.in= 11;
$scope.hex = hexafy.myFunc($scope.in);
});
</script>
Why it does not work?
In your input, you try to call a function:
<input type="number" ng-model="in" ng-change="hex(in)">
But $scope.hex is not a function in your controller:
$scope.hex = hexafy.myFunc($scope.in);
How to fix it?
Change it to:
$scope.hex = function() {
$scope.result = hexafy.myFunc($scope.in);
}
var app = angular.module('myApp', []);
app.service('hexafy', function() {
this.myFunc = function (x) {
return x.toString(16);
}
});
app.controller('myCtrl', function($scope, hexafy) {
$scope.in= 11;
$scope.hex = function() {
$scope.result = hexafy.myFunc($scope.in);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<input type="number" ng-model="in" ng-change="hex()">
{{in}} <br>{{result}}
</div>
Created Plunker. Problem is that you are using function name as assignment.
<input type="number" ng-model="in" ng-change="convertToHex(in)">
$scope.convertToHex= function(value) {
$scope.hex = hexafy.myFunc(value);
}

How to bind a value from one ng-model to an other by matching a specific string

I got a requirement to bind a value to a particular model when the value in the other model contains a string starting with "https".
For example, I have two text fields both fields having different model
<input type="text" ng-model="modelText1">
<input type="text" ng-model="modelText2">
Suppose I type a value on the first text field "https", the first input model modelText1 have to bind to the second input model modelText2 and later on i have to maintain it as like two-way binding. i.e. the second field will automatically get the value dynamically when it contains "https" at starting of a string.
Try it like in this Demo fiddle.
View
<div ng-controller="MyCtrl">
<input type="text" ng-model="modelText1">
<input type="text" ng-model="modelText2">
</div>
AngularJS Application
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope) {
$scope.modelText1 = '';
$scope.modelText2 = '';
var regEx = new RegExp(/^https/);
$scope.$watch('modelText1', function (newValue) {
if (newValue.toLowerCase().match(regEx)) {
$scope.modelText2 = newValue;
} else {
$scope.modelText2 = '';
}
});
});
An other approach is (that avoid using of $watch) is to use AngularJS ng-change like in this
example fiddle.
View
<div ng-controller="MyCtrl">
<input type="text" ng-model="modelText1" ng-change="change()">
<input type="text" ng-model="modelText2">
</div>
AngularJS Application
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope) {
$scope.modelText1 = '';
$scope.modelText2 = '';
var regEx = new RegExp(/^https/);
$scope.change = function () {
if ($scope.modelText1.toLowerCase().match(regEx)) {
$scope.modelText2 = $scope.modelText1;
} else {
$scope.modelText2 = '';
}
};
});
You can use the ng-change directive like this:
<input type="text" ng-model="modelText1" ng-change="onChange()">
<input type="text" ng-model="modelText2">
and your controller:
$scope.onChange = function() {
if ($scope.modelText1 === 'https') {
$scope.modelText2 = $scope.modelText1;
else
$scope.modelText2 = '';
};
use ng-change to check the text is equal to 'https'
angular.module('app',[])
.controller('ctrl',function($scope){
$scope.changeItem = function(item){
$scope.modelText2 = "";
if(item.toLowerCase() === "https"){
$scope.modelText2 = item
}
}
})
<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" ng-model="modelText1" ng-change="changeItem(modelText1)">
<input type="text" ng-model="modelText2">
</div>
EDiTED
to make sure it does't fail under 'HTTPS' use toLoweCase function to make all lower case
HTML :
<input type="text" ng-model="modelText1" ng-change="updateModal(modelText1)">
JS :
var modelText1 = $scope.modelText1.toLowerCase();
$scope.updateModal = function(){
$scope.modelText2 = '';
if(modelText1.indexOf('https')!=-1){
$scope.modelText2 = modelText1;
}
}
you could also possibly do this as a directive if you want to have a more reusable solution over multiple views http://jsfiddle.net/j5ga8vhk/7/
It also keeps the controller more clean, i always try to use the controller only for controlling complex business logic and business data
View
<div ng-controller="MyCtrl">
<input type="text" ng-model="modelText1" >
<input type="text" ng-model="modelText2" model-listener="modelText1" model-listener-value="https" >
</div>
Angular JS
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope) {
$scope.modelText1 = '';
$scope.modelText2 = '';
});
myApp.directive('modelListener', [function() {
return {
restrict: 'A',
controller: ['$scope', function($scope) {
}],
link: function($scope, iElement, iAttrs, ctrl) {
$scope.$watch(iAttrs.modelListener, function() {
if($scope[iAttrs.modelListener] === iAttrs.modelListenerValue ) {
$scope[iAttrs.ngModel] = $scope[iAttrs.modelListener];
} else {
$scope[iAttrs.ngModel] = "";
}
}, true);
}
};
}]);

accessing attribute directive values using controller as

I know how to do it Without controller as:
html
Let's assume I have a directive named ngUpperCase(either true or false)
<div ng-controller="myControl" >
<input type="text" ng-upper-case="isGiant" >
</div>
Js
myApp.directive('ngUpperCase',function(){
return{
restrict:'A',
priority:0,
link:function($scope,element,attr){
//---to retrieve value
var val = $scope[attr.ngUpperCase];
var anotherVal = $scope.$eval(attr.ngUpperCase);
$scope.$watch(attr.ngUpperCase,function(val){
//---to watch
})
}
};
})
How to make the directive if I'm using something like this?
<div ng-controller="myControl as ctl" >
<input type="text" ng-upper-case="ctl.isGiant" >
</div>
Since it's not very clear what you want to achieve, here is an example of doing what I understand you need: changing an input value to upper or lower case depending on a variable:
function ngUpperCase() {
return{
restrict:'A',
priority:0,
link:function($scope,element,attr){
//---to retrieve value
var val = $scope[attr.ngUpperCase];
var anotherVal = $scope.$eval(attr.ngUpperCase);
$scope.$watch(attr.ngUpperCase,function(val){
if(val) {
element[0].value = element[0].value.toUpperCase();
} else {
element[0].value = element[0].value.toLowerCase();
}
})
}
}
}
function myController() {
this.isGiant = true;
}
angular.module('myApp', []);
angular
.module('myApp')
.controller('myController', myController)
.directive('ngUpperCase', ngUpperCase);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myController as ctl" >
lower case<br>
upper case
<input type="text" ng-upper-case="ctl.isGiant" value="TeStiNg123" >
</div>
</div>

Setting data-ng-model in JavaScript

I need to set the data-ng-model attribute of an html input field via javascript.
I know I can't do
element.data-ng-model = "...";
because of the dashes. So I tried
element.["data-ng-model"] = "...";
and
element.dataNgModel = "...";
and
element.datangmodel = "...";
None of these seem to work properly.
Any suggestions?
Try:
element.setAttribute("ng-model", "...");
or if you have JQuery:
$(element).attr("ng-model", "...");
If you need to set the model with javascript you can set it in the controller see below From the angular docs
https://docs.angularjs.org/api/ng/directive/ngModel
(function(angular) {
'use strict';
angular.module('getterSetterExample', [])
.controller('ExampleController', ['$scope',
function($scope) {
var _name = 'Brian';
$scope.user = {
name: function(newName) {
// Note that newName can be undefined for two reasons:
// 1. Because it is called as a getter and thus called with no arguments
// 2. Because the property should actually be set to undefined. This happens e.g. if the
// input is invalid
return arguments.length ? (_name = newName) : _name;
}
};
}
]);
})(window.angular);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<div ng-app="getterSetterExample">
<div ng-controller="ExampleController">
<form name="userForm">
<label>Name:
<input type="text" name="userName" ng-model="user.name" ng-model-options="{ getterSetter: true }" />
</label>
</form>
<pre>user.name = <span ng-bind="user.name()"></span></pre>
</div>
</div>

Angular pass input value to $rootScope variable

I have situation where I want to use $rootScope variable and update its value with the one entered in input field. I have sitauation code shortened to this DEMO:
HTML:
<div ng-controller="MyCtrl">
<input type="text" ng-model="foo" placeholder="Enter something" />
<input type="button" ng-click="doSomething()" value="Send" ng-disabled="foo == null" />
</div>
SCRIPT:
var myApp = angular.module('myApp', []);
function MyCtrl($scope, $rootScope) {
$rootScope.foo = null;
$scope.doSomething = function () {
alert("Hello, " + $rootScope.foo);
}
}
Any suggestions on how to pass input value to $rootScope variable would be great!
Although not recommended, Still if you want you can do it the following way
<div ng-controller="MyCtrl">
<input type="text" ng-model="foo" placeholder="Enter something" ng-change="onFooChange()" />
<input type="button" ng-click="doSomething()" value="Send" ng-disabled="foo == null" />
</div>
Script
var myApp = angular.module('myApp', []);
function MyCtrl($scope, $rootScope) {
$rootScope.foo = null;
$scope.onFooChange = function(){
$rootScope.foo = angular.copy($scope.foo);
}
$scope.doSomething = function () {
alert("Hello, " + $rootScope.foo);
}
}
When the value of text field is changed onFooChange function is called and the value is stored into $rootScope.
Here is an approach without using ng-change:
function MyCtrl($scope, $rootScope) {
$scope.foo=null;
$scope.doSomething = function () {
$rootScope.foo=$scope.foo;
alert("Hello, " + $rootScope.foo);
}
}

Categories

Resources