Subversion Repositories eFlore/Archives.cel-v1

Rev

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