I am trying to load json data on the form which has two text fields. TextFields display correct price and qty from json. But, the problem is when user updates the price and qty, updated price and qty are not reflecting in controller method - $scope.total(). Here is my code
HTML file
<div ng-repeat="row in myData">
<input type="text" ng-model="row.price">
<input type="text" ng-model="row.qty">
</div>
JS file
$http.get('http call’).success(function(data){
$scope. myData = data
})
$scope.row = {
price : 10.0,
qty : 2;
};
$scope.total = function() {
console.log($scope.row.price);
console.log($scope.row.qty);
}
JSON - [{"price":10.50,"qty":3}]
Not sure what I am missing here? why updated values are not reflecting in controller?
Your $scope.total function needs to be called somewhere, and as mentioned by #pankajparkar, $scope.row is different than the row in your directive (which belongs to the ng-repeat's scope only).
Do this:
<div ng-repeat="row in myData">
<input type="text" ng-model="row.price" ng-change="total()">
<input type="text" ng-model="row.qty" ng-change="total()">
</div>
JS:
$http.get('http call').success(function(data){
$scope.myData = data;
});
$scope.total = function() {
console.log($scope.myData[0].price * $scope.myData[0].qty);
};
As your data is an array you loop througt is to get the total of all your objects:
$scope.total = function() {
var sum = 0;
myData.forEach(function(obj){
sum += obj.qty * obj.price
});
return sum;
}
and you need to call this function when values change.
Fiddle
With only one element in your array, your function total should be like #Joao answer:
$scope.total = function() {
return $scope.myData[0].price * $scope.myData[0].qty;
};
Fiddle
First thing if response is only one item then it should not be an array
It should be Single JSON such as {"price":10.50,"qty":3}
HTML Code
<input type="text" ng-model="myData.price">
<input type="text" ng-model="myData.qty">
<button type="button" ng-click="updateTotal()">
JS CODE
$http.get('http call').success(function(data){
$scope.myData = data;
});
$scope.total = function(){
//now here you will get updated scope values
console.log($scope.myData.price * $scope.myData.qty);
}
Hope this will be help full to you.
$scope.total is a function, but it is not returning anything.
instead of:
var total = $scope.row.price * $scope.row.qty
try:
return $scope.row.price * $scope.row.qty
Related
i have input with default value 0 , but this value not getting
my js getting error undefined ,if i enter any value it is showing .
but i want to show default value
<tr ng-repeat="r in rvm" >
<td>
<input type="text" lass="input-large" ng-value="2.00" ng-model="rvm.val1" name="val1" />
</td>
<td>
<button type="button" class="btn btn-default" ng-click="addRow1()">Add</button>
</td>
</tr>
JS
var ReceiptsApp = angular.module('ReceiptsApp', []);
ReceiptsApp.controller('ReceiptsController', function ($scope) {
$scope.rvm = [{}];
$scope.addRow1 = function ( ) {
alert($scope.rvm.val1);
}
});
js bin link here
enter link description here
You can either set it inside your controller
ReceiptsApp.controller('ReceiptsController', function ($scope) {
$scope.rvm.val1 = '0.00';
});
or using ng-init
<input type="text" lass="input-large" ng-init="rvm.val1='0.00'" ng-model="rvm.val1" name="val1" />
Just set a default value in the controller:
ReceiptsApp.controller('ReceiptsController', function ($scope) {
$scope.rvm.val1 = 'your default value';
});
If you read this link about ngValue you will see that it's not supposed to be used with a normal input (when you've also set ng-model on it), but rather for radio inputs and option elements. Your best solution is setting the value in the controller, as you should do.
It can also be used to achieve one-way binding of a given expression to an input element such as an input[text] or a textarea, when that element does not use ngModel.
<input type="text" lass="input-large" ng-value="2.00" ng-model="rvm.val1" name="val1" />
Problem is you are using rvm.val1 where rvm is array not an object in array
Change ng-model="rvm.val1" to ng-model="r.val1"
then you will be able to keep track of each value individually.
Inorder to initialize a value
<tr ng-repeat="r in rvm" ng-init="r.val1= 2.00">
Then in
$scope.addRow1 = function (index) {
// access individual object in rvm..
alert($scope.rvm[index].val1);
// push a new object
$scope.rvm.push({});
}
JSBin
If you don't want to use ng-init
You can do this
Each time you push a new item initialize the val1
$scope.rvm.push({val1: 2.00});
JsBin
var ReceiptsApp = angular.module('ReceiptsApp', []);
ReceiptsApp.controller('ReceiptsController', function ($scope) {
$scope.rvm = [{}];
$scope.rvm.val1=0;
$scope.addRow1 = function ( ) {
if($scope.rvm.val1 == ''){
$scope.rvm.val1=0;
alert($scope.rvm.val1);
} else {
alert($scope.rvm.val1);
}
}
});
Hi i have took a if condition where i am checking if input field is blank then it will initialise $scope.rvm.val1=0; and showing in alert.
it will work
This is my code
function Ctrl($scope) {
$scope.data = [];
$scope.data = [{
"label": "name",
"type": "string"
}, {
"label": "email",
"type": "string"
}];
$scope.addFields = function() {
var count = 0;
angular.forEach($scope.data, function(obj) {
if (count == 2) {
return true;
}
$scope.data.push(obj);
count = count + 1;
});
};
$scope.save = function() {
console.log($scope.data);
};
}
<div ng-app>
<div ng-controller="Ctrl">
<input type="button" value="add" ng-click="addFields()" />
<div ng-repeat="eachItem in data">
<label>{{eachItem.label}}</label>
<input type="text" ng-model="eachItem.value" />
</div>
<input type="button" value="save" ng-click="save()" />
</div>
</div>
This is my jsFiddle http://jsfiddle.net/0c5p38dt/5/
In the above code i have an array with multiple objects, these objects are getting from services dynamically. when i click add button again same objects push to the same array. I use ng-model inside ng-repeat for textfield. But when i enter data that will be effect on other textfields also.So how to differentiate the ng-model value for multiple same objects in array.
Your addFields() function is not adding fields that have their own objects. It is creating new fields that point to the existing objects.
Essentially, when your addFields() is called, it is saying "add two new fields that point to the same object as the first two fields." This is why they all share the same model.
The solution is to actually create a new object that is a clone of the original in the addFields() function like so:
$scope.addFields = function () {
var count=0;
angular.forEach($scope.data,function(obj){
if(count==2){
return true;
}
// Create a new object with the same properties as the original
var newObj = {'label':obj.label, 'type':obj.type}
$scope.data.push(newObj);
count=count+1;
});
};
I modified your jsFiddle: http://jsfiddle.net/nhupL4gs/
I tried to get the HTML page value to angularJS function , The below steps are which i tried.
HTML page :
<label class="item-input item-stacked-label">
<span class="input-label cont_det_label">First Name</span>
<p class="contact_display" id="txtFirstName" ng-model="testName">Satya</p>
</label>
angularJS Page :
.controller('SocialNetworkCtrl', ['$scope','$http','$state','ContactsService','$ionicNavBarDelegate','$ionicLoading','$ionicPopup',function($scope, $http, $state, ContactsService, $ionicNavBarDelegate, $ionicLoading,$ionicPopup) {
$scope.showUserProfile = function() {
$state.go("linkedin");
var firstname = (document.getElementById("txtFirstName").value);
}
}])
So I need var firstname = Satya ?? Is it correct way please guide me to access this value .
var firstName = $scope.testName
<input ng-model="testName" />
testName is the ng-model name that you have give. It will be automatically binded to your controller. No need the get the value using document.getElementById
Wrong usage , why ng-model in <p> tag??
Update
Change your fiddle with the following code, it will work. Also make sure framework is selected properly (as in the image)
<div ng-app ng-controller="testController">
<input ng-model="testDataName" ng-change="check()" /> {{testDataName}}
After ng-change : {{checkName}}
</div>
function testController($scope) {
$scope.testDataName="Dummy Name";
$scope.check = function () {
$scope.checkName=$scope.testDataName;
console.log($scope.checkName);
};
}
its a text node, you will require .innerHTML or '.innerText', .value is for form inputs
var firstname = (document.getElementById("txtFirstName").innerHTML);
and don't use ng-model on a p element, change it to like this
<p class="contact_display" id="txtFirstName">{{testName}}</p>
just use $scope.testName to get the value, no need for firstname = (document.getElementById("txtFirstName").innerHTML); querying DOM for value is jQuery style, use angular the $scope for 2 way bindings
Read more at official doc
Update here is updated function on loginCtrl
.controller('loginCtrl', ['$scope', function ($scope) {
$scope.testNameData = 'Satya';
$scope.doLogin = function() {
alert($scope.testNameData);
};
}])
If you really want to go jQuery way here is what you can do, its not recommended, you should use angular directive to do DOM manipulation
$scope.showUserPro = function() {
$ionicLoading.show();
// Here i need the value of <p tag>
var name = document.getElementById("txtFirstName"),
firstNameFromHtmlPtag = name.innerText;
console.log(firstNameFromHtmlPtag, 'Doing API Call 1');
}
One of the columns in my ng-repeat directive outputs the values of $$hashkey.
I have no idea how this started happening. I get data from a simple GET and inspecting that data as it gets in from the success callback shows the $$hashkey being inserted to each object. I understand the $$hashkey is used by angular but this never happened before as far as HTML view output goes.
This is on 1.2.16
HTTP GET:
$http.get('index.php/getWorkbook/'+$routeParams.workbook).success(function(data) {
console.log(data); // Has $$hashkey inserted
$scope.workbook = data;
});
HTML:
<tr ng-repeat='row in workbook'>
<td ng-repeat="key in notSorted(row)" ng-init="value = row[key]">
<input type="text" ng-model="value" ng-blur="edit(value, key, row)" />
</td>
</tr>
Here is the controller function.
$scope.notSorted = function(obj){
if (!obj) {
return [];
}
return Object.keys(obj);
}
Seems the rows don't like being ran through notSorted(). Adding angular.copy() ended up working for me.
$scope.notSorted = function(obj){
obj = angular.copy(obj);
if (!obj) {
return [];
}
return Object.keys(obj);
}
Try this change in your controller
$scope.workbook = data;
$scope.workbook = angular.fromJson(angular.toJson($scope.workbook));
I'm more and more disappointed with the angularFire 0.5.0, because nothing works correctly anymore. After I was able to fix the remove of a single item with help of you, I ran into another issue.
Each single item consists of a date, description and price. Before I updated, I was able to calculate the total of all prices and return it on the page. Now it just says NaN or Null. I was already trying to figure out why, but both values (earning.price, $scope.totalEarning) in the calculation are numbers. I don't get it. Does the new angular fire do anything? I'm trying to fix it since a while and just can't. I would be really, if somebody could figure it out. Probably I'm just not seeing it and it's a pretty dumb issue.
See it on plunkr: http://embed.plnkr.co/jb1iWOcjcm0alFchmzOH/preview
Here is the code:
$scope.addEarning = function() {
$scope.earnings.$add({date:$scope.FormEarningDate, description:$scope.FormEarningDescription, price:$scope.FormEarningPrice});
$scope.FormEarningDate = '';
$scope.FormEarningDescription = '';
$scope.FormEarningPrice = '';
$scope.updateEarning();
}
$scope.updateEarning = function() {
$scope.totalEarning = 0;
angular.forEach($scope.earnings, function (earning) {
price = parseFloat(earning.price)
$scope.totalEarning += price;
$log.log(typeof $scope.totalEarning);
})
$scope.totalBalance = $scope.totalEarning - $scope.totalCost;
}
And the html:
<form for="Profit" class="form-inline" style="margin-bottom: 20px" ng-submit="addEarning()">
<div class="form-group">
<div class="col-sm-3">
<input type="date" name="idate" ng-model="FormEarningDate" class="form-control" id="idate" placeholder="Date">
</div>
<div class="col-sm-5">
<input type="text" name="idesc" ng-model="FormEarningDescription" required class="form-control" id="idesc" placeholder="Description">
</div>
<div class="col-sm-2">
<input type="text" name="iprice" ng-model="FormEarningPrice" required class="form-control" id="iprice" placeholder="Amount">
</div>
</div>
<tr ng-repeat="earning in earnings | orderByPriority | orderBy : 'date'">
<td>{{earning.date}}</td>
<td>{{earning.description}}</td>
<td>{{earning.price}} €</td>
<td><button class="btn btn-danger" ng-click="earnings.$remove(earning.$id)">Löschen</button></td>
</tr>
<tr>
<td colspan="2"></td>
<td><strong>Total:</strong> {{totalEarning}} €</td>
<td></td>
</tr>
Updated Answer
There are several things you are doing incorrectly. As stated in my original answer, you need to iterate over the keys from Firebase, not the firebase object itself. Additionally, you need to ensure all updates happen after Firebase has updated (via an $on('change', ...) event handler) and within the AngularJS lifecycle (accomplished below using $timeout).
var app = angular.module('balance', ['firebase']);
app.controller('BalanceCtrl', function($scope, $log, $http, $timeout, $firebase) {
$scope.earnings = $firebase(new Firebase('https://dgdemo.firebaseio.com/Earnings'));
$scope.totalBalance = 'Nothing yet.';
$scope.totalEarning = 0;
$scope.totalCost = 0;
$scope.updateEarning = function() {
$scope.totalEarning = 0;
angular.forEach($scope.earnings.$getIndex(), function (id) {
var earning = $scope.earnings[id];
$scope.totalEarning += parseFloat(earning.price);
});
$scope.totalBalance = $scope.totalEarning - $scope.totalCost;
};
// Ensure any call to updateCallback will execute within the AngularJS lifecycle.
var updateCallback = angular.bind(null, $timeout, $scope.updateEarning);
$scope.addEarning = function() {
var earning = $scope.earnings.$add({
date: $scope.FormEarningDate,
description: $scope.FormEarningDescription,
price: $scope.FormEarningPrice
});
$scope.FormEarningDate = '';
$scope.FormEarningDescription = '';
$scope.FormEarningPrice = '';
};
$scope.earnings.$on('change', updateCallback);
});
Original Answer
This is because angular.forEach is iterating over all properties of the $scope.earnings object (which is a Firebase object). What you want to do is iterate over the individual items.
$scope.updateEarning = function() {
$scope.totalEarning = 0;
angular.forEach($scope.earnings.$getIndex(), function (id) {
var earning = $scope.earnings[id];
$scope.totalEarning += parseFloat(earning.price);
});
$scope.totalBalance = $scope.totalEarning - $scope.totalCost;
}