Kevin Miller has created an accordion widget using prototype and script.aculo.us. In this article I'll demonstrate how to build a selection list that has sub-sections utilizing the accordion control. Here is a demonstation comparing a basic select list control and the accordion select list: To make the control work, you first add a read-only text box with the drop down button image floating to the right of it, for example:
<span style="float: right"> <img id="accSelectToggle" src="images/btn_dropdown.png" width="21" height="16" alt="Expand list" title="Expand list" /> </span> <input type="text" id="accSelect" title="List" readonly="readonly" value="Option 1.1" />You then define a
div which contains the accordion control, such as:
<div id="accSelectOptions" class="accordion_container" style="display: none"> <h1 class="accordion_toggle">Category 1</h1> <div class="accordion_content"> <ul> <li value="option11">Option 1.1</li> <li value="option12">Option 1.2</li> <li value="option13">Option 1.3</li> </ul> </div> ... </div>Add your preferred CSS styling. In my example the CSS looks like:
#accSelect {
 width: 169px;
 height: 14px;
 border-style: none;
 padding-left: 4px;
}
.accordion_container {
 z-index: 10;
 position: absolute;
 width: 198px;
 border: solid 1px black;
}
.accordion_toggle {
 display: block;
 padding: 0.3em 0.5em;
 font-weight: normal;
 font-size: 1em;
 text-decoration: none;
 outline: none;
 border-bottom: 1px solid #def;
 color: #000000;
 cursor: pointer;
 margin: 0px;
 background-image: url('images/expand.gif');
 background-position: 99% 50%;
 background-repeat: no-repeat;
 padding-right: 5px;
 background-color: #9BE;
}
.accordion_toggle_active {
 color: #ffffff;
 font-weight: bolder;
 background-image: url('images/ns-expand.gif');
 background-color: #47B;
}
.accordion_content {
 background-color: #ffffff;
 overflow: auto;
 display: block;
}
.accordion_content ul {
 padding-left: 1em;
 margin: 0;
 padding-right: 0;
 padding-bottom: 0px;
 list-style-type: none
}
.accordion_content li {
 margin: auto;
 padding: 0px;
}
.highlight {
 background-color: #DDD;
}
And finally add a little JavaScript to make the magic happen:
    function  toggleAccordionSelect(event) {
        var image = event.target;
        var collapseIcon = "images/btn_dropdown-selected.png";
        var expandIcon = "images/btn_dropdown.png";
        if ($('accSelectOptions').style.display === 'none') {
            image.src = collapseIcon;
            image.alt = "Collapse List";
            image.title = "Collapse List";
            $('accSelectOptions').show();
        }
        else {
            image.src = expandIcon;
            image.alt = "Expand List";
            image.title = "Expand List";
            $('accSelectOptions').hide();
        }
    }
    function toggleHighlight(event) {
        var item = event.target;
        item.toggleClassName('highlight');
    }
    
    function selectAccordionOption(event) {
        var selectedOption = Event.element(event);
        // update the selection input field value to the selected display value
        $('accSelect').value = selectedOption.innerHTML;
        // internal value is stored as an attribute, do whatever you need to with it
        var realValue = selectedOption.getAttribute('value');
        
        // hide the accordion list
        toggleAccordionSelect({target: $('accSelectToggle')});       
    }
    
    var accordionSelect = new accordion('accSelectOptions', {
        classNames : {
            toggle : 'accordion_toggle',
            toggleActive : 'accordion_toggle_active',
            content : 'accordion_content'
            },
        onEvent : 'mousedown'
        });
    // By default, open first accordion in the drop down
    var accordionToggles = $$('#accSelectOptions .accordion_toggle');
    accordionSelect.activate(accordionToggles[0]);
    // register event observers        
    Event.observe('accSelectToggle', 'mousedown', toggleAccordionSelect);
    $$('#accSelectOptions .accordion_content li').each(function(accSelectOption) {
        Event.observe(accSelectOption, 'mousedown', selectAccordionOption);
        Event.observe(accSelectOption, 'mouseover', toggleHighlight);
        Event.observe(accSelectOption, 'mouseout', toggleHighlight);
    });
 









 ) on the right side of the text.  The background color is white with a double gray border and large, bold font.
) on the right side of the text.  The background color is white with a double gray border and large, bold font.