(function( $ ) {
$.widget( "ui.combobox", {
_create: function() {
- var input,
- that = this,
- wasOpen = false,
- select = this.element.hide(),
- selected = select.children( ":selected" ),
- value = selected.val() ? selected.text() : "",
- wrapper = this.wrapper = $( "<span>" )
- .addClass( "ui-combobox" )
- .insertAfter( select );
-
- function removeIfInvalid( element ) {
- var value = $( element ).val().toLowerCase(),
- valid = false;
- select.children( "option" ).each(function() {
- if ( $( this ).text().toLowerCase() === value ) {
- this.selected = valid = true;
- return false;
- }
- });
+ this.wrapper = $( "<span>" )
+ .addClass( "ui-combobox" )
+ .insertAfter( this.element );
- if ( !valid ) {
- // remove invalid value, as it didn't match anything
- $( element )
- .val( "" )
- .attr( "title", value + " didn't match any item" )
- .tooltip( "open" );
- select.val( "" );
- setTimeout(function() {
- input.tooltip( "close" ).attr( "title", "" );
- }, 2500 );
- input.data( "ui-autocomplete" ).term = "";
- }
- }
+ this._createAutocomplete();
+ this._createShowAllButton();
+ },
+
+ _createAutocomplete: function() {
+ var selected = this.element.children( ":selected" ),
+ value = selected.val() ? selected.text() : "";
- input = $( "<input>" )
- .appendTo( wrapper )
+ this.input = $( "<input>" )
+ .appendTo( this.wrapper )
.val( value )
.attr( "title", "" )
- .addClass( "ui-state-default ui-combobox-input" )
+ .addClass( "ui-state-default ui-combobox-input ui-widget ui-widget-content ui-corner-left" )
.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,
- value: text,
- option: this
- };
- }) );
- },
- select: function( event, ui ) {
- ui.item.option.selected = true;
- that._trigger( "select", event, {
- item: ui.item.option
- });
- },
- change: function( event, ui ) {
- if ( !ui.item ) {
- removeIfInvalid( this );
- }
- }
+ source: $.proxy( this, "_source" )
})
- .addClass( "ui-widget ui-widget-content ui-corner-left" );
+ .tooltip({
+ tooltipClass: "ui-state-highlight"
+ });
+
+ this._on( this.input, {
+ autocompleteselect: function( event, ui ) {
+ ui.item.option.selected = true;
+ this._trigger( "select", event, {
+ item: ui.item.option
+ });
+ },
+
+ autocompletechange: "_removeIfInvalid"
+ });
+ },
+
+ _createShowAllButton: function() {
+ var wasOpen = false;
$( "<a>" )
.attr( "tabIndex", -1 )
.attr( "title", "Show All Items" )
.tooltip()
- .appendTo( wrapper )
+ .appendTo( this.wrapper )
.button({
icons: {
primary: "ui-icon-triangle-1-s"
.click(function() {
input.focus();
- // close if already visible
+ // Close if already visible
if ( wasOpen ) {
return;
}
- // pass empty string as value to search for, displaying all results
+ // Pass empty string as value to search for, displaying all results
input.autocomplete( "search", "" );
});
+ },
+
+ _source: function( request, response ) {
+ var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
+ response( this.element.children( "option" ).map(function() {
+ var text = $( this ).text();
+ if ( this.value && ( !request.term || matcher.test(text) ) )
+ return {
+ label: text,
+ value: text,
+ option: this
+ };
+ }) );
+ },
+
+ _removeIfInvalid: function( event, ui ) {
- input.tooltip({
- tooltipClass: "ui-state-highlight"
+ // Selected an item, nothing to do
+ if ( ui.item ) {
+ return;
+ }
+
+ // Search for a match (case-insensitive)
+ var value = this.input.val(),
+ valueLowerCase = value.toLowerCase(),
+ valid = false;
+ this.element.children( "option" ).each(function() {
+ if ( $( this ).text().toLowerCase() === valueLowerCase ) {
+ this.selected = valid = true;
+ return false;
+ }
});
+
+ // Found a match, nothing to do
+ if ( valid ) {
+ return;
+ }
+
+ // Remove invalid value
+ this.input
+ .val( "" )
+ .attr( "title", value + " didn't match any item" )
+ .tooltip( "open" );
+ this.element.val( "" );
+ this._delay(function() {
+ this.input.tooltip( "close" ).attr( "title", "" );
+ }, 2500 );
+ this.input.data( "ui-autocomplete" ).term = "";
},
_destroy: function() {