Saturday, 23 March 2013

Multi-level Bootstrap Menu on GDrive or site44

I've talked about menus within GDrive and site44 before but I've improved my script so that it allows multi-level menus. Given the following json:

var links = [
    {
        "text": "Cam River Levels",
        "url":[
            {
                "text":"Canal Lock",
                "url":"/canal/"
            }

        ]
    },
    {
        "url":"/star/",
        "text":"Star"
    },
    {
        "url":"/time/",
        "text":"Time"
    },
    {
        "text":"SVG",
        "url":[
            {
                "text":"Swirly Skyline",
                "url":"/img/city.svg"
            },
            {
                "text":"Swirly Colour",
                "url":"/img/sun.svg"
            },
            {
                "text":"Swirly Greyscale",
                "url":"/img/pretty.svg"
            },
            {
                "text":"Spinny Swirly",
                "url":"/img/spinny_swirly.svg"
            }
        ]
    },
    {
        "text":"Experiments",
        "url":[
            {
                "text":"MultiSelect",
                "url":"/multiselect/"
            },
            {
                "text":"data URL",
                "url":"/experiments/data_url_messing.html"
            }
        ]
    }
];
var base = "https://googledrive.com/host/randomstring";

My new jQuery looks like this:

$(function(){
    $.each(links, function(k,v){
        if (v.url instanceof Array) {
            var dropdown = $("<li></li>", {
                "class": "dropdown"
            }).appendTo($("#siteLinks"));
            dropdown.append($("<a></a>", {
                "class": "dropdown-toggle",
                "data-toggle": "dropdown",
                "href": "#",
                "text": v.text
            }).append($("<b></b>", {
                "class": "carat"
            })));
            var dropdownMenu = $("<ul></ul>", {
                "class": "dropdown-menu"
            }).appendTo(dropdown);
            $.each(v.url, function(a, b){
                dropdownMenu.append($("<li></li>").append($("<a></a>", {
                    "href": (b.url.indexOf("http") == -1) ? base + b.url : b.url,
                    "text": b.text
                })));
            });
        } else {
            $("#siteLinks").append($("<li></li>").append($("<a></a>",{
                "href": (v.url.indexOf("http") == -1) ? base + v.url : v.url,
                "text": v.text
            })));
        }
    });
    $("#siteLinks").find("li").each(function(k,v){
        if ($(v).find("a").attr("href") == document.location.href.toString()) {
            $(v).addClass("active");
        }
    });
});

It's simplified the adding of the "active" class. I'm really quite happy with it and it makes the script easier to read.