I feel like I am missing something basic here, and would love some help.
I have some data that looks like this
"playerPoints"{
"ted":{"military":3,"gold":2},
"bill":{"military":2,"gold":4}
}
And an ng-repeat that is player in playerPoints and it shows a list of each players points. But I want a total at the end of each list. That adds up all of that specific players points. In this instance ted would have 5 and bill would have 6.
I have looked around and haven't really come across something that seems like it would work, but this is where the missing basic info could come into play.
Any assistance would be grand.
You need a function in your controller or service that does this in advance. Something like this untested example:
myService.data = {
"playerPoints": {
"ted": {
"military": 3,
"gold": 2
},
"bill": {
"military": 2,
"gold": 4
}
}
};
function sum(obj) {
var sum = 0;
for (var el in obj) {
if (obj.hasOwnProperty(el)) {
sum += parseFloat(obj[el]);
}
}
obj[el]["total"] = sum;
}
sum(myService.data.playerPoints);
In your controller you'll assign a variable to the service property:
ctrl.playerData = myService.data;
Then in your view you can simply output that key's value:
<div ng-repeat="player in ctrl.playerData">
<span>{{player.total}}</span>
...
</div>
If done properly in a service and stored as a property of the service the view will be automatically data-bound and will update dynamically if the object's data changes.
Related
I have a list of products and i'm storing it in my LocalStorage. My LocalStroage looks something like this:
{
"2":{"id":"2","colour":"Black","size":"S","quantity":"1"},
"3":{"id":"3","colour":"Blue","size":"Universal","quantity":"1"},
}
I want to display '2' in my UI(because i have two items in my LocalStorage). What I tried so far is:
var temp = JSON.parse(localStorage["productTable"]);
for(var i in temp) {
totalitems ++;
}
itemsincart.innerHTML = '<i class=\"ion-android-cart\"></i><span id=\"cart-total\">'+totalitems+'</span>';
In this i'm getting totalitems as sum of id which I know is wrong.
And tried this Localstorage: Count how many values in key when using stringify and in this i'm getting '1' everytime.
Can anyone please help me figure out how I can show the number of items in my LocalStorage?
You do not need to use for loop Object.keys(temp).length to get the length of json object like following snippet:
var temp = {
"2":{"id":"2","colour":"Black","size":"S","quantity":"1"},
"3":{"id":"3","colour":"Blue","size":"Universal","quantity":"1"},
};
console.log(Object.keys(temp).length+" items in cart");
In your case try following:
var temp = JSON.parse(localStorage["productTable"]);
itemsincart.innerHTML = '<i class=\"ion-android-cart\"></i><span id=\"cart-total\">'+Object.keys(temp).length+'</span>';
I recently searched a solution for this, and found out the easiest way is just to create another localStorage item (cartQty).
So everytime you add a product to your cart, increase the cartQty number.
$('button').on('click',function() {
//...
++i;
window.localStorage.setItem('cartQty', i);
// display your cart quantity
$('span#total').text(window.localStorage.getItem('cartQty');
}
didn't realised question is for AngularJS, but you get the idea
Try this out,
var totalitems = JSON.parse(localStorage["productTable"]).length;
itemsincart.innerHTML = '<i class=\"ion-android-cart\"></i><span id=\"cart-total\">'+totalitems+'</span>';
I am looking to order my list by a number of specific values on one property, and then some addtional properties once that is done.
The code I have is:
<tr ng-repeat-start="subcontractor in trade.SubContractors | orderBy:['Status':'PREF','Status':'APPR','Status':'LOGD','Status':'NIU','-AverageScores.AverageScore','-ProjectCount','SubcontractorName']">
Where the important bit (and the bit I can't get working) is:
'Status':'PREF','Status':'APPR','Status':'LOGD','Status':'NIU'
Is there a way of doing this in angular?
I would instead implement a handler to process data. Process subcontractors before it's set, running each element through a handler and assigning "sortValue" property to each one.
Then simply call orderBy using the sortValue property. This way you would decouple sorting data from displaying data. Though don't use a filter to do so, as it would be quite expensive resource-vise.
Something like
var statusSorting = ['PREF','APPR','LOGD','NIU'];
function sortContractors(models) {
var processed = [];
angular.forEach(models, function(model){
// logic to assign sortValue
var statusIndex = statusSorting.indexOf(model.status);
model.sortValue = statusIndex + 1;
});
return processed;
}
api.getData()
.then(function(data){
$scope.models = sortContractors(data);
});
// template
<tr ng-repeat="model in models | orderBy:'sortValue'">
You can then control priority by changing status position in the array and ordering desc/asc.
Alternately:
orderBy multiple fields in Angular
<tr ng-repeat="model in models | orderBy:['sortValue', 'contractorName']">
Your answer had a few non-required parts so I've tweaked it to give me the following:
function getStatusSortOrder(subcontractors) {
var statusSorting = ['PREF', 'APPR', 'LOGD', 'NIU'];
angular.forEach(subcontractors, function (model) {
statusIndex = statusSorting.indexOf(model.Status);
model.StatusSortValue = statusIndex;
});
}
I have a product controller and when I'm saving a new product I want to save some records to another related controller to make a record of what categories the product is associated with.
My code I'm using is:
$this->Product->create();
if ($this->Product->save($this->request->data)) {
$newProductId = $this->Product->getInsertID();
//associate products with categories
foreach($categoriesToSave as $key=>$value) {
$saveArray['CategoriesProduct'] = array('category_id'=>$value, 'product_id'=>$newProductId);
$this->Product->CategoriesProduct->create();
$this->Product->CategoriesProduct->save($saveArray);
$this->Product->CategoriesProduct->clear();
}
}
For some reason though, even if $categoriesToSave has 10 items in it, only the very last one is being saved. So it's obviuosly creating only the one new CategoriesProduct item and saving each record over the top of the last instead of create()-ing a new one.
Can anyone explain what I'm doing wrong and how I can make this work?
The way I would do it would be like this:
//Add a counter
$c = 0
foreach($categoriesToSave as $key=>$value) {
$saveArray[$c]['CategoriesProduct']['category_id'] = $value;
$saveArray[$c]['CategoriesProduct']['product_id'] = $newProductId;
$c++;
}
$this->Product->CategoriesProduct->saveMany($saveArray);
I don't think that is the only way to do it but that should work just fine.
Good luck!
I'd like to be able to search model attributes contained within a backbonejs collection. This is how I do it now...
wherePartial: function(attrs) {
// this method is really only tolerant of string values. you can't do partial
// matches on objects, but you can compare a list of strings. If you send it a list
// of values; attrs={keyA:[1,2,3],keyB:1}, etc the code will loop through the entire
// attrs obj and look for a match. strings are partially matched and if a list is found
// it's expected that it contains a list of string values. The string values should be considered
// to be like an OR operation in a query. Non-list items are like an AND.
if (_.isEmpty(attrs)) return [];
var matchFound = false;
return this.filter(function(model) {
// this is in the outer for loop so that a function isn't created on each iteration
function listComparator(value, index, list){
return model.get(key).toLowerCase().indexOf(value.toLowerCase()) >= 0;
}
for (var key in attrs) {
if (_.isArray(attrs[key])){
matchFound = _.any(attrs[key],listComparator);
if (matchFound !== true) return false;
} else {
matchFound = model.get(key).toLowerCase().indexOf(attrs[key].toLowerCase()) >= 0;
if (matchFound === false) return false;
}
}
return true;
});
}
Assume "C" is an instantiated collection, this is how I use it:
name:joe (nickname:joe the man nickname:joe cool nickname:joey)
is typed into a textbox and converted into this:
C.wherePartial({name:"joe",nicknames:["joe the man","joe cool","joey"]})
The above method returns all models that have the name joe and within that scope, any of the models that have the name joe and any of the nicknames. It works well for what I use it for. However, I'd really like to make a search that doesn't require the key:value pattern. I'd like to do this in a search box like when using a search engine on the web. I thought about just looking at every attribute on each model, but that takes awhile when you have a large collection (160k+ models).
Has anyone come across a need like this in the past? If so, how did you solve it? I'd like to keep the search contained on the client and not use any ajax calls to the backend. The reason for this is that the entire collection is already loaded on the client.
I thought of a way to do it. Serialize the attributes to a string during model instantiation. Listen for updates and update the serialization.
serializeAttr: function(){
this.serializedAttr = "";
var self = this;
_.each(this.toJSON(),function(value, key, list){
self.serializedAttr += value;
});
}
Then I can do simple searches on that cached value:
cc.serializedAttr.toLowerCase().indexOf("joe") >= 0
So i have 2 classes, users and health readings. i made a array of user objects with an array of readings inside it.i just want access to the date and weight in the reading array, i have been trying for a long time to figure this out! please help this simple problem is driving me nuts!
// Class to represent a row in the seat reservations grid
function Reading(theDate,theWeight)
{
self.theDate=ko.observable(theDate);
self.theWeight=ko.observable(theWeight);
}
function User(name,weight,date) {
var self = this;
self.name = name;
self.date = date;
self.weight = ko.observable(weight);
self.theReadings = ko.observableArray([
new Reading(12,13)
]);
}
// Editable data
self.users = ko.observableArray([
new User("George",1,2012),
new User("Bindu",2,2012)
]);
/this alerts an object but i dont know how to access the weight/date variable
alert(self.users()[0].theReadings()[0]);
self.readings = ko.observableArray([
new Reading(12,13)
Just missed a few things on this one.
Here ya go.
http://jsfiddle.net/EN7y4/3/
Namely. You had "self.theWeight" in function Reading instead of "this."...
Happy Coding!
alert(self.users()[0].theReadings()[0].theWeight();
I would recommend removing the 'thes'. That's an uncommon style.