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); });