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.

Reply via email to