Combobox, JQuery, Programming

Create and Style an Editable Select List Using a JQuery Combobox

JQuery Combobox
JQuery Combobox

By default there is no HTML control that can act as both a dropdown list and an editable input area. The best resource to create such a control is the JQuery Combobox widget.

Overview

HTML and Web-based controls can cause confusion for users who are accustomed to using Windows applications. Often the look of Web-based controls is similar to the Windows-based equivalent, but then the behavior of the HTML control is sufficiently different to cause confusion with the user.

Case in point: drop-down lists in a Windows-based application often allow a user to either select from a list of options, or to enter free-form text themselves. There is no real equivalent for this on the Web which basically combines the functionality of a free-form text area with a select list.

JQuery, however provides a neat solution for this through the Combobox widget. This is documented on the JQuery-UI Web site, and sample code is provided.

The Problem: No Basic Examples

Although taking example the code from the JQuery Web site and plugging it into a page works, it contains extra fields and styling that really doesn’t look presentable. It took me a bit of playing around with the code of my page and with the DOM of the JQuery Combobox widget before I was able to get it working in a way that looks good with a basic Web form.

The Solution: A Usable Sample

In the code at the bottom of this article I am providing an example version of the JQuery Combobox widget scaled down to the basics, and with the styles pre-set so that it will look good when it is plugged into a Web form. I think this will be useful for anyone who just wants to cut and paste a functional JQuery Combobox (including myself in future).

I won’t go into explaining the details of the JQuery code, since it is well documented on different sites including the JQuery-UI Web site from where I pieced it together.

Overview of the CSS Styling

However, the CSS styling of the Widget bears some explaining:

  • The .ui-menu-item style tag allows you to adjust the attributes of each item within the drop-down list. I needed to set the font size to 8pt since the default font size being rendered was too large.
  • .demo : This is the div that surrounds the ComboBox widget in the code below. I set the font size here to ensure uniform font sizes were being used throughout the widget. The default styling of the widget needs to be overidden since otherwise you will get a mixture of font sizes.
  • .ui-button This style will affect the rendering of the ComboBox widget’s down button. By default this button appears way too large for me. You can increase the height and width of the button using the CSS height and width attributes, but this will not go smaller after a point, which is a problem since this point is still too large. I needed to set the padding-top and padding-bottom to 2 px in order to gain control over the button’s size.
  • .ui-button.ui-widget .ui-button-text :  I also needed to adjust the attributes for these options in order to reduce the size of the ComboBox widget’s down button. I reduced the font size to 2pt and then set the line height as: line-height:10px; . This resulted in a down button that looked as high as the text box which was set at 20px high.
  • .ui-autocomplete-input :  This style affects the look of the text input area of the editable Combobox.

The Styled Example Editable Select List

<html><head><link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" type="text/css" media="all" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<style>
.ui-menu-item {font-size:8pt;}
.demo{font-size:8pt;}
.ui-button { margin-left: -1px; padding-top: 2px;padding-bottom: 2px;}
.ui-button-icon-only .ui-button-text { padding: 0.35em; }
.ui-autocomplete-input { margin: 0; padding: 0.2em 0 0.47em 0.45em;height:20px;}
.ui-button.ui-widget .ui-button-text{ line-height:10px; font-size:2pt; }
 </style>
 <script>
 (function( $ ) {
 $.widget( "ui.combobox", {
 _create: function() {
 var self = this,
 select = this.element.hide(),
 selected = select.children( ":selected" ),
 value = selected.val() ? selected.text() : "";
 var input = this.input = $( "<input>" )
 .insertAfter( select )
 .val( value )
 .autocomplete({
 delay: 0,
 minLength: 0,
 source: function( request, response ) {
 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
 response( select.children( "option" ).map(function() {
 var text = $( this ).text();
 if ( this.value && ( !request.term || matcher.test(text) ) )
 return {
 label: text.replace(
 new RegExp(
 "(?![^&;]+;)(?!<[^<>]*)(" +
 $.ui.autocomplete.escapeRegex(request.term) +
 ")(?![^<>]*>)(?![^&;]+;)", "gi"
 ), "<strong>$1</strong>" ),
 value: text,
 option: this
 };
 }) );
 },
 select: function( event, ui ) {
 ui.item.option.selected = true;
 self._trigger( "selected", event, {
 item: ui.item.option
 });
 },
 change: function( event, ui ) {
 if ( !ui.item ) {
 var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" ),
 valid = false;
 select.children( "option" ).each(function() {
 if ( $( this ).text().match( matcher ) ) {
 this.selected = valid = true;
 return false;
 }
 });
 if ( !valid ) {
 // remove invalid value, as it didn't match anything
 $( this ).val( "" );
 select.val( "" );
 input.data( "autocomplete" ).term = "";
 return false;
 }
 }
 }
 })
 .addClass( "ui-widget ui-widget-content ui-corner-left" );
 input.data( "autocomplete" )._renderItem = function( ul, item ) {
 return $( "<li></li>" )
 .data( "item.autocomplete", item )
 .append( "<a>" + item.label + "</a>" )
 .appendTo( ul );
 };
 this.button = $( "<button type='button'>&nbsp;</button>" )
 .attr( "tabIndex", -1 )
 .attr( "title", "Show All Items" )
 .insertAfter( input )
 .button({
 icons: {
 primary: "ui-icon-triangle-1-s"
 },
 text: false
 })
 .removeClass( "ui-corner-all" )
 .addClass( "ui-corner-right ui-button-icon" )
 .click(function() {
 // close if already visible
 if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
 input.autocomplete( "close" );
 return;
 }
 // work around a bug (likely same cause as #5265)
 $( this ).blur();
// pass empty string as value to search for, displaying all results
 input.autocomplete( "search", "" );
 input.focus();
 });
 },
 destroy: function() {
 this.input.remove();
 this.button.remove();
 this.element.show();
 $.Widget.prototype.destroy.call( this );
 }
 });
 })( jQuery );
$(function() {
 $( "#selLanguage" ).combobox();
 });
 </script>
</head><body>
<div class="demo">
<div class="ui-widget">
 <select id="selLanguage">
 <option value="">Select one...</option>
 <option value="ActionScript">ActionScript</option>
 <option value="AppleScript">AppleScript</option>
 <option value="Asp">Asp</option>
 <option value="BASIC">BASIC</option>
 <option value="C">C</option>
 <option value="C++">C++</option>
 <option value="Clojure">Clojure</option>
 <option value="COBOL">COBOL</option>
 <option value="ColdFusion">ColdFusion</option>
 <option value="Erlang">Erlang</option>
 <option value="Fortran">Fortran</option>
 <option value="Groovy">Groovy</option>
 <option value="Haskell">Haskell</option>
 <option value="Java">Java</option>
 <option value="JavaScript">JavaScript</option>
 <option value="Lisp">Lisp</option>
 <option value="Perl">Perl</option>
 <option value="PHP">PHP</option>
 <option value="Python">Python</option>
 <option value="Ruby">Ruby</option>
 <option value="Scala">Scala</option>
 <option value="Scheme">Scheme</option>
 </select>
</div>
</div></body></html>

JQuery Combobox References:

Advertisement

5 thoughts on “Create and Style an Editable Select List Using a JQuery Combobox”

  1. Thanks for the tip and the provided example. It was actually what I needed, too.

    1. I want to use same combo box multiple time in the form. Please can any one explain how can I do it. If I use same id(), first combo box only editable.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s