Search and Top Navigation
#7897 closed bug (notabug)
Opened November 18, 2011 04:39AM UTC
Closed November 18, 2011 04:54AM UTC
Last modified November 18, 2011 05:57AM UTC
autocomplete combobox implementation is missing "required" validation
Reported by: | ole | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | 1.9.0 |
Component: | ui.core | Version: | 1.8.16 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
Hi,
In this write up I have assumed that the goal of the autocomplete combobox is to provide the same functionality as a regular select element, in addition to filtering and jquery ui theme styling.
Jquery validation supports validating a regular select element by leaving the value attribute as an empty string for the option that is the "Placeholder" label of the select element.
http://stackoverflow.com/questions/1271640/validate-select-box
It would be great if the combobox implementation supported the same semantics. The text of the option that is the "Placeholder" label is also not shown in the combobox.
I'm pasting a minimal demo below (It includes the combobox plugin):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html style="background-color: white;"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script> <script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js"></script> <script src="http://ajax.microsoft.com/ajax/jquery.validate/1.9/additional-methods.js"></script> <link rel="stylesheet" href="jquery-ui.css"/> <style> .ui-button { margin-left: -1px; } .ui-button-icon-only .ui-button-text { padding: 0.35em; } .ui-autocomplete-input { margin: 0; padding: 0.48em 0 0.47em 0.45em; } </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'> </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 ); </script> <script> $(function() { $("#button").button(); $("#select1").combobox(); $(function() { $("#form").validate( { rules: { select0: { required: true}, select1: { required: true} }, messages: { select0: "Please select an option" } }); $("#button").click( function(event) { result = $("#form").valid(); console.log("valid: " + result); }); }); }); </script> </head> <body> <a id="button">validate</a> <form id="form"> <select id="select0" name="select0"> <option value="">Choose an option</option> <option value="option1">Option1</option> <option value="option2">Option2</option> </select> <br/> <select id="select1" name="select1"> <option value="">Choose an option</option> <option value="option1">Option1</option> <option value="option2">Option2</option> </select> </form> </body> </html>
Attachments (0)
Change History (5)
Changed November 18, 2011 04:54AM UTC by comment:1
resolution: | → invalid |
---|---|
status: | new → closed |
Changed November 18, 2011 05:31AM UTC by comment:2
Could you please point me to the location of the defined behaviour specification?
Changed November 18, 2011 05:33AM UTC by comment:3
Changed November 18, 2011 05:47AM UTC by comment:4
Aha - Thanks - I see what you mean. Do you think having it as an option would be appropriate. Something like:
$("#myselect").combobox(validation: true);
Changed November 18, 2011 05:57AM UTC by comment:5
No, you should use a select.
That's not how it should work. There's defined behavior for a combobox and the current implementation matches that.