Let’s say I have a page where I display a list of links in my sidebar. But I also have other content I want to add in my sidebar and I don’t want to have to scroll down in order to see all the content I have there. What can I do to limit the size of my list of links? Oh, yes, I can use CSS and make the font size smaller. but I don’t want to do that, because I like the font-size like it is now. So what else can help me here…??

I know! I can use JavaScript! Cool! But if I use JavaScript, what would happen with my list of links when my page would be visited by someone that doesn’t have JavaScript enabled? hmmm… then I should use this technique called unobtrusive scripting. Ok, fine, I can do that! 

First, I should define my purpose: I want my list of links to show up as a DropDownList control for those having JavaScript enabled and also having the same functionality as it had before and to be displayed as a normal list for those that don’t have JavaScript enabled.

 The html markup for my list of links looks like this:

    <div id=”PageSidebarManager”>

        <div id=”ListContainer”>

            <ul id=”SIDEBAR_LIST_MENU”>

                <li class=”CAPTION”>

                    <p>Web sites</p>

                    <ul>

                        <li><a href=”http://www.seomegacorp.com/blog/Microsoft”>Microsoft</a></li>

                        <li><a href=”http://www.seomegacorp.com/blog/Adobe”>Adobe</a></li>

                        <li><a href=”http://www.seomegacorp.com/blog/Sun”>Sun</a></li>

                    </ul>

                </li>

                <li class=”CAPTION”>

                    <p>Search Engines</p>

                    <ul>

                        <li><a href=”http://www.seomegacorp.com/blog/Yahoo”>Yahoo</a></li>

                        <li><a href=”http://www.seomegacorp.com/blog/MSN”>MSN</a></li>

                        <li><a href=”http://www.seomegacorp.com/blog/Google”>Google</a></li>

                    </ul>

                </li>

                <li class=”CAPTION”>

                    <p>SEO</p>

                    <ul>

                        <li><a href=”http://www.seomegacorp.com/blog/Link baiting”>Link baiting</a></li>

                        <li><a href=”http://www.seomegacorp.com/blog/Black Hat”>Black Hat</a></li>

                        <li><a href=”http://www.seomegacorp.com/blog/White Hat”>White Hat</a></li>

                    </ul>

                </li>

            </ul>

        </div>

        <div id=”SidebarSelectorContainer”>

            <p class=”SelectorTitle”>Select: </p>

        </div>

        <div id=”SidebarUpdatePanel”>

            <p id=”textContainer” class=”ResultText”></p>

        </div>

    </div>


I have added some divs to wrap the content I’ll generate using JavaScript:

  1. SidebarSelectorContainer - this div will wrap the paragraph and the generated DropDownList control
  2. SidebarUpdatePanel - this div will wrap the paragraph that will display the selected item from the DropDownList.

Ok, I don’t quite need the last div, because when the user selects a menu item from the DropDownList I would redirect him to that specific page he requested, but for the sake of simplicity, I decided to just show some info in it.

At this point, I need the CSS markup, so my list of links would be displayed nicely on the page and also to hide (by default) the div I will be using in the script:

<style type=”text/css” media=”screen”>

 

DIV#PageSidebarManager { width: 500px; height: auto; margin: 50px auto auto 50px; padding: 5px 5px 5px 5px;}

 

/* JavaScript enabled */

DIV#SidebarSelectorContainer {

    display: none; /* will be made visible in script */

    width: auto; height: auto;

    text-align: left; vertical-align: middle;

    margin: 5px 5px 5px 5px; padding: 0 0 0 0;

}

P.SelectorTitle {

    float: left; margin: 3px 7px 0 3px; padding: 0 0 0 0;

    font-family: Georgia, Tahoma, ‘Times New Roman’, Serif;

    font-size: 10pt;

    font-weight: 800;

    color: #000000;

}

DIV#SidebarUpdatePanel {

    width: auto; height: auto;

    text-align: left; vertical-align: middle;

    margin: 5px 5px 5px 5px; padding: 0 0 0 0;

}

P.ResultText {

    margin: 3px 7px 0 3px; padding: 0 0 0 0;

    font-family: Verdana, Sans-Serif;

    font-size: 10pt;

    font-weight: 800;

    color: #696969;

}

 

/* JavaScript disabled */

                        /* SIDEBAR MENU */

UL#SIDEBAR_LIST_MENU { margin: 5px 5px 5px 0; padding: 0 0 0 0; }

LI.CAPTION { padding: 3px 0 3px 0; }

LI.CAPTION P {

    width: auto; height: auto;

    font-family: Georgia, Tahoma, ‘Times New Roman’, Serif;

    font-size: 12pt;

    color: #000000;

    margin: 0 0 0 0;

    text-indent: 5px;

}

/* SECOND LEVEL LIST */

UL#SIDEBAR_LIST_MENU LI UL { margin: 0 7px 0 7px; }

UL#SIDEBAR_LIST_MENU LI UL LI { }

UL#SIDEBAR_LIST_MENU LI UL A { color: #808080; }

UL#SIDEBAR_LIST_MENU LI UL A:hover { color: #000000; text-decoration: underline; }

 

</style>


Now I have one more question: Should I start scripting this by hand or I should use one of the multitude of free javascript libraries you can find over the internet? I could do it either way, but again, for the sake of simplicity I’ll choose the Core library (you can download it from here: Core library).

First thing first: import the script in the page.

Second, start writing my script. But, before actually starting it,  I’ll need two more Objects to make my work easier:

  1. the Core.Browser - to differentiate the Internet Explorer browser from the others,
  2. and the Core.DOM - to get the references to the objects I’ll need in my script.

Now I’m ready to write:     :  )

    <script id=”CreateSidebarMenu” type=”text/javascript”>

 

Core.Browser =

{

    UA: window.navigator.userAgent,

    isIE: function() { return (Core.Browser.UA.indexOf(“MSIE”) != -1); }

};

 

Core.DOM =

{

    getById: function(targetElement)

    {

        if (document.getElementById){ return document.getElementById(targetElement); }

        else if (document.all)      { return document.all[targetElement]; }

        else if (document.layers)   { return document.layers[targetElement]; }

    }

};

 

var SidebarMenuManager =

{

    init: function()

    {

        // get a reference to the main menu list ddl_container

        var list_container = Core.DOM.getById(“ListContainer”);

        // hide the main menu list ddl_container

        list_container.style.display = “none”;

 

        // get a reference to the selector’s ddl_container

        var ddl_container = Core.DOM.getById(“SidebarSelectorContainer”);

        // display the ddl_container

        ddl_container.style.display = “block”;

 

        // create the dropdownlist

        var selector = document.createElement(“select”);

        // Add the onChange event to DropDownList

        Core.addEventListener(selector, “change”, SidebarMenuManager.Selector_onChange);

 

        // get a reference to the main list ddl_container

        var mainList = Core.DOM.getById(“SIDEBAR_LIST_MENU”);

 

        // get a reference to the list captions

        var li_captions = Core.getElementsByClass(“CAPTION”);

        for (var c = 0; c < li_captions.length; c++) {

 

            var selectorCaptions = document.createElement(“optgroup”);

            selectorCaptions.label = li_captions[c].getElementsByTagName(“p”)[0].innerText ||

                                    li_captions[c].getElementsByTagName(“p”)[0].textContent;

            selector.appendChild(selectorCaptions);

 

            // get a reference to the second level list

            var secondLevel_list = li_captions[c].getElementsByTagName(“ul”)[0];

            // extract the links

            var links = secondLevel_list.getElementsByTagName(“a”);

            for (var s = 0; s < links.length; s++) {

 

                var optionLinks = document.createElement(“option”);

                var href = links[s].getAttribute(“href”);

                var text = links[s].innerText || links[s].textContent;

 

                if (Core.Browser.isIE()) { optionLinks.label = text; }

                else { optionLinks.text = text; }

 

                optionLinks.value = href;

                // add links in the optgroup

                selectorCaptions.appendChild(optionLinks);

            }

        }

 

        return ddl_container.appendChild(selector);

    },

    Selector_onChange: function(event)

    {

        // get a reference to the paragraph

        var text_container = Core.DOM.getById(“textContainer”);

        var textToShow = “”;

 

        if (Core.Browser.isIE()) {

            return text_container.innerText = “you have selected the “ + this.options[this.selectedIndex].label +

                                                ” list item and it points to: “ + this.options[this.selectedIndex].value;

        }

        else {

            return text_container.textContent = “you have selected the “ + this.options[this.selectedIndex].text +

                                                    ” list item and it points to: “ + this.options[this.selectedIndex].value;

        }

    }

};

Core.start(SidebarMenuManager);

    </script>

 I have now a totally unobtrusive list of links and more available space to use in the sidebar! *me happy now!*

If you’d like to test it, here’s the link: Unobtrusive list of links

===
note: I have only tested in IE7, opera 9, Firefox 2, Safari 3 on Vista OS.

Popularity: 11% [?]