Subversion Repositories eFlore/Archives.cel-v1

Rev

Rev 9 | Rev 12 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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