JAL-1807 update
[jalviewjs.git] / site / swingjs / jquery / jquery-ui-cb.js
1 /*
2 adapted from jquery ui example
3
4 SwingJS[1] options include:
5
6     id          id to report
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)
10
11 SwingJS[2] ensure caret is not left in box after selection if readOnly
12
13 SwingJS[3] do not remove entered value if invalid
14
15 SwingJS[4] match only starting points using regex '^'
16
17 SwingJS[5] Tooltips removed
18          
19 SwingJS[6] ENTER action accepted for any value
20
21
22  */
23
24
25         (function( $ ) {
26
27   
28                 $.widget( "custom.swingjs_combobox", {
29                         _create: function() {
30
31 // SwingJS[1]
32             
33       this.n  = this.options.n || (this.options.n = 5);
34       this.readOnly = this.options.readOnly;
35       this.actionListener = this.options.actionListener || null;
36       
37       this.id = this.options.id || "<noid>";      
38             
39             
40                                 this.wrapper = $( "<div>" )
41           .insertAfter( this.element )
42           .addClass( "custom-swingjs_combobox" );
43      
44                     
45                                 this.element.hide();
46                                 this._createAutocomplete();
47                                 this._createShowAllButton();
48                         },
49
50                         _createAutocomplete: function() {
51                                 var selected = this.element.children( ":selected" ),
52                                         value = selected.val() ? selected.text() : "";
53
54         var self = this;
55         
56                                 this.input = $( "<input>" )
57                                         .appendTo( this.wrapper )
58                                         .val( value )
59                                         .attr( "title", "" )
60                                         .addClass( "custom-swingjs_combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
61                                         .autocomplete({
62                                                 delay: 0,
63                                                 minLength: 0,
64                                                 source: $.proxy( this, "_source" )
65                                         })
66           .keypress(function(event){
67 // SwingJS[6]          
68             if(event.which == 13 && self.actionListener) {
69               self.input.data("autocomplete").widget().hide();
70               self.actionListener(self.id, self, "enterPressed", self.input.val());
71               
72             }
73           });
74
75 //SwingJS[1]
76
77         if (this.readOnly)
78           this.input.attr("readOnly",true);
79           
80         this.input.data("autocomplete").widget().css({height:(this.n*1.67) + "em"})
81         
82 //SwingJS[5]
83
84   //                                    .tooltip({
85         //                                      tooltipClass: "ui-state-highlight"
86   //                    })
87
88         var al = this.actionListener
89         
90                                 this._on( this.input, {
91                                         autocompleteselect: function( event, ui ) {
92                                                 ui.item.option.selected = true;
93                                                 this._trigger( "select", event, {
94                                                         item: ui.item.option
95                                                 });
96
97 // SwingJS[1]
98             if (al) {
99               al(self.id, self, "selected", ui.item.option.text);
100             }
101       
102 // SwingJS[2]
103                                                 if (this.readOnly) 
104               this.input.blur()
105             
106                                         },
107
108 // SwingJS[2]
109           focus: function(){if (this.readOnly){this.input.blur()}},
110                                         autocompletechange: "_removeIfInvalid"
111                                 });
112                         },
113
114                         _createShowAllButton: function() {
115                                 var input = this.input,
116                                         wasOpen = false;
117
118                                 this.btn = $( "<a>" )
119                                         .attr( "tabIndex", -1 )
120                                         .attr( "title", "Show All Items" )
121 //                                      .tooltip()
122                                         .appendTo( this.wrapper )
123                                         .button({
124                                                 icons: {
125                                                         primary: "ui-icon-triangle-1-s"
126                                                 },
127                                                 text: false
128                                         })
129                                         .removeClass( "ui-corner-all" )
130                                         .addClass( "custom-swingjs_combobox-toggle ui-corner-right" )
131                                         .mousedown(function() {
132                                                 wasOpen = input.autocomplete( "widget" ).is( ":visible" );
133                                         })
134                                         .click(function() {
135               input.focus();
136
137                                                 // Close if already visible
138                                                 if ( wasOpen ) {
139                                                         return;
140                                                 }
141
142                                                 // Pass empty string as value to search for, displaying all results
143                                                 input.autocomplete( "search", "" );
144                                         });
145                         },
146
147                         _source: function( request, response ) {
148
149 // SwingJS[4] 
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) ) )
154                                                 return {
155                                                         label: text,
156                                                         value: text,
157                                                         option: this
158                                                 };
159                                 }) );
160                         },
161
162                         _removeIfInvalid: function( event, ui ) {
163
164           
165 // SwingJS[3]
166
167                                 // Selected an item, nothing to do
168                                 if ( ui.item ) {
169                                         return;
170                                 }
171
172                                 // Search for a match (case-insensitive)
173                                 var value = this.input.val(),
174                                         valueLowerCase = value.toLowerCase(),
175                                         valid = false;
176                                 this.element.children( "option" ).each(function() {
177                                         if ( $( this ).text().toLowerCase() === valueLowerCase ) {
178                                                 this.selected = valid = true;
179                                                 return false;
180                                         }
181                                 });
182
183                                 // Found a match, nothing to do
184                                 if ( valid ) {
185                                         return;
186                                 }
187
188           
189 // SwingJS[3]
190 /*
191                                 // Remove invalid value
192                                 this.input
193                                         .val( "" );
194                                         .attr( "title", value + " didn't match any item" )
195                                         .tooltip( "open" );
196
197                                 this.element.val( "" );
198
199                                 this._delay(function() {
200                                         this.input.tooltip( "close" ).attr( "title", "" );
201                                 }, 2500 );
202         
203                                 this.input.autocomplete( "instance" ).term = "";
204 */
205                         },
206                         _destroy: function() {
207                                 this.wrapper.remove();
208                                 this.element.show();
209                         }
210                 });
211         })( jQuery );