Subversion Repositories eFlore/Archives.cel-v1

Rev

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

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