For me, standard HTML Select element is pretty much annoying. It's ugly. It can't be styled properly in Internet Explorer. And it can't contain nothing but simple text. That is the reason why I needed to reinvent Drop Down element. This tutorial shows how to do that (easily, believe it or not).
View demo Download source code
There is an update at the end of this tutorial and the second demo that shows the results of this updated code.
Simple structure
Let me explain HTML structure that will be used here. In this example we will use a short list of 8 countries. List is created using Definition List (DL) element. Why this element? It is similar to unordered/ordered list – the only difference is that DL consists of two elements: DT (term) and DD (definition). This makes it perfect candidate for Drop Down element. Element DT can be used to show collapsed state with currently selected option while DD can show all the available options in nested UL. Here is the sample structure:
<dl class="dropdown"> <dt><a href="#"><span>Please select the country</span></a></dt> <dd> <ul> <li><a href="#">Brazil</a></li> <li><a href="#">France</a></li> <li><a href="#">Germany</a></li> <li><a href="#">India</a></li> <li><a href="#">Japan</a></li> <li><a href="#">Serbia</a></li> <li><a href="#">United Kingdom</a></li> <li><a href="#">United States</a></li> </ul> </dd> </dl>
In order to make Drop Down functional we have to add several important CSS styles. First of all we have to reset margins and paddings for DD, DT and UL. DD will be positioned relatively, so that nested UL can be absolutely positioned. As I mentioned earlier, in collapsed state, only DT will be visible. It contains link with span inside it and two elements make sliding doors, a technique that is often used for creating buttons and tabs. Styling UL is simple, it will be positioned 2px below DT and initially hidden.
/* General dropdown styles */
.dropdown dd, .dropdown dt, .dropdown ul { margin:0px; padding:0px; }
.dropdown dd { position:relative; }
/* DT styles for sliding doors */
.dropdown dt a {background:#e4dfcb url(arrow.png) no-repeat scroll right center;
display:block; padding-right:20px; border:1px solid #d4ca9a; width:150px;}
.dropdown dt a span {cursor:pointer; display:block; padding:5px;}
/* UL styles */
.dropdown dd ul { background:#e4dfcb none repeat scroll 0 0; display:none;
list-style:none; padding:5px 0px; position:absolute;
left:0px; top:2px; width:auto; min-width:170px;}
.dropdown span.value { display:none;}
.dropdown dd ul li a { padding:5px; display:block;}
After adding some colors, borders and hover effects (check out source code on demo page), the result so far will be something that really looks like Drop Down.
Let's make it work
It's time to involve jQuery. Each click on DT (actually link inside DT) will toggle nested UL.
$(".dropdown dt a").click(function() {
$(".dropdown dd ul").toggle();
});
This was the simplest part. Now let's simulate other features of Select element. When you choose an option from the list (UL) it become selected option and is shown inside the link in DT. The function below replaces the HTML of currently selected item with the inner HTML of clicked link. At the end, it hides nested UL.
$(".dropdown dd ul li a").click(function() {
var text = $(this).html();
$(".dropdown dt a span").html(text);
$(".dropdown dd ul").hide();
});
This looks more like Drop Down, but there are still some things that need to be done. First, once you reveal nested UL by clicking on Drop Down it remains visible. And that's a bug. Although there can be better solutions, I've came up with this one:
$(document).bind('click', function(e) {
var $clicked = $(e.target);
if (! $clicked.parents().hasClass("dropdown"))
$(".dropdown dd ul").hide();
});
The function above checks each click on a page and if click occurred on some elements outside the dropdown it hides nested UL. Now this looks like regular Select element.
What about selected value?
Although it looks fine it will surely become a headache for developers. Select element has "value" attribute where you can store some data then needs to be sent to the server. This attribute is usually populated by ID's of records stored in the database. In our example with list of countries, it is more likely that some country ID will be needed for any serious processing on the server. So how to store these values and how to get selected one?
Let's modify HTML structure from the beginning of this tutorial and add <span> element inside links in UL. Each <span> have class "value" and real value inside it.
<dl class="dropdown"> <dt><a href="#"><span>Please select the country</span></a></dt> <dd> <ul> <li><a href="#">Brazil<span class="value">BR</span></a></li> <li><a href="#">France<span class="value">FR</span></a></li> <li><a href="#">Germany<span class="value">DE</span></a></li> <li><a href="#">India<span class="value">IN</span></a></li> <li><a href="#">Japan<span class="value">JP</span></a></li> <li><a href="#">Serbia<span class="value">CS</span></a></li> <li><a href="#">United Kingdom<span class="value">UK</span></a></li> <li><a href="#">United States<span class="value">US</span></a></li> </ul> </dd> </dl>
It would be strange to have codes next to country names in the list, so let's hide these spans.
.dropdown span.value { display:none;}
And that is the only change we'll need to make in order to make this Drop Down fully functional. Take one more look at click handler for links in UL – it replaces inner HTML of link in DT with inner HTML of clicked link. This means tha tlink in DT element will have <span> with value included.
var text = $(this).html();
$(".dropdown dt a span").html(text);
It's easy now to get selected value from our Drop Down. You can create a function like the one below to extract selected value. As the matter of fact, the very same function extracts selected value in the demo and shows this value under the Drop Down.
function getSelectedValue(id) {
return $("#" + id).find("dt a span.value").html();
}
The code works in all major browsers: Firefox, Safari, Google Chrome, Opera(9.64), Internet Explorer 7 and 8. It works even in IE6, althoug it needs some polishing :)
Update (29.07.2009): Creating DropDown from SELECT
Since many of you pointed out the issue with accessiblity (and I agree with that) I made another example that creates DropDown dynamically from SELECT element and binds click event to it. It still doesn't have up/down key navigation, though.
Instead of having hard-coded DL, we will have SELECT element with all the items here:
<select id="source"> <option selected="selected" value="BR">Brasil</option> <option value="FR">France</option> <option value="DE">Germany</option> <option value="IN">India</option> <option value="JP">Japan</option> <option value="RS">Serbia</option> <option value="UK">United Kingdom</option> <option value="US">United States</option> </select>
We will then use jQuery to dynamically create list from SELECT:
function createDropDown(){
var source = $("#source");
var selected = source.find("option[selected]"); // get selected <option>
var options = $("option", source); // get all <option> elements
// create <dl> and <dt> with selected value inside it
$("body").append('<dl id="target" class="dropdown"></dl>')
$("#target").append('<dt><a href="#">' + selected.text() +
'<span class="value">' + selected.val() +
'</span></a></dt>')
$("#target").append('<dd><ul></ul></dd>')
// iterate through all the <option> elements and create UL
options.each(function(){
$("#target dd ul").append('<li><a href="#">' +
$(this).text() + '<span class="value">' +
$(this).val() + '</span></a></li>');
});
}
Let me briefly explain the code here (you can check the entire source code in the second demo). It first reads all the <option> elements and selected <option> element as well. Next, it creates DL and DT with selected item inside it. After DL is being created, the code iterates throug <option> collection and create UL with list items inside it.
In order to fully bind this DropDown to SELECT element we need to refresh SELECT each time new selection is made in DropDown.
We have to modify click event handler for links in UL. It will get
the selected item from the DL and assign a value from <span> to
SELECT element.
$(".dropdown dd ul li a").click(function() {
var text = $(this).html();
$(".dropdown dt a").html(text);
$(".dropdown dd ul").hide();
var source = $("#source");
source.val($(this).find("span.value").html())
});
That should fix the issue. Thanks everyone for pointing out this.
Wasn't that simple?
I think that reinvention of Drop Down wasn't that hard, although it might seems as is it. There are several features that need to be implemented in order to have a credible simulation, but each one of those is simple and straightforward. Have you ever had a need for reinventing Drop Down? What are your experiences? In any case, let me know your thoughts!
Very very cool. I’ve seen that before, but never read a tutorial about how to make it. Great post Janko. And very helpful + inspiring.
Interesting. It would be better to have tab focus and key navigation
Hello Janko,
thanks for this great article. I really really appreciate your work on this issue.
tommy
Very nice tutorial !!
Is it better with dropdown dd ul { display:block } by default ?
Great tut. I like the idea but it does have some accessibility issues.
In an ideal world, it would have the same functionality as a standard drop down so you’d be able to access it using the regular keyboard shortcuts. Also, it would be nice if you could just use a regular dropdown and then replace it with your funky version if the user is running javascript.
Nice tutorial. you should implement it on your blog comments system ;-)
Thanks for the comments :)
jQueryGlobe, Patternhead: Yes, this has its price, so regular dropdown "behind the scenes" can be a solution. What I also missed to mention is :focus class that should be included.
Max: Dropdowns are in "collapsed" state by default, I doubt it will make sense to have it revealed by default.
Marc: I will think about it in next version, for sure :)
very cool. I’ve been several times in the need of reinventing the dropdown.
I will try to build an asp.net user control from this.
Thank you.
These are the little things that I try to improve in my designs. I never even thought about putting images and other elements in my drop-downs. Cool.
Wow another cool drop down menu! Thanks for the detail tutorial! Wonder what is the min version of browser support?
Nice job. I think with a few minor CSS adjustments you could fix the IE6 issues as well.
Seems to function but the layout of the visual drop down is off.
Thanks for posting the tutorials – keep them coming.
I woud definitely add sliding effect for this :)
You really need some :focus styles on there to help make this keyboard accessible.
Great looking manipulation.
I tried doing this a while back and the lack of keyboard integration was the killer for me, it didn’t fly with an users I had test it.
Here’s a link I found a while back that manipulates an actual select box element and turns it into a keyboard navigable, accessible version of what you did. It’s not as attractive but maybe combine the idea be and styles of you .
http://www.brainfault.com/2007/07/23/select-box-replacement/
Never finished my last sentence… It’s not as attractive but maybe someone combine the idea behind braindefault’s and styles of the tutorial on this page.
Echoing Patternhead, while it’s a great concept, this would be an absolutely fantastic solution if jQuery built the alternate DL markup automatically using a real < select > tag as the source of data.
Maybe I am missing something but what if you are posting a form to the server and can’t use javascript for the post? Then since you are not using a real select element the selected data does not get posted. Wouldn’t it be better to create a hidden input with the selected value after clicking?
Hey Janko, good job!
I was wondering how would you integrate this with the code behind, so we can manipulate the value on C# or VB.NET.
Brettgil: yes, it doesn’t take much work for IE6 :)
Sergejus: Good idea, some fast sliding would make it more attractive.
Jeff L: Yep, I realized that after posting the tutorial :)
HeySatan, Chris: This would resolve most of the issues. HeySatan, Thanks for the link!
DrWatson: A hidden input is fine If you don’t use javascript/ajax.
Lineker: HiddenField, DropDownList or runat="server" on Drop Down will make it accessible from the server.
I’ve been using a modified version of jQuery Stylish Select from Scott Darby:
http://www.scottdarby.com/2009/05/jquery-plugin-stylish-select-unobstrusive-select-box-replacement/
Demo:
http://www.scottdarby.com/plugins/stylish-select/0.3/
One thing I like about this is that it hides the browser select boxes (so in non or limited-JS browsers like phones, the original select still appears), and still supports [b]keyboard navigation[/b] and [b]proper usability[/b].
Wow, nice comments. I didn’t realized some things at first sight.
I think keyboard navigation/shortcuts will be very helpful regarding accessibility issues.
Nevertheless: a great job for modern browsers (I think you can skip IE6 support – like YouTube ;)) and backend functionality (almost, you can also skip accessibility there).
I think this article http://www.456bereastreet.com/archive/200705/why_styling_form_controls_with_css_is_problematic/ is a good starting point if someone wants to know some things about changing the style (and maybe the behavior) of common and well known control elements.
Justion: The plugin seems to be good one, although it needs modifications for styling.
Tommy: Sure, styling standard elements can really be a pain, that why you might consider "reinventing".
Hi. I think the most impressive detail in this is that the whole code is only some lines and it works as a charm.
You should keep this as a light, easy-to-understand version.
Cool innovative idea. My issue with it is accessibility, and others have hinted at this. The problem is non-javascript enabled clients can’t use this. (Nor would the hidden field work without JS to assign the value from the drop down). One solution that has been discussed is building the foundation using a select, then using jQuery to replace it with the newfangled drop down. Other than that I do love the innovative spirit behind this drop down, especially with the limited user interface options we have as web developers.
The box feels great.
As a few have stated, keyboard navigation would be a major plus. I.e., being able to TAB to the control and use the UP/DOWN/PageUp/PageDown controls. Not sure if this is possible.
Mohammad: Yes, that is an issue, and it should be done using <select> if required. For many line-of-business applications that rely heavily on javascript/ajax this wouldn’t be a big problem.
Valamas: Actually you can tab to the control but you won’t be able to use up/down keys.
I would suggest a small improvement: You even don’t need span element; you can easily add value into parent LI element, like:
[quote]
<LI value=’RS’>Serbia</LI>
[/quote]
… which can easily be reached via jQuery’s .attr(‘value’).
My 2 cents ;)
hey – cool implementation – one problem – in your source download, there are no files related to the demo. It seems you have zipped up the wrong folder :)
Does not work in Firefox 3.5
violonista: Good point! The only reason why I added span is that I can easily replace the HTML of DT link without accessing any other elements.
Bradvin: Ooops, my mistake. You can try now, I’ve fixed it.
Andrew: Strange, what bug occurs in FF3.5?
I’m not the biggest fan of dropdowns. They break way too often and you’re left annoyed with the website that doesn’t work right.
last week i’m developing a web app that required a selec with icons, and i make myself script and today i foud it :(, but your idea was very good, if iimplements kyboard navigator it’s wil lbetter!
Very cool, but when navegate by keyboard, should highlight the selection.
FULANO: It highlights the selection in demo if you use FF (:focus class)
Nice technique, maybe it will revive the dropdown menu. I haven’t been seeing them lately
Cool! i have just found it! but have you any ideas how to replace SELECT box tag with your script?
Thanks
I updated the tutorial with the code that creates DropDown from <select>. Demo is also updated.
Nice mate ,im going to try and edit it and give a fade in effect
Great tutorial! It looks a lot like the one at NETTUTS.
For adding keyEvents you could do something like this:
In my example it requires the select tag to be inside the dl tag.
It can easily be rewritten to suite the above example.
$( ".dropdown" ).keyup(
function( e ) {
// get keyCode (window.event is for IE)
var sKey = e.keyCode || window.event.keyCode;
var $select = $(this).find( "select" );
if(sKey == 40 || sKey == 38){
if( sKey == 38 ){ // keyUp
if( $select[0].selectedIndex == 0 || $select[0].selectedIndex == -1 )
$select[0].selectedIndex = 0;
else {
$select[0].selectedIndex–;
}
} else { // keyDown
if( $select[0].selectedIndex == $(this).find( "select option" ).length -1 )
$select[0].selectedIndex = 0;
else {
$select[0].selectedIndex++;
}
}
$(this).find( ‘a:first’ ).html( $(this).find(":selected").text() );
return true;
} else {
return false;
}
}
);
I saw that it highlights on focus, but what i really thought was highlight the options when it get focus by the Keyboard. Get it? Trigger de same effect of hover.
When we navigate to the selectbox and then press Enter, the options are showed, but when we try to select the option using the arrows it doesn’t highlight.
Mark: Thanks for the tip!!
Fulano: If you mean to expand the options on focus I think that would be the strange behavior. I haven’t implemented up/down key navigation, but Mark’s code can resolve this issue.
I like your approach Janko :-) Great job~
I don’t know why but on MacOSX FF3.0.11, I cannot see the comments (display:none on the div#commentlist)
Nothing occurs when I submit the comment form… known bug for BlogEngine.NET?
so, i could make SELECT BOX as display:none; and it will work. right?
Soh Tanaka: Thanks!!
Marin: I don’t know why is that happening, I will check that. Thanks for letting me know!
psd to html: Yep, it should work. Try hiding/unhiding SELECT in the demo with firebug :)
Awesome job!
One challenge I’m having is that if it is below the scroll (or farther down on the page), clicking it makes it move to the top. If you take the sample and put a lot of <p> spaces so it’s farther down on the page, you will see when you select it you return to home (@the top).
So drop downs toward the bottom are a little challenging.
Es genial, very cool reinventing input fields.
Hey, this is pretty cool, thanks for the tutorial.
I have developed the code for keyup and down some more. If the drop down is not open it just changes values/text on up/down key. If dropdown is open i navigates up and down the list.
The code is from the dropdown styling I have developed for my own project, for my company.
var oSelect = {
mCurrent : -1,
mTotal : 0
}
//==== Treating keys pressed
$( ".dropdown" ).keyup(
function( e ) {
// get keyCode (window.event is for IE)
var sKey = e.keyCode || window.event.keyCode;
var $select = $(this).find( "select" );
oSelect.mTotal = $(this).find( "select option" ).length;
if(sKey == 40 || sKey == 38){
if( sKey == 38 ){ // keyUp
if( oSelect.mCurrent == 0 || oSelect.mCurrent == -1 )
oSelect.mCurrent = oSelect.mTotal-1;
else {
oSelect.mCurrent–;
}
} else { // keyDown
if( oSelect.mCurrent == oSelect.mTotal -1 )
oSelect.mCurrent = 0;
else {
oSelect.mCurrent++;
}
}
if( $( this ).find( "ul:hidden" ).length > 0 ) {
$select[0].selectedIndex = oSelect.mCurrent;
$(this).find( ‘a:first’ ).html( $(this).find(":selected").text() );
} if( $( this ).find( "ul:visible" ).length > 0 ) {
// loop through each result li applying the correct style
$ul = $( this ).find("ul");
$ul.children().each(
function( i ) {
if( i == oSelect.mCurrent ) {
$select[0].selectedIndex = oSelect.mCurrent;
$( this ).addClass("selected");
} else
$( this ).removeClass("selected");
}
);
}
return true;
} else if( sKey == 13 ) {
if( $(this).find( "ul li.selected" ).text() != "" ) {
$(this).find( ‘a:first’ ).html( $(this).find( "ul li.selected" ).text() );
return true;
}
return false;
} else {
return false;
}
}
);
Hi Janko, thanks for the great tutorial, the drop down looks fantastic, thanks for sharing it with us.
This is so awesome. I hate select boxes, so this will totally redefine how I look at them.
Can somebody please see if this problem can be duplicated. It does it on IE7 (PC) and FireFox (Mac)
On the Demo: http://www.jankoatwarpspeed.com/examples/reinventing-drop-down/
1. Make the window size small so that you need to scroll down to access the drop down.
2. Once Scrolled down click the drop down
3. It will jump to the top of the page
When I put this in the footer of a demo site it’s causing it to jump to the top of the page.
Ben: The easiest way (although there might be better ones) is to add "return:false;" to the end of handlers for click events.
Mark: Thanks for sharing the code, once again :)
Looks pretty awesome although it would be great if you could also use the keyboard to navigate through the list. But very well written!
Very nice is, that it works without js too :).
Good work! I’ll be looking for something like this soon so very helpful.
Accessible version is always better; start with something that works for everyone and enhance it with JS.
Thanks!
excellent ty!! i was looking for a good solution to style <select>..maybe we can see some other styled form elements in the future? :)
Janko,
I guess I’m not experienced enough to get the jump from happening, how would you apply: return:false;?
Another example using jQuery can be found: http://www.filamentgroup.com/lab/jquery_ui_selectmenu_an_aria_accessible_plugin_for_styling_a_html_select/
Thanks in advance for any help.
Thanks everyone!
Bill: Check out this link on StackOverflow: http://stackoverflow.com/questions/265478/preventdefault-on-an-a-tag you can find explanation there for return:false, and also for another possibility and that is to use preventDefault() method.
Download link isn’t working for me.
dbone: I just tried and it works fine. Did you get any errors?
Janko,
Thanks for the advice. I updated:
$(".dropdown dt a").click(function() {
$(".dropdown dd ul").toggle();
});
with
$(".dropdown dt a").click(function(event) {
event.preventDefault();
$(".dropdown dd ul").toggle();
and is seems to work fine now — no jumping.
I wanted to utilize this on a page with multiple dropdowns and with the current config, it was only working with one per page. I re-wrote it a bit– and now it only affects the list that you’re clicking on. I’m no jQuery expert, so there’s a chance this is full of poor-use mistakes, but it works and I can have as many drop downs on a page as I want. Thanks for the idea, the styling, and the tutorial!
The only other change I made is that each DL list needs to have a unique ID (obviously). So, "sample1", "sample2", etc would work fine.
$(".dropdown dt a").click(function() {
var dropID = $(this).closest("dl").attr("id");
$("#"+dropID+" dd ul").slideToggle(200);
});
$(".dropdown dd ul li a").click(function() {
var dropID = $(this).closest("dl").attr("id");
var text = $(this).html();
var selVal = $(this).find(".dropdown_value").html();
alert("SELECTED: "+text+" | Value= "+selVal);
$("#"+dropID+" dt a").html(text);
$("#"+dropID+" dd ul").hide();
// INSERT FUNCTION HERE getSelectedValue("partner_dropdown"));
});
$("dl[class!=dropdown]").click(function() {
$(".dropdown dd ul").hide();
});
This is excellent, awesome enough – thanks a lot for your effort on this and sharing with us…
Thanks,
Vivek
[http://www.developersnippets.com]
Hi Again,
This is not working for IE 6.0….
Thanks,
Vivek
Hello Janko,
First off, excellent tutorial! After applying the code, I am having one slight issue though. We’re using multiple drop-downs and it seems that clicking on one opens both of them up. Is there any specific way to only open the one that is clicked on?
We’ve applied unique ID’s to both of them, however, the issue still remains. Any help would be much appreciated!
Nice work. I like your tutorials and will definitely learn from them.
Keep it up!
nice tutorial. its really easy and simple
I needed this working for multiple dropdowns on a page, and I also wanted some nice effects with it. I also needed to accomplish hiding the drop down when somewhere else on the page was clicked or when an item was clicked….
This is how I did it.
$(".dropdown dt a")
.click(function(){
$(this).closest(".dropdown").find("ul").animate({opacity: ‘show’, height: ‘show’}, ‘fast’);
return false;
})
.blur(function() {
$(this).closest(".dropdown").find("ul").animate({opacity: ‘hide’, height: ‘hide’}, ‘fast’);
});
$(".dropdown dd ul a")
.click(function() {
// DO YOUR STUFF HERE ON CLICK
return false;
});
Nice Articles. it can be enhanced using jquery toggle so it will look much better.
Hi Janco. Great stuff.
Can you add in your second example guys’ code for multiple dropdowns and add to <span>s another class based on corresponded option value (then we can create icons designing <span>s)?
I was hoping to use the version which automatically converts <select> boxes into this. It works fine except for one thing – I can’t put rich code like images inside the <option> tags:
<option><img /> abc</option> becomes <option> abc</option>
Even using .innerHTML removes the rich formatting. Even putting the contents of the <option> in a CDATA doesn’t work:
<option><![CDATA[<img /> abc]]></option> becomes <option></option>
Is there any way round this? Sure I could write the transformed structure by hand, but that feels ugly.
I worked around my problem by putting an alternative copy of the contents into the label attribute, and pulling those out on conversion:
<option label="<img /> abc">abc</option>
Sorry guys for my dilettantism
But can anybody tell me what is my mistakes? I just wanna create few drop downs on one page – immediately after selects.dropdown_value, and use spans.value to create unique icons for each list item.
$(document).ready(function() {
createDropDown();
$(".dropdown dt a").click(function(event) {
event.preventDefault();
var dropID = $(this).closest("dl").attr("id");
$("#" + dropID).find("ul").toggle();
});
$(document).bind(‘click’, function(e) {
var $clicked = $(e.target);
if (! $clicked.parents().hasClass("dropdown"))
$(".dropdown dd ul").hide();
});
$(".dropdown dd ul a").click(function() {
var dropID = $(this).closest("dl").attr("id");
var text = $(this).html();
var source = $(this).find(".dropdown");
$("#" + dropID + " dt a").html(text);
$("#" + dropID + " dd ul").hide();
source.val($(this).find("span.value").html())
});
});
function createDropDown() {
var selects = $(".dropdown_value");
var idCounter = 1;
var dropID = "dropdown_" + idCounter;
jQuery.each(selects, function() {
var source = $(this);
var selected = source.find("option[selected]");
var options = $("option", source);
source.after(‘<dl id="’ + dropID + ‘" class="dropdown"></dl>’);
$("#" + dropID).append(‘<dt><a href="#">’ + selected.text() +
‘<span class="value">’ + selected.val() + ‘</span></a></dt>’);
$("#" + dropID).append(‘<dd><ul></ul></dd>’);
options.each(function() {
$("#" + dropID + " dd ul").append(‘<li><a href="#">’ + $(this).text() +
‘<span class="value">’ + $(this).val() + ‘</span></a></li>’);
});
});
idCounter++;
}
i like mootools more, but still a great job!
I’ve change code for multiple drop downs with spans which can be used as icons by myself.
$(document).ready(function() {
createDropDown();
$(".dropdown dt a").click(function(event) {
event.preventDefault();
var dropID = $(this).closest("dl").attr("id");
$("#" + dropID).find("ul").toggle();
});
$(document).bind(‘click’, function(e) {
var $clicked = $(e.target);
if (! $clicked.parents().hasClass("dropdown"))
$(".dropdown dd ul").hide();
});
$(".dropdown dd ul a").click(function() {
var dl = $(this).closest("dl");
var dropID = dl.attr("id");
var text = $(this).html();
var source = dl.prev();
$("#" + dropID + " dt a").html(text);
$("#" + dropID + " dd ul").hide();
source.val($(this).find("span.value").html())
});
});
function createDropDown() {
var selects = $("select.dropdown_value");
var idCounter = 1;
selects.each(function() {
var dropID = "dropdown_" + idCounter;
var source = $(this);
var selected = source.find("option[selected]");
var options = $("option", source);
source.after(‘<dl id="’ + dropID + ‘" class="dropdown"></dl>’);
$("#" + dropID).append(‘<dt><a href="#">’ + selected.text() + ‘<span class="value">’ + selected.val() + ‘</span></a></dt>’);
$("#" + dropID).append(‘<dd><ul></ul></dd>’);
options.each(function() {
$("#" + dropID + " dd ul").append(‘<li><a href="#">’ + $(this).text() + ‘<span class="value">’ + $(this).val() + ‘</span></a></li>’);
});
idCounter++;
});
}
Very nice. I’ve been planing on doing something like this for a while! [b]Thank you![/b]
Anyone care to turn this into a JSF (javaserverfaces) component?
heres how to integrate this with icefaces:
<script>
var $j = jQuery.noConflict();
as per:
http://docs.jquery.com/Using_jQuery_with_Other_Libraries#Including_jQuery_before_Other_Libraries
Great tip..I was exactly looking for the same..you made my day..Thanks