Subversion Repositories eFlore/Archives.cel-v1

Rev

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

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