Subversion Repositories eFlore/Applications.cel

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2602 aurelien 1
package org.tela_botanica.client.util.autocompletion;
2
 
3
import java.util.ArrayList;
4
import java.util.Iterator;
5
import java.util.List;
6
import java.util.Map;
7
 
8
import org.tela_botanica.client.cel2;
9
import org.tela_botanica.client.modeles.objets.Utilisateur;
10
 
11
import com.google.gwt.core.client.Callback;
12
import com.google.gwt.core.client.JavaScriptObject;
13
import com.google.gwt.event.dom.client.KeyCodes;
14
import com.google.gwt.event.dom.client.KeyDownEvent;
15
import com.google.gwt.event.dom.client.KeyDownHandler;
16
import com.google.gwt.event.dom.client.KeyPressEvent;
17
import com.google.gwt.event.dom.client.KeyPressHandler;
18
import com.google.gwt.event.logical.shared.SelectionEvent;
19
import com.google.gwt.event.logical.shared.SelectionHandler;
20
import com.google.gwt.event.logical.shared.ValueChangeEvent;
21
import com.google.gwt.event.logical.shared.ValueChangeHandler;
22
import com.google.gwt.http.client.Request;
23
import com.google.gwt.http.client.RequestBuilder;
24
import com.google.gwt.http.client.RequestCallback;
25
import com.google.gwt.http.client.RequestException;
26
import com.google.gwt.http.client.Response;
27
import com.google.gwt.http.client.URL;
28
import com.google.gwt.user.client.Event;
29
import com.google.gwt.user.client.Timer;
30
import com.google.gwt.user.client.Window;
31
import com.google.gwt.user.client.ui.ChangeListener;
32
import com.google.gwt.user.client.ui.Label;
33
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
34
import com.google.gwt.user.client.ui.SuggestBox;
35
import com.google.gwt.user.client.ui.SuggestBox.DefaultSuggestionDisplay;
36
import com.google.gwt.user.client.ui.TextBox;
37
import com.google.gwt.user.client.ui.SuggestBox.SuggestionDisplay;
38
import com.google.gwt.user.client.ui.SuggestOracle;
39
import com.google.gwt.user.client.ui.Widget;
40
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
41
import com.gwtext.client.widgets.BoxComponent;
42
import com.gwtext.client.widgets.Component;
43
import com.gwtext.client.widgets.Container;
44
import com.gwtext.client.widgets.Panel;
45
import com.gwtext.client.widgets.event.PanelListener;
46
import com.gwtext.client.widgets.event.PanelListenerAdapter;
47
import com.gwtext.client.widgets.layout.FitLayout;
48
 
49
@SuppressWarnings("unchecked")
50
public abstract class AutoCompletionComboBox extends Panel {
51
 
52
	Label label = null;
53
	MultiWordSuggestOracle msu = null;
54
	SuggestBox suggestions = null;
55
	DefaultSuggestionDisplay sgd = null;
56
 
57
	Callback<String, String> surCopierColler = null;
58
 
59
	SuggestOracle.Request requeteOracle;
60
    SuggestOracle.Callback callBackOracle;
61
 
62
	Timer suggestionTimer = null;
63
    int tempsAvantRequete = 500;
64
 
65
    Map<String, String> possibilites = null;
66
 
67
    String urlRequete = "";
68
 
69
	public AutoCompletionComboBox(String nomLabel, String urlRequete) {
70
 
71
		this.setStyleName("champAutoComplete");
72
 
73
		this.label = new Label(nomLabel+":");
74
		this.urlRequete = urlRequete;
75
 
76
		sgd = new SuggestBox.DefaultSuggestionDisplay();
77
		msu = new MultiWordSuggestOracle() {
78
			@Override
79
			public void requestSuggestions(Request request, Callback callback) {
80
				List<MultiWordSuggestion> retenus = new ArrayList<MultiWordSuggestion>();
81
				Iterator<String> it = possibilites.keySet().iterator();
82
			    while (it.hasNext()) {
83
			    	String cle = it.next();
84
					MultiWordSuggestion muWoSug = new MultiWordSuggestion(possibilites.get(cle), possibilites.get(cle));
85
					retenus.add(muWoSug);
86
			    }
87
 
88
				Response reponse = new Response(retenus);
89
				callback.onSuggestionsReady(request, reponse);
90
			}
91
		};
92
 
93
		suggestions = new SuggestBox(msu, new TextBox(), sgd) {
94
			public void onBrowserEvent(Event event) {
95
			    switch (event.getTypeInt()) {
96
			        case Event.ONPASTE: {
97
			        	if(surCopierColler != null) {
98
			        		surCopierColler.onSuccess(suggestions.getValueBox().getValue());
99
			        	}
100
			        }
101
			        break;
102
			        default:
103
			        	super.onBrowserEvent(event);
104
			    }
105
 
106
			}
107
		};
108
 
109
		suggestions.setAutoSelectEnabled(false);
110
		setLayout(new FitLayout());
111
		add(label);
112
		add(suggestions);
113
		gererEvenements();
114
	}
115
 
116
	public void gererEvenements() {
117
		suggestions.addKeyDownHandler(new KeyDownHandler() {
118
 
119
		    @Override
120
		    public void onKeyDown(KeyDownEvent event) {
121
		    	// Lorsque la liste de suggestions est ouverte, une frappe sur entrée selectionne la valeur
122
		    	// Si elle est fermée, elle déclenche la fonction abstraite de validation (utile pour les champs
123
		    	// du genre station, milieu etc... et la saisie d'obs rapide
124
				if(event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
125
					if((sgd == null || !sgd.isSuggestionListShowing())) {
126
						onValidationSaisie();
127
						event.stopPropagation();
128
						return;
129
					} else {
130
						// Dans les autres cas, un appui sur entrée ne doit pas redéclencher l'autcomplétion
131
						return;
132
					}
133
				}
134
 
135
				// Tout autre frappe d'un caractère "normal" déclenche le timer d'autocomplétion
136
				if(!KeyDownEvent.isArrow(event.getNativeKeyCode())) {
137
					gererTimer();
138
				}
139
		    }
140
 
141
		});
142
 
143
		requeteOracle = new SuggestOracle.Request();
144
		callBackOracle = new SuggestOracle.Callback() {
145
 
146
			public void onSuggestionsReady(SuggestOracle.Request request, SuggestOracle.Response response) {
147
				suggestions.showSuggestionList();
148
			}
149
	    };
150
 
151
	    suggestions.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>(){
152
			@Override
153
			public void onSelection(SelectionEvent<Suggestion> event) {
154
				onSelectionValeur();
155
			}
156
		});
157
 
158
	    suggestions.addValueChangeHandler(new ValueChangeHandler<String>() {
159
			@Override
160
			public void onValueChange(ValueChangeEvent<String> event) {
161
				onModificationValeur();
162
			}
163
		});
164
 
165
	    surCopierColler = new Callback<String, String>() {
166
			@Override
167
			public void onSuccess(String result) {
168
				gererTimer();
169
			}
170
 
171
			@Override
172
			public void onFailure(String reason) {
173
				// rien à faire ça n'échoue jamais
174
			}
175
		};
176
 
177
		addListener(new PanelListenerAdapter() {
178
 
179
			@Override
180
			public void onResize(BoxComponent component, int adjWidth, int adjHeight,
181
					int rawWidth, int rawHeight) {
182
				redimensionner(rawWidth);
183
			}
184
		});
185
	}
186
 
187
	public void redimensionner(final int largeur) {
188
		suggestions.setWidth((largeur - label.getOffsetWidth() - 13)+"px");
189
	}
190
 
191
	public void gererTimer() {
192
		if(suggestionTimer == null) {
193
			suggestionTimer = new Timer() {
194
				public void run() {
195
					requeteSuggestions();
196
				}
197
			};
198
			suggestionTimer.schedule(tempsAvantRequete);
199
		} else {
200
			suggestionTimer.schedule(tempsAvantRequete);
201
		}
202
	}
203
 
204
	public void setTempsAvantRequete(int temps) {
205
		tempsAvantRequete = temps;
206
	}
207
 
208
	public int getTempsAvantRequete(int temps) {
209
		return tempsAvantRequete;
210
	}
211
 
212
	public void requeteSuggestions() {
213
 
214
		// Suppression des espaces et caractères inutiles
215
		String valeur = suggestions.getValue().trim().isEmpty() ? "*" : suggestions.getValue().trim();
216
		final String requeteAjax = URL.encodeQueryString(valeur);
217
 
218
		// ceci permet au composant qui utilise l'autocomplétion
219
		// d'annuler une requete
220
		if(requeteAjax == null) {
221
			return;
222
		}
223
 
224
		String urlRequeteUtil = urlRequete.replace("{utilisateur}", Utilisateur.getInstance().getIdentifiantUtilisateurConsulte());
225
		String urlProxy = urlRequeteUtil+requeteAjax;
226
 
227
		RequestBuilder rb = new RequestBuilder(RequestBuilder.GET, urlProxy) ;
228
		try {
229
			rb.sendRequest(null, new RequestCallback() {
230
				public void onError(final Request request, final Throwable exception) {
231
					// TODO Auto-generated method stub
232
				}
233
 
234
				public void onResponseReceived(final Request request,
235
						final Response response) {
236
					surReponseRequete(requeteAjax, response);
237
				}
238
			}) ;
239
 
240
		} catch (RequestException e) {
241
			// TODO Auto-generated catch block
242
			e.printStackTrace();
243
		}
244
	}
245
 
246
	public void surReponseRequete(String requete, Response response) {
247
		possibilites = parserResultatRequete(response);
248
		msu.clear();
249
		Iterator<String> it = possibilites.keySet().iterator();
250
	    while (it.hasNext()) {
251
	    	msu.add(possibilites.get(it.next()));
252
	    }
253
 
254
		requeteOracle.setQuery(requete);
255
		msu.requestSuggestions(requeteOracle, callBackOracle);
256
	}
257
 
258
	public String getText() {
259
		return suggestions.getText();
260
	}
261
 
262
	public String getRawValue() {
263
		return suggestions.getText();
264
	}
265
 
266
	public void setValue(String texte) {
267
		suggestions.setText(texte);
268
	}
269
 
270
	public void reset() {
271
		suggestions.setValue("");
272
	}
273
 
274
	public void setTabIndex(int index) {
275
		suggestions.setTabIndex(index);
276
	}
277
 
278
	protected abstract Map<String, String> parserResultatRequete(Response response);
279
	protected abstract void onModificationValeur();
280
	protected abstract void onSelectionValeur();
281
	protected abstract void onValidationSaisie();
282
}