AutoComplete, Combobox, JavaScript, JQuery, Programming

JQuery Editable Select List – How to Duplicate the Value into a Text Box as it is Being Entered

Editable Select List Text Duplication
Editable Select List Text Duplication

Editable Select lists are a useful feature offered by JQuery through the JQuery-Ui ComboBox widget.

In an earlier article I explained how to set up a basic JQuery ComboBox widget, which I will expand on in today’s article.

So what is this article about? Bottom line is that I wanted to create something that looks like the above image, except that I wanted the duplication area to remain hidden when the form was to be submitted. How it should work is that as a user either types into the editable select list, or selects a value from the list of options, the text entered/selected should immediately be duplicated to a hidden area. For demonstration purposes, though, I have left the duplication area visible so that you can see the logic in action.

Why is this Useful?

Good question! I was working with a Web page written 15 years ago that was running VBScript and on the submit event was triggering ActiveX objects built by companies that have long since gone out of business. Because the existing code on the page was archaic and the deadlines were set to five minutes ago, I wanted to interfere as little as possible with the existing code.

So to keep the page objects and logic as unchanged as possible I turned the old text user input area into a hidden area and added a JQuery Editable Select list ComboBox that should populate the hidden field as the user was either selecting or manually entering information.

This is a rather unique requirement and may not be applicable to your case, but I’m certain that the logic can also be used for other purposes.

How can the text duplication be done?

The JQuery ComboBox widget comes with a number of events that can be used to catch changes. There are two events that need to be managed in order to capture changes to the selected text or the typed text in the editable select list, and a third that can possibly be useful depending on circumstances:

  1. The change: event option is useful to get the value of the widget when focus is lost
  2. The select: event option is useful when a user changes the selected item using the dropdown list option.
  3. The search: event option is useful when a user manually types into the editable select list

Although the change: event option looks to be the most useful, it is actually not the right option to use. The change: event fires like the JavaScript onBlur event. What this means is that the event logic is triggered only when focus is lost from the editable select list control by being placed elsewhere on the page (either by clicking or by typing). However if the user clicks the submit button, the event does not fire and the wrong value is in the field when the form is submitted!

So clearly the change: event option is not the right event for this example.

In its place, the select: and search: events work quite nicely.

Reviewing the select: event

The problem with the select: event is capturing the correct value. You do not want to get the original value, but the newly selected value. So remember not to get the value of the select list (which will return the original value), but instead get the value passed in to the event function.

In code this looks like the following snippet. I have highlighted in bold the line of code responsible for getting the latest value selected by the user:

select: function( event, ui ) {
 ui.item.option.selected = true;
 self._trigger( "selected", event, {
 item: ui.item.option
 });
$("#editTestId").val(ui.item.value);
 },

Reviewing The search: Event

The setValue: event is triggered whenever the user types in the editable select list. This is exactly the behavior needed to keep the value in the duplication area current using the following code snippet:

search: function(event, ui) {
var setValue = $( this ).val();
$("#editTestId").val(setValue) ;
},

The Example Code

Here is the code for the example page we’ve been looking at. You can copy and save the code below and it will render like the screenshot at the start of this article.

<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>
<script language="JavaScript">
 (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
 };
 }) );
 },
search: function(event, ui) {
var setValue = $( this ).val();
$("#editTestId").val(setValue) ;
},
 select: function( event, ui ) {
 ui.item.option.selected = true;
 self._trigger( "selected", event, {
 item: ui.item.option
 });
$("#editTestId").val(ui.item.value);
 },
 change: function( event, ui ) {
var setValue = $( this ).val();
$("#editTestId").val(setValue) ;
 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 ) {
 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() {
 if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
 input.autocomplete( "close" );
 return;
 }
 $( this ).blur();
 input.autocomplete( "search", "" );
 input.focus();
 });
 },
 destroy: function() {
 this.input.remove();
 this.button.remove();
 this.element.show();
 $.Widget.prototype.destroy.call( this );
 }
});
 })( jQuery );
 $(function() {
 $( "#selSelectListId" ).combobox();
 });
</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></head><body>
<div class="demo">
<div class="ui-widget">&nbsp;
<select name="selSelectListName" id="selSelectListId">
<option value="Alfa">Alfa</option><option value="Bravo">Bravo</option><option value="Charlie">Charlie</option><option value="Delta">Delta</option><option value="Echo">Echo</option><option value="Foxtrot">Foxtrot</option><option value="Golf">Golf</option><option value="Hotel">Hotel</option>
<option value="India">India</option><option value="Juliett">Juliett</option><option value="Juliet">Juliet</option><option value="Kilo">Kilo</option><option value="Lima">Lima</option><option value="Mike">Mike</option><option value="November">November</option><option value="Oscar">Oscar</option><option value="Papa"">Papa</option>
</select>
Duplication area:<input type="text" id="editTestId" name="editTestName" value="cat">
<input type="submit" id=connectbutton value="Submit Form" name="ButtonLogin" class="button">
</div>
</div>
</body></html>
Advertisement

1 thought on “JQuery Editable Select List – How to Duplicate the Value into a Text Box as it is Being Entered”

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