2 adapted from jquery ui example
4 SwingJS[1] options include:
7 n number of visible fields
8 readonly no input focus; no editing
9 actionListener function to call on ENTER or select as f(id, this, "selected" or "enterPressed", this.value)
11 SwingJS[2] ensure caret is not left in box after selection if readOnly
13 SwingJS[3] do not remove entered value if invalid
15 SwingJS[4] match only starting points using regex '^'
17 SwingJS[5] Tooltips removed
19 SwingJS[6] ENTER action accepted for any value
28 $.widget( "custom.swingjs_combobox", {
33 this.n = this.options.n || (this.options.n = 5);
34 this.readOnly = this.options.readOnly;
35 this.actionListener = this.options.actionListener || null;
37 this.id = this.options.id || "<noid>";
40 this.wrapper = $( "<div>" )
41 .insertAfter( this.element )
42 .addClass( "custom-swingjs_combobox" );
46 this._createAutocomplete();
47 this._createShowAllButton();
50 _createAutocomplete: function() {
51 var selected = this.element.children( ":selected" ),
52 value = selected.val() ? selected.text() : "";
56 this.input = $( "<input>" )
57 .appendTo( this.wrapper )
60 .addClass( "custom-swingjs_combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
64 source: $.proxy( this, "_source" )
66 .keypress(function(event){
68 if(event.which == 13 && self.actionListener) {
69 self.input.data("autocomplete").widget().hide();
70 self.actionListener(self.id, self, "enterPressed", self.input.val());
78 this.input.attr("readOnly",true);
80 this.input.data("autocomplete").widget().css({height:(this.n*1.67) + "em"})
85 // tooltipClass: "ui-state-highlight"
88 var al = this.actionListener
90 this._on( this.input, {
91 autocompleteselect: function( event, ui ) {
92 ui.item.option.selected = true;
93 this._trigger( "select", event, {
99 al(self.id, self, "selected", ui.item.option.text);
109 focus: function(){if (this.readOnly){this.input.blur()}},
110 autocompletechange: "_removeIfInvalid"
114 _createShowAllButton: function() {
115 var input = this.input,
118 this.btn = $( "<a>" )
119 .attr( "tabIndex", -1 )
120 .attr( "title", "Show All Items" )
122 .appendTo( this.wrapper )
125 primary: "ui-icon-triangle-1-s"
129 .removeClass( "ui-corner-all" )
130 .addClass( "custom-swingjs_combobox-toggle ui-corner-right" )
131 .mousedown(function() {
132 wasOpen = input.autocomplete( "widget" ).is( ":visible" );
137 // Close if already visible
142 // Pass empty string as value to search for, displaying all results
143 input.autocomplete( "search", "" );
147 _source: function( request, response ) {
150 var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex(request.term), "i" );
151 response( this.element.children( "option" ).map(function() {
152 var text = $( this ).text();
153 if ( this.value && ( !request.term || matcher.test(text) ) )
162 _removeIfInvalid: function( event, ui ) {
167 // Selected an item, nothing to do
172 // Search for a match (case-insensitive)
173 var value = this.input.val(),
174 valueLowerCase = value.toLowerCase(),
176 this.element.children( "option" ).each(function() {
177 if ( $( this ).text().toLowerCase() === valueLowerCase ) {
178 this.selected = valid = true;
183 // Found a match, nothing to do
191 // Remove invalid value
194 .attr( "title", value + " didn't match any item" )
197 this.element.val( "" );
199 this._delay(function() {
200 this.input.tooltip( "close" ).attr( "title", "" );
203 this.input.autocomplete( "instance" ).term = "";
206 _destroy: function() {
207 this.wrapper.remove();