Pages

Subscribe Twitter facebook

Wednesday, February 8, 2012

Custom Drop-down Menu using CSS and jQuery


A google search for 'custom drop-down menu' or 'custom html select' returns several amazing articles and blog posts explaining how to customize the html select tag. And most of them customize using css and javascript. Most of them demonstrate how the tag can be edited to match websites themes and stuff.

Now, instead of just customizing the existing menu, I've tried to create a new menu using jQuery which works the same way a normal html select tag works. It's surprisingly simple to create and is cross-browser compatible.

For this, I'm gonna be using jQuery-1.7.1. Let's start with the basic structure of the new drop-down menu(ddm). Here, I'll use an html ul(Unordered List) tag to display the options and a normal html div as the base which displays the selected item.

First, Let's design the base. The CSS code for the base div tag goes like this:
.cselect{
height: 32px;
font-family:inherit;
font-size:13px;
margin-top: 20px;
width: 288px;
background: rgb(248,248,248);
border: 1px solid #d9d9d9;
padding: 14px 0 0 10px;
cursor:pointer;
}
.cselect:hover{
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
-webkit-box-shadow:0 2px 5px rgba(0, 0, 0, 0.2);
box-shadow: 0 1px 2px rgba(0, 0, 0,0.15);
border-color: #999;
}
.cselect[state=selected] {
background: -webkit-gradient(linear,left top,left bottom,from(#EEE),to(#E0E0E0));
background: -moz-gradient(linear,left top,left bottom,from(#EEE),to(#E0E0E0));
background: -o-gradient(linear,left top,left bottom,from(#EEE),to(#E0E0E0));
-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
-moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
border-color: #CCC;
color: #333;
}



The base is ready. Now to design the list that displays the options. For this i'll be using the html ul tag.


ul.list1{
font-family: inherit;
font-size:13px;
  width: 288px;
margin:0;
  background: rgb(249,249,249);
 border: 1px solid #d9d9d9;
cursor:default;
list-style-type: none;
padding-left: 5px;
padding-right: 5px;
 padding-top:4px;
}
ul.list1 li{
width: 288px;
height: 32px;
padding: 11px 0 0 0;
border-bottom: 1px solid #999;
}
ul.list1 li.last{
border: none;
}
ul.list1 li:hover{
background: #999;
background-size: 100%;
color: #fff;
}
#l1, #l2{
text-decoration:none;
}

Now with both the elements designed and ready, I'll animate the visibility of the list to imitate a drop-down menu.

$(".list1").hide();
$(".list1").focusout(function(){ $(this).hide();});

$(".cselect").click(function(){    
  if($(this).attr("state") == "")
  $(this).attr("state","selected");
  else if($(this).attr("state") == "selected")
  $(this).attr("state","");
  $(".list1").toggle();
   });

Now, for this to be included in a form, I'lll add an <input> tag with type="hidden" which will hold the value selected using the drop-down menu and submit it with the form.
<input type="hidden" id="hidval" name="tag">

Now to bind the input tag with the ddm so that it's value changes according to the selection.

function setvalue(id)
{
var v=$(id).text();
$(".cselect").attr("state","");
$(".cselect").html(v);
$("#hidval").val(v);
$(".list1").hide();
};
The HTML part for the base and the list goes like this:
<div class="cselect" state="">Custom Select</div>
<ul class="list1">
  <li id="l1" onClick="javascript: setvalue(this);" value="Choice1">Choice2</li>
  <li id="l2" onClick="javascript: setvalue(this);" class="last" value="Choice2">Choice2</li>
</ul>
The function setvalue() will be trigerred when a choice is selected which changes the value in the hidden input tag.

Hence the total code for the custom drop-down menu is:
<script type="text/javascript">
$(document).ready(function(){
$(".list1").hide();
$(".list1").focusout(function(){ $(this).hide();});
$(".cselect").click(function(){    
 if($(this).attr("state") == "")
 $(this).attr("state","selected");
 else if($(this).attr("state") == "selected")
 $(this).attr("state","");
 $(".list1").toggle();
 });
});
function setvalue(id){
  var v=$(id).text();
  $(".cselect").attr("state","");
  $(".cselect").html(v);
  $("#hidval").val(v);
  $(".list1").hide();
};
</script>
<style type="text/css">
.cselect{
height: 32px;
font-family:inherit;
font-size:13px;
margin-top: 20px;
width: 288px;
background: rgb(248,248,248);
border: 1px solid #d9d9d9;
padding: 14px 0 0 10px;
cursor:pointer;
}
.cselect:hover{
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
-webkit-box-shadow:0 2px 5px rgba(0, 0, 0, 0.2);
box-shadow: 0 1px 2px rgba(0, 0, 0,0.15);
border-color: #999;
}
.cselect[state=selected] {
background: -webkit-gradient(linear,left top,left bottom,from(#EEE),to(#E0E0E0));
background: -moz-gradient(linear,left top,left bottom,from(#EEE),to(#E0E0E0));
background: -o-gradient(linear,left top,left bottom,from(#EEE),to(#E0E0E0));
-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
-moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
border-color: #CCC;
color: #333;
}
ul.list1{
font-family: inherit;
font-size:13px;
  width: 288px;
margin:0;
  background: rgb(249,249,249);
 border: 1px solid #d9d9d9;
cursor:default;
list-style-type: none;
padding-left: 5px;
padding-right: 5px;
 padding-top:4px;
}
ul.list1 li{
width: 288px;
height: 32px;
padding: 11px 0 0 0;
border-bottom: 1px solid #999;
}
ul.list1 li.last{
border: none;
}
ul.list1 li:hover{
background: #999;
background-size: 100%;
color: #fff;
}
#l1, #l2{
text-decoration:none;
}
</style>
<div class="cselect" state="">Custom Select</div>
<ul class="list1">
  <li id="l1" onClick="javascript: setvalue(this);" value="Choice1">Choice1</li>
  <li id="l2" onClick="javascript: setvalue(this);" class="last" value="Choice2">Choice2</li>
</ul>
<input type="hidden" id="hidval" name="tag">
The custom Drop-Down Menu should work just fine with the above code.