Subversion Repositories eFlore/Archives.cel-v1

Rev

Rev 6 | Rev 8 | 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)
24
// TODO : traiter Tab (selection)
25
// TODO : revoir traitement keyup, keydown
4 ddelon 26
// TODO : reactiver le cache (du design à revoir dans ce cas la)
2 ddelon 27
 
28
import com.google.gwt.user.client.HTTPRequest;
29
import com.google.gwt.user.client.ResponseTextHandler;
30
import com.google.gwt.user.client.ui.ChangeListener;
31
import com.google.gwt.user.client.ui.KeyboardListener;
32
import com.google.gwt.user.client.ui.ListBox;
33
import com.google.gwt.user.client.ui.PopupPanel;
34
import com.google.gwt.user.client.ui.RootPanel;
35
import com.google.gwt.user.client.ui.TextBox;
36
import com.google.gwt.user.client.ui.Widget;
37
 
38
import java.util.Vector;
39
import java.util.HashMap;
40
 
41
 
42
 
43
public class AutoCompleteAsyncTextBox extends TextBox
44
    implements KeyboardListener, ChangeListener, SourcesAutoCompleteAsyncTextBoxEvents {
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);
54
  protected ListBox choices = new ListBox();
55
  protected Vector items = new Vector();
56
  protected boolean popupAdded = false;
57
  protected boolean visible = false;
6 ddelon 58
  protected String currentValue = null;
2 ddelon 59
 
4 ddelon 60
 
2 ddelon 61
  /**
62
   * Default Constructor
63
   *
64
   */
4 ddelon 65
  public AutoCompleteAsyncTextBox(ResponseTextHandler rsp)
2 ddelon 66
  {
67
    super();
4 ddelon 68
    responseTextHandler=rsp;
2 ddelon 69
    this.addKeyboardListener(this);
70
    choices.addChangeListener(this);
71
    this.setStyleName("AutoCompleteAsyncTextBox");
72
 
73
    choicesPopup.add(choices);
74
    choicesPopup.addStyleName("AutoCompleteChoices");
75
 
76
    choices.setStyleName("list");
77
 
78
  }
79
 
80
 
81
 
82
  public void addAutoCompleteAsyncTextBoxListener(AutoCompleteAsyncTextBoxListener listener) {
83
	    if (autoCompleteAsyncTextBoxListeners == null) {
84
	      autoCompleteAsyncTextBoxListeners = new AutoCompleteAsyncTextBoxListenerCollection();
85
	    }
86
	    autoCompleteAsyncTextBoxListeners.addElement(listener);
87
  }
88
 
89
 
90
 
91
  public void setSearchUrl(String url) {
92
 
93
	  this.searchUrl=url;
94
  }
95
 
96
  private void doFetchURL(String match) {
97
	  /*
98
	   * Here we fetch the URL and call the handler
99
	   */
4 ddelon 100
 
101
	  String rematch=match.replaceFirst(" ","/");
2 ddelon 102
 
103
	  if (this.searchUrl!=null && searching==false) {
104
		  searching=true;
4 ddelon 105
	      HTTPRequest.asyncGet(this.searchUrl + rematch, responseTextHandler );
2 ddelon 106
 
107
	  }
108
  }
109
 
110
 
111
  /**
112
   * Not used at all
113
   */
114
  public void onKeyDown(Widget arg0, char arg1, int arg2) {
115
  }
116
 
117
  /**
118
   * Not used at all
119
   */
120
  public void onKeyPress(Widget arg0, char arg1, int arg2) {
121
 
122
	    if(arg1 == KEY_DOWN)
123
	    {
124
	      int selectedIndex = choices.getSelectedIndex();
125
	      selectedIndex++;
126
	      if(selectedIndex >= choices.getItemCount())
127
	      {
128
	        selectedIndex = 0;
129
	      }
130
	      choices.setSelectedIndex(selectedIndex);
131
 
132
	      return;
133
	    }
134
 
135
	    if(arg1 == KEY_UP)
136
	    {
137
	      int selectedIndex = choices.getSelectedIndex();
138
	      selectedIndex--;
139
	      if(selectedIndex < 0)
140
	      {
141
	        selectedIndex = choices.getItemCount() - 1 ;
142
	      }
143
	      choices.setSelectedIndex(selectedIndex);
144
 
145
	      return;
146
	    }
147
 
148
 
149
  }
150
 
151
  /**
152
   * A key was released, start autocompletion
153
   */
154
  public void onKeyUp(Widget arg0, char arg1, int arg2) {
155
 
156
 
157
	 if(arg1 == KEY_DOWN)
158
	 {
159
		 return;
160
 
161
	 }
162
 
163
 
164
	 if(arg1 == KEY_UP)
165
	 {
166
		 return;
167
 
168
	 }
169
 
170
    if(arg1 == KEY_ENTER)
171
    {
172
      if(visible)
173
      {
174
        complete();
175
      }
176
      else {
177
    	 // Validation de l'entree :
178
          if (autoCompleteAsyncTextBoxListeners!= null) {
6 ddelon 179
              autoCompleteAsyncTextBoxListeners.fireTextBoxEnter(this,this.getText(),currentValue);
2 ddelon 180
          }
6 ddelon 181
    	  currentValue=null;
2 ddelon 182
    	  this.setText("");
183
      }
184
 
185
      return;
186
    }
187
 
188
    if(arg1 == KEY_ESCAPE)
189
    {
190
      choices.clear();
191
      items.clear();
192
      choicesPopup.hide();
193
      visible = false;
194
 
195
      return;
196
    }
197
 
198
 
199
 // Lancement appel
200
    String text = this.getText();
201
 
202
    if(text.length() > 0)
203
    {
204
      items.clear();
205
 
7 ddelon 206
      if (getFromCache(text)!=null) {
2 ddelon 207
    	  items=getFromCache(text);
208
    	  displayList();
209
      }
7 ddelon 210
      else {
211
 
2 ddelon 212
    	  this.doFetchURL(text);
7 ddelon 213
      }
2 ddelon 214
    }
215
  }
216
 
217
 
218
  // Display assistant
219
 
220
    public void displayList() {
221
 
222
    	searching=false;
223
	    if(this.items.size() > 0)
224
	    {
225
 
7 ddelon 226
	      addToCache(this.getText(),(Vector) items.clone());
2 ddelon 227
 
228
	      choices.clear();
229
 
230
	      for(int i = 0; i < items.size(); i++)
231
	      {
6 ddelon 232
	        choices.addItem(((String [])items.get(i))[0],((String [])items.get(i))[1]);
2 ddelon 233
	      }
234
 
235
 
236
	      // if there is only one match and it is what is in the
237
	      // text field anyways there is no need to show autocompletion
6 ddelon 238
	      if(items.size() == 1 && (((String []) items.get(0))[0]).compareTo(this.getText()) == 0)
2 ddelon 239
	      {
240
	        choicesPopup.hide();
241
	      } else {
242
	        choices.setSelectedIndex(0);
243
	        choices.setVisibleItemCount(items.size());
244
 
245
	        if(!popupAdded)
246
	        {
247
	          RootPanel.get().add(choicesPopup);
248
	          popupAdded = true;
249
	        }
250
	        choicesPopup.show();
251
	        visible = true;
252
	        choicesPopup.setPopupPosition(this.getAbsoluteLeft(),
253
	        this.getAbsoluteTop() + this.getOffsetHeight());
254
	        //choicesPopup.setWidth(this.getOffsetWidth() + "px");
255
	        choices.setWidth(this.getOffsetWidth() + "px");
256
	      }
257
 
258
	    } else {
259
	      visible = false;
260
	      choicesPopup.hide();
261
	    }
262
	  }
263
 
264
  /**
265
   * A mouseclick in the list of items
266
   */
267
  public void onChange(Widget arg0) {
268
    complete();
269
  }
270
 
271
  public void onClick(Widget arg0) {
272
    complete();
273
  }
274
 
275
  // add selected item to textbox
276
  protected void complete()
277
  {
278
    if(choices.getItemCount() > 0)
279
    {
280
      this.setText(choices.getItemText(choices.getSelectedIndex()));
6 ddelon 281
      currentValue=choices.getValue(choices.getSelectedIndex());
2 ddelon 282
    }
283
 
284
    visible=false;
285
    items.clear();
286
    choices.clear();
287
    choicesPopup.hide();
288
  }
289
 
290
 
6 ddelon 291
  public void addItem(String item, String value) {
292
	  items.add(new String [] {item, value});
2 ddelon 293
  }
294
 
295
  private void addToCache (String query, Vector result)
296
  {
297
	cache.put(query.toLowerCase(),result);
298
  }
299
 
300
  private Vector getFromCache (String query)
301
  {
302
	return (Vector) cache.get(query.toLowerCase());
303
  }
304
 
305
 
306
 
307
 
308
}
309