On Thu, Dec 18, 2008 at 4:49 AM, alpha tester <david.oli...@rbs.co.uk> wrote: > > > Hmmm... struggling to read from this new dataset using the code provided - > can someone point out the stupidity in the following code: > > <html> > <head> > <script type="text/javascript"> > var myData = > { records : [ > { CATEGORY : "Sport", TITLE : "The world of sport", LINK: "http://test.com" > }, > { CATEGORY : "Sport", TITLE : "More sport", LINK: "http://test.com" }, > { CATEGORY : "News", TITLE : "News views", LINK: "http://test.com" }, > { CATEGORY : "News", TITLE : "Some more news", LINK: "http://test.com" }, > { CATEGORY : "Events", TITLE : "Big Events", LINK: "http://test.com" }, > { CATEGORY : "Events", TITLE : "Small Events", LINK: "http://test.com" }, > ]}; > </script> > <script type="text/javascript" src="jquery.js"></script> > </head> > <body> > <div id="container"> > <ul> > <li>test</li> > </ul> > </div> > > <script type="text/javascript"> > > // Group categories dynamically into datasets > var categories = {}, groupBy = "CATEGORY"; > $.each(myData.records, function(i, record) > { > if (!categories[record[groupBy]]) > categories[record[groupBy]] = []; > categories[record[groupBy]].push(record); > }); > > //total number of categories > var categoryCount = myData.records.length-1;
You want the length of categories, not myData, because the former has the correct number of unique category names. But you don't need it, anyway. Also, I wouldn't bother pushing the entire record into categories because the name, being the key, is no longer necessary: categories[record[groupBy]].push({ title: record.TITLE, link: record.LINK }); Here, record[groupBy] represents the category name, which is the key that points to an array of title/link collections. I've changed the names to lowercase to distinguish this data from myData. > // Append categories to unordered list item > for (i=0;i<=categoryCount;i++) > { > $("ul").append("<li>"+categories.records[i].CATEGORY+"</li>"); > } > A few things: You need to supply the full tag, not just the name, as you would with createElement(). The <ul> only exists for each iteration. You need to create it before starting the loop. The name of each category is a key in the categories collection, so there's no reason to get it from records. And, now I notice it, you're referring to records as if it was a separate variable than myData. And you don't need the for() loop at all, as jQuery can iterate over categories. /* create a jQuery object */ var ul = $('<ul>'); $.each(categories, function(key, val) { /* key is the category name string * val is an array of title/link collections */ $('<li>').text(key).appendTo(ul); }); /* attach the list to the body */ ul.appendTo('body'); If you want a sub-list for each category: var ul = $('<ul>'); $.each(categories, function(key, val) { var li = $('<li>').text(key); if (val.length) { var ul_inner = $('<ul>'); /* val is an array of objects so no key */ $.each(val, function(i, o) { $('<li>') .append($('<a>') .attr('href', o.link) .text(o.title) ) .appendTo(ul_inner); }); li.append(ul_inner); } li.appendTo(ul); }); ul.appendTo('body'); There's likely a far more elegant way to do that but I'm not quite finished my first coffee yet.