Subversion Repositories eFlore/Applications.del

Rev

Rev 1957 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package org.tela_botanica.del.client.composants.formulaires.autocompletion;

import org.tela_botanica.del.client.utils.InfosNomPourAutocompletion;

import com.google.gwt.core.client.Callback;
import com.google.gwt.event.dom.client.HasKeyPressHandlers;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.logical.shared.HasSelectionHandlers;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.SuggestOracle;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;

public abstract class AutoCompletionComboBoxPresenteur {
        
        public interface Vue extends IsWidget {
                public void ajouterVue(HasWidgets composite);
                public HasKeyPressHandlers getSuggestBoxHasKeyPressHandlers();
                public String getValeur();
                public void remplirListe(InfosNomPourAutocompletion[] suggestions);
                public void afficherSuggestions(SuggestOracle.Request request,SuggestOracle.Callback response);
                public void afficherListeDeroulante();
                public void nettoyer();
                public void setValeur(String valeur);
                public HasSelectionHandlers<Suggestion> getSuggestBoxHasSelectionChangeHandlers();
                public HasText getSuggestBox();
                public void afficherStyleErreur(String styleErreur);
                public void supprimerStyleErreur(String styleErreur);
                public void setHandlerCopierColler(Callback<String, String> cb);
        }
        private Vue autoCompletionComboBoxVue;
        
        SuggestOracle.Request requeteOracle;
    SuggestOracle.Callback callBackOracle;
    
        Timer suggestionTimer = null;
    int tempsAvantRequete = 500;
    
    String urlRequete = "";
        
        public AutoCompletionComboBoxPresenteur(Vue vue, String urlRequete) {
                this.autoCompletionComboBoxVue = vue;
                this.urlRequete = urlRequete;
                gererEvenements();
        }
        
        public void go(HasWidgets composite) {
                autoCompletionComboBoxVue.ajouterVue(composite);
        }
        
        public void gererEvenements() {
                autoCompletionComboBoxVue.getSuggestBoxHasKeyPressHandlers().addKeyPressHandler(new KeyPressHandler() {
                        public void onKeyPress(KeyPressEvent event) {           
                                if(event.getUnicodeCharCode() != 0) {
                                        gererTimer();
                                }
                        }
                });
                
                requeteOracle = new SuggestOracle.Request();
                callBackOracle = new SuggestOracle.Callback() {

                        public void onSuggestionsReady(SuggestOracle.Request request, SuggestOracle.Response response) {
                                autoCompletionComboBoxVue.afficherListeDeroulante();    
                        }
            };
            
            autoCompletionComboBoxVue.getSuggestBoxHasSelectionChangeHandlers().addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>(){                           
                        @Override
                        public void onSelection(SelectionEvent<Suggestion> event) {
                                surSelectionSuggestion(event.getSelectedItem().getReplacementString());
                        }
                });
            
            autoCompletionComboBoxVue.setHandlerCopierColler(new Callback<String, String>() {           
                        @Override
                        public void onSuccess(String result) {
                                gererTimer();
                        }
                        
                        @Override
                        public void onFailure(String reason) {
                                // rien à faire ça n'échoue jamais
                        }
                });
        }
        
        public void gererTimer() {
                if(suggestionTimer == null) {
                        suggestionTimer = new Timer() {
                                public void run() {
                                        requeteSuggestions();
                                }       
                        };                                      
                        suggestionTimer.schedule(tempsAvantRequete);
                } else {
                        suggestionTimer.schedule(tempsAvantRequete);
                }
        }
        
        public void setTempsAvantRequete(int temps) {
                tempsAvantRequete = temps;
        }
        
        public int getTempsAvantRequete(int temps) {
                return tempsAvantRequete;
        }
        
        public String getValeur() {
                return autoCompletionComboBoxVue.getValeur();
        }
        
        public void setValeur(String taxon) {
                autoCompletionComboBoxVue.setValeur(taxon);
        }
        
        public void nettoyer() {
                autoCompletionComboBoxVue.nettoyer();
        }
        
        public void requeteSuggestions() {
                
                // Suppression des espaces et caractères inutiles
                String valeur = autoCompletionComboBoxVue.getValeur().trim();
                
                final String requete = URL.encodeQueryString(valeur);
                String requeteAjax = effectuerPreTraitementChaineRequete(requete);      
                
                // ceci permet au composant qui utilise l'autocomplétion
                // d'annuler une requete
                if(requeteAjax == null) {
                        return;
                }
                
                String urlProxy = urlRequete+requeteAjax;
                
                RequestBuilder rb = new RequestBuilder(RequestBuilder.GET, urlProxy) ;
                try {           
                        rb.sendRequest(null, new RequestCallback() {
                                public void onError(final Request request, final Throwable exception) {
                                        // TODO Auto-generated method stub              
                                }

                                public void onResponseReceived(final Request request,
                                                final Response response) {
                                        surReponseRequete(requete, response);
                                }
                        }) ;

                } catch (RequestException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }
        
        public void surReponseRequete(String requete, Response response) {
                InfosNomPourAutocompletion[] valeurs = parserResultatRequete(response);
                autoCompletionComboBoxVue.remplirListe(valeurs);
                requeteOracle.setQuery(requete);
                autoCompletionComboBoxVue.afficherSuggestions(requeteOracle, callBackOracle);   
        }
        
        protected void surSelectionSuggestion(String suggestion) {
                return;
        }
        
        /**
         * Permet d'intervenir sur la chaine tapée par l'utilisateur avant que celle-ci ne soit passée 
         * à la requête asynchrone pour pouvoir la formater (pour mettre en minuscule, séparer des termes) 
         * par défaut renvoie la chaine telle quelle, à surcharger au besoin
         * @param String requete chaine de recherche contenant ce que l'utilisateur à tapé
         * @return String une chaine transformée 
         */
        protected String effectuerPreTraitementChaineRequete(String requete) {
                return requete;
        }
        
        /**
         * Parse les résultats de la requete afin de pouvoir les utiliser à implémenter par le 
         * composants qui crée la combobox selon le contexte et le web service appelé.        
         * @param Response la réponse à la requête asynchrone
         * @return String[] le tableau des suggestions qui sera affiché dans la combobox
         */
        protected abstract InfosNomPourAutocompletion[] parserResultatRequete(Response response);

        public Vue getAutoCompletionComboBoxVue() {
                return autoCompletionComboBoxVue;
        }
        
        public void afficherStyleErreur(String styleErreur) {
                autoCompletionComboBoxVue.afficherStyleErreur(styleErreur);
        }
        
        public void supprimerStyleErreur(String styleErreur) {
                autoCompletionComboBoxVue.supprimerStyleErreur(styleErreur);
        }
}