Subversion Repositories eFlore/Archives.cel-v1

Rev

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