Go back to the main page

Simple Megadropdowns


Megadropdowns or (mega drop-downs) are a much better usability item than regular scrolling select boxes. Jakob Nielsen has a great write up on this topic. Below is simple and programmatic implementation of a megadropdown using Prototype. This implementation doesn't have a few characteristics that his article details, such as grouping,images, or typography; however, it does display all the information at once and eliminates scrolling. That characteristic is the most important usability benefit over traditional HTML select boxes.

Demo: Choose a state or province. click here


div.dropDown { position:absolute;background:whitesmoke;border-right:1px solid gray;border-bottom:1px solid gray; }
div.dropDown div.dropDownInner { cursor:pointer;padding:5px; }
    <a href="" class="usCa">click here<a>


var usJson = {"AL US":"Alabama","AK US":"Alaska","AS US":"American Samoa","AZ US":"Arizona","AR US":"Arkansas","CA US":"California","CO US":"Colorado","CT US":"Connecticut","DE US":"Delaware","DC US":"District of Columbia","FL US":"Florida","GA US":"Georgia","GU US":"Guam","HI US":"Hawaii","ID US":"Idaho","IL US":"Illinois","IN US":"Indiana","IA US":"Iowa","KS US":"Kansas","KY US":"Kentucky","LA US":"Louisiana","ME US":"Maine","MH US":"Marshall Islands","MD US":"Maryland","MA US":"Massachusetts","MI US":"Michigan","MN US":"Minnesota","MS US":"Mississippi","MO US":"Missouri","MT US":"Montana","NE US":"Nebraska","NV US":"Nevada","NH US":"New Hampshire","NJ US":"New Jersey","NM US":"New Mexico","NY US":"New York","NC US":"North Carolina","ND US":"North Dakota","OH US":"Ohio","OK US":"Oklahoma","OR US":"Oregon","PW US":"Palau","PA US":"Pennsylvania","PR US":"Puerto Rico","RI US":"Rhode Island","SC US":"South Carolina","SD US":"South Dakota","TN US":"Tennessee","TX US":"Texas","UT US":"Utah","VT US":"Vermont","VI US":"Virgin Islands","VA US":"Virginia","WA US":"Washington","WV US":"West Virginia","WI US":"Wisconsin","WY US":"Wyoming"};

$$('.usCa').invoke('dropdown',usJson,function(){ alert($H(this.values).inspect()); });

Documentation: List of arguments for the Dropdown class

Argument Description
Argument #1: JSON key,value Object or Array You may either use a key,value object like the usJson example above or a array e.g. ['Alberta','British Columbia', .. ]
Argument #2: Callback function The callback function this reference is automatically bound to the dropdown object. Therefore, you have a lot of freedom on how to handle the response. In general, the most used property is going to be this.values object. It has two properties this.values.inside and this.values.outside. In the above example .inside is equal to the key e.g. "NH US" and the .outside is equal to the value e.g. "New Hampshire". See the code for all the properties and methods available.
Options See table below for Options details

List of options for the Dropdown class

Option Default Description
groupsOf 12 Number of items listed in a column or a row (see layout option) before a new column or row is started.
Demo: click here
$$('.demoGroupsOf').invoke('dropdown',usJson,function(){ alert($H(this.values).inspect()); },{ groupsOf: 20 });
layout column The other option here is "row". Row will render the dropdown top to bottom / left to right.
Demo: click here
$$('.demoLayout').invoke('dropdown',usJson,function(){ alert($H(this.values).inspect()); },{ layout: 'row' });
alignRight false By default the dropdown is aligned left of where the click target is. By setting alignRight to true you may align the dropdown on its right side. Useful if the link target is near the edge of the right side of the page. The dropdown will be automatically adjusted to alignRight if click event is on the right half of the page.
Demo: click here
$$('.demoLayout').invoke('dropdown',usJson,function(){ alert($H(this.values).inspect()); },{ alignRight: true });
mouseOverColor gray
offsetLeft false With offsetLeft you may move the dropdown to the right or the left (by using negative values).
Demo: click here
$$('.demoOffsetLeft').invoke('dropdown',usJson,function(){ alert($H(this.values).inspect()); },{ offsetLeft: -200 });
offsetTop false With offsetTop you may move the dropdown down or up (by using negative values).
Demo: click here
$$('.demoOffsetTop').invoke('dropdown',usJson,function(){ alert($H(this.values).inspect()); },{ offsetTop: -200 });

List of actions for the Dropdown class

Action Description
add Adds data on the fly to the dropdown
Demo: click here
            $$('.demoAddData')[0].dropdown(usJson,function(){ alert($H(this.values).inspect()); }).add( { inside: 'CD US', outside: 'Canada' });
If you are just using a simple array you would just include the inside property
            .add( { inside: 'Canada' });
There are three other options for add being sortByKey,reverseOrder,andsortOff
sort Takes two arguments.
  • Argument 1 is true for sort by value and false to sort by key
  • Argument 2 is true for descending sort and false for ascending sort
Demo: click here
            $$('.demoSort')[0].dropdown(usJson,function(){ alert($H(this.values).inspect()); }).sort(true,true);


In the future, I would like to add simple grouping via a multi-dimensional JSON object such as in the below snippet. The big challenge here would be the layout, however, adding new data on the fly and sorting would also be difficult to do well. You can find the code on my github repo.

  // Idea for a grouping support
  "northeast": {
                "NY US": "New York", 
                "NH US": "New Hampshire", 
                "PA US": "Pennsylvania",
                "etc": "etc"

  • Pushed on 06/03/2010 by Christian