Custom HTML Dropdown control (part 1)

My problem stated with the fact that if you set a width to a dropdown (select) control, IE clips the contents of a drop down list when expanded.

 

IE 7
Firefox 3

 

To solve this, I decided to create my own custom dropdown control and as a bonus be able to add some more custom functionality like ComboBox features, more visual effects, etc. 

 

The basic principle is to have two text boxes (one for the selected text and another one hidden for the selected value), a down arrow button to show the list of options and a div that shows the options. All this peppered with some javascript (using jquery to ease things up) to control the behavior.

 

The Text boxes & button

   1: <div>
   2:     <span class="textBoxWrapper">
   3:         <input type="text" id="ddText" class="ddTextBox" readonly>
   4:         <img src="gfx/downArrow.gif" id="btn" align="texttop" class="arrowImg">
   5:     </span>
   6: </div>
   7: <input id="ddValue" type="text" style="display:none;">

 

The first textbox (ddText) will hold the selected text, the second textbox (ddValue) will hold the value attribute of the selected item (if any) so it can be retrieved from the server side; and all these is wrapped in a span and a div. We need outer div to be able to make the span floated and having the whole control work as expected.

 

The list of options

   1: <div id="listBox" class="listBox" style="display:none;" tabindex="0">
   2:     <ul>
   3:         <li value="1">Item 1 with a lot of stuff to make it bigger</li>
   4:         <li value="2">Item 2 a little shorter</li>
   5:         <li value="3">Item 3</li>
   6:         <li value="4">Item 4</li>
   7:         <li value="5">Item 5</li>
   8:         <li value="6">Item 6</li>
   9:         <li value="7">Item 7</li>
  10:         <li value="8">Item 8</li>
  11:     </ul>
  12: </div>

The list of options is a regular div with an unorder list to hold the options. The only two special things about this code are the tabindex="0" property of the div that will help us workaround a problem with the OnBlur event on firefox not firing, and the non-standard "value" attribute of the list items.

 

With all these code we'll have the following control:

 

Styling the control

The wrapper and text boxes

   1: .textBoxWrapper {
   2:     border:solid 1px #7F9DB9;
   3:     padding:0;
   4:     white-space:nowrap;
   5:     height:1em;
   6: }
   7: .ddTextBox {
   8:     border:solid 0px white;
   9:     width:120px;
  10:     padding-left:.2em;
  11:     cursor:arrow;
  12: }
  13: .arrowImg {
  14:     margin:1px;
  15: }

The wrapper simple has a solid border with no padding and the white-space:nowrap will prevent the img from wrapping below the textbox.

Nothing special in the ddTextBox, we just remove the border (since we added the border to the span wrapped around the textbox and down arrow), set the width as desired and add some padding to make it look good, and we end up with this:

 

 

The styles for the list of options look like this:

   1: .listBox {
   2:     height:100px;
   3:     overflow-y:auto;
   4:     overflow-x:hidden;
   5:     border:solid 1px black;
   6:     background-color:white;
   7:     white-space:nowrap;
   8:     float:left;
   9:     position:absolute;
  10: }
  11: .listBox ul {
  12:     margin:0px;
  13:     padding:0px;
  14:     list-style-type:none;
  15: }
  16: .listBox ul li {
  17:     cursor:arrow;
  18:     padding-left:.2em;
  19:     padding-right:1.3em;
  20: }
  21: .highLight {
  22:     background-color:#316ac5;
  23:     color:white;
  24: }

The special things here are the overflow-y:auto to show the scroll bar if the content is greater than the defined height, and the float:left and position:absolute so it shows on top of the other elements on the page as expected. The rest of the classes are to format the <ul> and <li> elements and to highLight the options when we hover over them.

 

And that's all its needed to format our drop down for now

 

The script

Now all the magic happens in a set of javascript functions to handle the different events for our control:

   1: <script src="js/jquery-1.2.6.min.js" type="text/javascript"></script>
   2: <script type="text/javascript">
   3:     $(document).ready(function() {
   4:         var $items = $('#listBox ul li');
   5:         var $listBox = $('#listBox');
   6:  
   7:         $('#btn').click(function() {
   8:             var minWidth = $('#ddText').outerWidth() + $('#btn').outerWidth();
   9:             $listBox.css("left",$('#ddText').eq(0).offset().left).css("min-width",minWidth);
  10:             if($listBox.css("display")=="none") {
  11:                 $listBox.show("fast", function() {
  12:                     $listBox.scrollTop(0).eq(0).focus();
  13:                 });
  14:             }
  15:             else {
  16:                 $listBox.hide("fast");
  17:             }
  18:         });
  19:  
  20:         $items.click(function(e) {
  21:             $('#ddText').val($(this).text());
  22:             $('#ddValue').val($(this).attr("value"));
  23:             $listBox.hide("fast");
  24:         });
  25:         
  26:         $('#ddText').click(function() {
  27:             $('#btn').click();
  28:         });
  29:  
  30:         $items.hover(function() {
  31:                 $(this).addClass("highLight");
  32:             }, function() {
  33:                 $(this).removeClass("highLight");
  34:             }
  35:         );
  36:  
  37:         $listBox.blur(function(e) {
  38:             $listBox.hide("fast");
  39:         });
  40:     });
  41: </script>

 

When the btn.click event fires (the user click on the down arrow) we need to adjust the position of the listbox to be be below the textbox and show the div

When the user selects and item, we'll get the selected text and selected value and set them to the corresponding textBoxes, and hide the list box

When the hover event happens on the options we simple swap in and out the highLight class.

When the the user clicks on anything else on the page outside the list box (onblur) we need to hide the listbox without making a selection.

 

And that's it! we have a fully functional drop down that corrects the IE clipping problem and is ready to extend as we want (ie. combobox functionality, finer control over style, autocomplete, etc.).

 

In the next part we'll convert this into a server control to bind it to some server data and maybe we can add some combo box functionality.

 

For the complete source click here

 

EDIT: Next part is The Server Control

Published Saturday, November 22, 2008 12:23 PM by jaimedp

Comments

# Custom HTML Dropdown control (part 1) - Jaime del Palacio

Saturday, November 22, 2008 2:00 PM by Custom HTML Dropdown control (part 1) - Jaime del Palacio

Pingback from  Custom HTML Dropdown control (part 1) - Jaime del Palacio

# re: Custom HTML Dropdown control (part 1)

Wednesday, January 28, 2009 12:23 PM by Tom Cugini

Please send URL for Part 2 of this article.

Thanks,

Tom

# re: Custom HTML Dropdown control (part 1)

Wednesday, January 28, 2009 12:37 PM by Asim

Good example... did you get a chance to write about how to make this a server control?

# re: Custom HTML Dropdown control (part 1)

Monday, February 16, 2009 2:28 PM by Jeff

Looking forward to part 2.  Also, it seems the close event doesn't work in Safari, when clicking on the remeainder of the screen to close the dropdown.

# re: Custom HTML Dropdown control (part 1)

Monday, February 16, 2009 3:57 PM by jaimedp

I'm working on part 2 of this post, I hope I can upload it over the weekend

@Jeff, what version of safari are you seeing this problem?

# re: Custom HTML Dropdown control (part 1)

Thursday, February 26, 2009 8:10 AM by Hugh Jass

Just wondering what's in the .js file and how we can access that control.  Also, if you have the arrow graphic all alone that would be cool, otherwise I'm sure I can just cut it out from above or find my own.

# re: Custom HTML Dropdown control (part 1)

Thursday, February 26, 2009 1:48 PM by jaimedp

@Hugh. The jquery.x.x.x.js has the JQuery libreary. You can find a description at http://jquery.com/. Regarding the arrow you can use whatever graphic you like.

I'm finishing the Server control version of this drop down and all post a link to the blog entry in this entry too.

# re: Custom HTML Dropdown control (part 1)

Tuesday, March 31, 2009 6:08 AM by savitha

For the complete source click here

In the above website path complete source code is not working

# re: Custom HTML Dropdown control (part 1)

Wednesday, June 16, 2010 3:03 PM by Daniel Tsadok

Great work!

Ditto re the missing source code, though...

# re: Custom HTML Dropdown control (part 1)

Monday, October 03, 2011 12:12 PM by Hernando Cadet

How could I accomplish this for Drupal? My email is h.cadet@gmx.us is for my website at www.hernandocadet.info

# re: Custom HTML Dropdown control (part 1)

Monday, October 03, 2011 12:25 PM by jaimedp

@Hernando I'm not familiar with Drupal, but the basic concept (part 1) is only based on html and CSS, so as long as you can edit HTML & CSS directly into your CMS (being Drupal or any other), you can implement this concept.

Leave a Comment

(required) 
(required) 
(optional)
(required)