0

I have problems with printing to html an array with json objects. The original code Im using is this for the javascrit object that is the "shopping cart"

var ShoppingCart = {
  Id: 1,
  ShoppingCartItems: [] //array with json objects
};

And the array in the "ShoppinCartItems"

{Id:1,ShoppingCartItems:[{ProductID:"9",Quantity:"2",Price:"68.40",Name:"Cake",Date:"2014-05-30",StoreID:"1",UserID:"1"},{ProductID:"7",Quantity:"1",Price:"11.40",Name:"Donut",Date:"2014-05-30",StoreID:"1",UserID:"1"}]}

(I dont know if this is valid because im using an example.)

So with this array of json objects I want to display a table in html displayin those values group by date. The actual code Im using is this:

$.each(ShoppingCart.ShoppingCartItems, function (i, Productos) {
   $(".cart").append("\
   <tr style='background-color: #F1F1F1; border-bottom: 3px solid #fff;'>\
   <td style='width: 10%;'>" + Number(Productos.Quantity) + "</td>\
   <td style='width: 33%'>" + Productos.Name + "</td>\
   <td style='width: 33%'>" + (Productos.Date || 'N/A') + "</td>\
   <td style='width: 20%'>" + Productos.Price + "</td>\
                        </tr>");
 }); //each

But unfortunately the result will be like this

Qty            Name           Price
2014-05-30
2              Cake           68
2014-05-30     
1              Donut          10 (e.g.)

And the result I want is this

Qty            Name           Price
May 30, 2014
2             Cake            68
1             Donut           10 (e.g.)
---
May 31, 2014
1             Other product   10.00

I want the products grouped by date but I cant manage to group by from the json array of every product, I dont know which is the bes solution, hope someone can help me

Thanks

Jorge F
  • 679
  • 1
  • 11
  • 24
  • are the items sorted by that date or not? – Axel Amthor May 13 '14 at 16:52
  • Thanks for the reply, every item has it's own date. The functionality is the user pick a date (from datepicker for example), and every product they choose will have that date (e.g. 2014-05-13) that is today in this case. – Jorge F May 13 '14 at 16:55
  • Thanks for the help, I'll try to understand the code because as a non english speaker is a little bit more dificult to understand the explaantion. As Derek comment, another answer has the solution but I'll try to see what I can undestand. – Jorge F May 13 '14 at 17:18

2 Answers2

0

It appears your problem is similar to the one found here.

The solution there was as follows:

First, separate grouping and aggregating. Lets declare prototypical "group by" function. It takes another function to produce "hash" string for array element.

Array.prototype.groupBy = function(hash){   
   var _hash = hash ? hash : function(o){return o;};
   var _map = {};   
   var put = function(map, key, value) {
     if (!map[_hash(key)]) {
       map[_hash(key)] = {};
       map[_hash(key)].group = [];
       map[_hash(key)].key = key;
     }

     map[_hash(key)].group.push(value);    
   }

   this.map(function(obj){
     put(_map, obj, obj);   
   });

   return Object.keys(_map).map(function(key){
       return {key: _map[key].key, 
         group: _map[key].group
       };   
     }); 
};

When grouping is done you can aggregate data how you need, in your case

data.groupBy(function(o){
  return JSON.stringify({a: o.Phase, b: o.Step});
})
/* aggreagating */
.map(function(el){ 
  var sum = el.group.reduce(function(l,c) {
    return l + parseInt(c.Value);
  }, 0);

  el.key.Value = sum; 
  return el.key;
}); 

In general, it works. I have tested this code in Chrome console, but feel free to improve and find mistakes ;).

I think that is what you are looking for.

Here I have an implementation of grouping that will get you an array of dates. http://jsfiddle.net/JV499/2/

var ItemsByDate = new Array();
$.each(ShoppingCart.ShoppingCartItems, function (i, Productos) {
    var pushNewItem = true;
    for (var index = 0; index < ItemsByDate.length; index++)
    {
        dateGroup = ItemsByDate[index];
        if (dateGroup.Date && dateGroup.Date == Productos.Date) {
            dateGroup.Items.push(Productos);
            pushNewItem = false;
        } else {

            pushNewItem = true;
        }
    }
    if (pushNewItem) {
        ItemsByDate.push({
                Date : Productos.Date, Items : [Productos]
            });
    }
});
Community
  • 1
  • 1
Fyona
  • 79
  • 4
  • I think he is using underscore.js, I can't use that for some reasons. – Jorge F May 13 '14 at 16:58
  • The third answer has a solution that does not require another java script library to function. However it might require some finessing for your particular application. There is likely a much more simple solution that will solve this for your particular scenario. – Fyona May 13 '14 at 17:04
  • Thanks I will try to understand the answer as beginner. – Jorge F May 13 '14 at 17:19
0

I think all you need to do is sort the array by date, which you can achieve like so:

data.ShoppingCartItems.sort(function (a, b) {
  return new Date(a.Date) - new Date(b.Date);
});

When you come to loop over the array keep a reference to the last date and only add the date to the output if it's different.

This example will help explain it better.

Andy
  • 61,948
  • 13
  • 68
  • 95
  • Thanks for the response, I will give it a try but in the fiddle you are using forEach (which i think it's has no compatibility for below IE9, and for various reasons I need compatibility, but I will give it a try to your code. – Jorge F May 13 '14 at 17:33
  • Thanks Andy, your solution (fiddle) I managed to use $.each for compatibily reasons and adapt with my needs and I tested and everything seems to work fine!. Thank you very much for the fiddle and your time. – Jorge F May 13 '14 at 18:21