Subversion Repositories eFlore/Archives.cel-v1

Rev

Rev 28 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 ddelon 1
/*
2
Auto-Completion Textbox for GWT
3
Copyright (C) 2006 Oliver Albers http://gwt.components.googlepages.com/
4
 
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
9
 
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
14
 
15
You should have received a copy of the GNU Lesser General Public
16
License along with this library; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
 
19
*/
20
package org.tela_botanica.client;
21
 
22
 
27 ddelon 23
// TODO : traiter latence (augmenter en fonction rapidit� saisie + texte vide)
8 ddelon 24
// TODO : traitement espace apres l'espece (%20)
28 ddelon 25
// TODO : Utiliser Suggestbox et les Associating Data Transfer Objects (DTOs) with Suggestion Objects
2 ddelon 26
 
27
import com.google.gwt.user.client.HTTPRequest;
28
import com.google.gwt.user.client.ResponseTextHandler;
29
import com.google.gwt.user.client.ui.KeyboardListener;
30
import com.google.gwt.user.client.ui.ListBox;
31
import com.google.gwt.user.client.ui.PopupPanel;
32
import com.google.gwt.user.client.ui.TextBox;
33
import com.google.gwt.user.client.ui.Widget;
8 ddelon 34
import com.google.gwt.user.client.DOM;
35
import com.google.gwt.user.client.Event;
2 ddelon 36
 
37
import java.util.Vector;
38
import java.util.HashMap;
39
 
40
 
41
 
42
public class AutoCompleteAsyncTextBox extends TextBox
8 ddelon 43
    implements KeyboardListener, SourcesAutoCompleteAsyncTextBoxEvents {
2 ddelon 44
 
45
  private String searchUrl = null;
46
  private AutoCompleteAsyncTextBoxListenerCollection autoCompleteAsyncTextBoxListeners=null;
47
 
48
  private HashMap cache = new HashMap();
49
  private boolean searching = false;
4 ddelon 50
  private ResponseTextHandler responseTextHandler=null;
2 ddelon 51
 
52
  protected PopupPanel choicesPopup = new PopupPanel(true);
8 ddelon 53
  protected ListBox choices = new ListBox() {
54
	  public void onBrowserEvent(Event event) {
55
		  if (Event.ONCLICK == DOM.eventGetType(event)) {
56
			  complete();
57
		  }
58
	  }
59
  };
2 ddelon 60
  protected Vector items = new Vector();
61
  protected boolean visible = false;
10 ddelon 62
 
63
  /**
64
   * Value linked to current text
65
   */
6 ddelon 66
  protected String currentValue = null;
8 ddelon 67
 
2 ddelon 68
 
4 ddelon 69
 
2 ddelon 70
  /**
71
   * Default Constructor
72
   *
73
   */
4 ddelon 74
  public AutoCompleteAsyncTextBox(ResponseTextHandler rsp)
2 ddelon 75
  {
76
    super();
4 ddelon 77
    responseTextHandler=rsp;
2 ddelon 78
    this.addKeyboardListener(this);
8 ddelon 79
    choices.sinkEvents(Event.ONCLICK);
2 ddelon 80
    this.setStyleName("AutoCompleteAsyncTextBox");
81
 
82
    choicesPopup.add(choices);
83
    choicesPopup.addStyleName("AutoCompleteChoices");
84
 
85
    choices.setStyleName("list");
86
 
87
  }
88
 
89
 
90
 
91
  public void addAutoCompleteAsyncTextBoxListener(AutoCompleteAsyncTextBoxListener listener) {
92
	    if (autoCompleteAsyncTextBoxListeners == null) {
93
	      autoCompleteAsyncTextBoxListeners = new AutoCompleteAsyncTextBoxListenerCollection();
94
	    }
95
	    autoCompleteAsyncTextBoxListeners.addElement(listener);
96
  }
97
 
98
 
99
 
100
  public void setSearchUrl(String url) {
101
 
102
	  this.searchUrl=url;
103
  }
104
 
105
  private void doFetchURL(String match) {
106
	  /*
107
	   * Here we fetch the URL and call the handler
108
	   */
26 ddelon 109
 
110
 
9 ddelon 111
	  String rematch=match.replaceAll(" ","/");
112
	  rematch=rematch.replaceAll("%","");
2 ddelon 113
 
114
	  if (this.searchUrl!=null && searching==false) {
115
		  searching=true;
9 ddelon 116
	 //     HTTPRequest.asyncGet(URL.encodeComponent(this.searchUrl) + rematch, responseTextHandler );
4 ddelon 117
	      HTTPRequest.asyncGet(this.searchUrl + rematch, responseTextHandler );
2 ddelon 118
 
119
	  }
120
  }
121
 
122
 
123
  public void onKeyDown(Widget arg0, char arg1, int arg2) {
8 ddelon 124
 
125
 
126
	  if(arg1 == KEY_ENTER)
2 ddelon 127
	    {
8 ddelon 128
	      enterKey(arg0, arg1, arg2);
2 ddelon 129
	    }
8 ddelon 130
	    else if(arg1 == KEY_DOWN)
2 ddelon 131
	    {
8 ddelon 132
	      downKey(arg0, arg1, arg2);
2 ddelon 133
	    }
8 ddelon 134
	    else if(arg1 == KEY_UP)
135
	    {
136
	      upKey(arg0, arg1, arg2);
137
	    }
138
	    else if(arg1 == KEY_ESCAPE)
139
	    {
140
	      escapeKey(arg0, arg1, arg2);
141
	    }
142
 
2 ddelon 143
 
8 ddelon 144
  }
2 ddelon 145
  /**
8 ddelon 146
   * Not used at all (probleme avec ie, qui ne comprend pas les touches meta)
2 ddelon 147
   */
8 ddelon 148
  public void onKeyPress(Widget arg0, char arg1, int arg2) {
149
 
2 ddelon 150
 
8 ddelon 151
  }
152
 
153
  // The down key was pressed.
154
  protected void downKey(Widget arg0, char arg1, int arg2) {
155
 
156
	    int selectedIndex = choices.getSelectedIndex();
157
	    selectedIndex++;
158
	    if (selectedIndex >= choices.getItemCount())
159
	    {
160
	      selectedIndex = 0;
161
	    }
162
	    choices.setSelectedIndex(selectedIndex);
163
 }
2 ddelon 164
 
8 ddelon 165
  // The up key was pressed.
166
  protected void upKey(Widget arg0, char arg1, int arg2) {
167
    int selectedIndex = choices.getSelectedIndex();
168
    selectedIndex--;
169
    if(selectedIndex < 0)
170
    {
171
      selectedIndex = choices.getItemCount() - 1;
172
    }
173
    choices.setSelectedIndex(selectedIndex);
174
  }
2 ddelon 175
 
8 ddelon 176
  // The enter key was pressed.
177
  protected void enterKey(Widget arg0, char arg1, int arg2) {
2 ddelon 178
      if(visible)
179
      {
180
        complete();
181
      }
182
      else {
8 ddelon 183
    	 // Validation de l'entree : appel asynchrone
2 ddelon 184
          if (autoCompleteAsyncTextBoxListeners!= null) {
6 ddelon 185
              autoCompleteAsyncTextBoxListeners.fireTextBoxEnter(this,this.getText(),currentValue);
2 ddelon 186
          }
6 ddelon 187
    	  currentValue=null;
2 ddelon 188
    	  this.setText("");
29 ddelon 189
    	  this.setValue(null);
2 ddelon 190
      }
8 ddelon 191
 
192
  }
193
 
194
//The escape key was pressed.
195
  protected void escapeKey(Widget arg0, char arg1, int arg2) {
196
    choices.clear();
197
    items.clear();
198
    choicesPopup.hide();
199
    visible = false;
200
 
201
  }
202
 
203
 
204
  // Any other non-special key was pressed.
205
  protected void otherKey(Widget arg0, char arg1, int arg2) {
2 ddelon 206
 
8 ddelon 207
 
208
    // Lancement appel
2 ddelon 209
    String text = this.getText();
210
 
8 ddelon 211
 
212
	    if(text.length() > 0)
213
	    {
214
 
29 ddelon 215
	    	  currentValue=null;
216
 
8 ddelon 217
		      items.clear();
218
 
219
		      if (getFromCache(text)!=null) {
220
		    	  items=getFromCache(text);
221
		    	  displayList();
222
		      }
223
		      else {
224
 
225
		    	  this.doFetchURL(text);
226
		      }
227
		 }
228
 
229
 
230
 
231
 
232
  }
233
 
234
  public void onKeyUp(Widget arg0, char arg1, int arg2) {
235
 
236
	  switch(arg1) {
237
      case KEY_ALT:
238
      case KEY_CTRL:
239
      case KEY_DOWN:
240
      case KEY_END:
241
      case KEY_ENTER:
242
      case KEY_ESCAPE:
243
      case KEY_HOME:
244
      case KEY_LEFT:
245
      case KEY_PAGEDOWN:
246
      case KEY_PAGEUP:
247
      case KEY_RIGHT:
248
      case KEY_SHIFT:
249
      case KEY_TAB:
250
      case KEY_UP:
251
        break;
252
      default:
253
        otherKey(arg0, arg1, arg2);
254
        break;
2 ddelon 255
    }
8 ddelon 256
 
2 ddelon 257
  }
258
 
259
 
260
  // Display assistant
261
 
262
    public void displayList() {
263
 
264
    	searching=false;
265
	    if(this.items.size() > 0)
266
	    {
267
 
7 ddelon 268
	      addToCache(this.getText(),(Vector) items.clone());
2 ddelon 269
 
270
	      choices.clear();
271
 
272
	      for(int i = 0; i < items.size(); i++)
273
	      {
6 ddelon 274
	        choices.addItem(((String [])items.get(i))[0],((String [])items.get(i))[1]);
2 ddelon 275
	      }
276
 
277
 
278
	      // if there is only one match and it is what is in the
279
	      // text field anyways there is no need to show autocompletion
8 ddelon 280
	    //  if(items.size() == 1 && (((String []) items.get(0))[0]).compareTo(this.getText()) == 0)
281
	     // {
282
	       // choicesPopup.hide();
283
	     // } else {
2 ddelon 284
	        choices.setSelectedIndex(0);
285
	        choices.setVisibleItemCount(items.size());
286
 
28 ddelon 287
 
2 ddelon 288
	        visible = true;
28 ddelon 289
	        choicesPopup.setPopupPosition(this.getAbsoluteLeft(), this.getAbsoluteTop() + this.getOffsetHeight());
290
	        choicesPopup.setPopupPosition(this.getAbsoluteLeft(), this.getAbsoluteTop() + this.getOffsetHeight());
8 ddelon 291
	        choicesPopup.setWidth(this.getOffsetWidth() + "px");
2 ddelon 292
	        choices.setWidth(this.getOffsetWidth() + "px");
28 ddelon 293
 
294
	        choicesPopup.show();
295
 
8 ddelon 296
	    //  }
2 ddelon 297
 
298
	    } else {
299
	      visible = false;
300
	      choicesPopup.hide();
301
	    }
302
	  }
303
 
304
  /**
305
   * A mouseclick in the list of items
306
   */
307
  public void onChange(Widget arg0) {
308
    complete();
309
  }
8 ddelon 310
 
2 ddelon 311
 
312
  public void onClick(Widget arg0) {
313
    complete();
314
  }
315
 
316
  // add selected item to textbox
317
  protected void complete()
318
  {
25 ddelon 319
 
320
 
2 ddelon 321
    if(choices.getItemCount() > 0)
322
    {
323
      this.setText(choices.getItemText(choices.getSelectedIndex()));
6 ddelon 324
      currentValue=choices.getValue(choices.getSelectedIndex());
25 ddelon 325
      if (autoCompleteAsyncTextBoxListeners!= null) {
326
          autoCompleteAsyncTextBoxListeners.fireTextBoxComplete(responseTextHandler,this.getText(),currentValue);
327
      }
2 ddelon 328
    }
329
 
330
    visible=false;
331
    items.clear();
332
    choices.clear();
333
    choicesPopup.hide();
334
  }
335
 
336
 
6 ddelon 337
  public void addItem(String item, String value) {
338
	  items.add(new String [] {item, value});
2 ddelon 339
  }
340
 
341
  private void addToCache (String query, Vector result)
342
  {
343
	cache.put(query.toLowerCase(),result);
344
  }
345
 
346
  private Vector getFromCache (String query)
347
  {
348
	return (Vector) cache.get(query.toLowerCase());
349
  }
10 ddelon 350
 
351
 
352
 
353
public String getValue() {
354
	return currentValue;
355
}
2 ddelon 356
 
357
 
13 ddelon 358
public  void setValue(String value) {
359
	 this.currentValue=value;
360
}
361
 
2 ddelon 362
 
363
}
364