Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Tutto e di + - Autocomplete
Forum - Tutto e di + - Autocomplete

Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 22:20
Martedė, 17/09/2013
Ho appena inserito questo codice nel repo per la versione mobile del sito. Questa funzione ci permettera di non utilizzare una libreria di terze parti e di mantenere il codice piu' pulito.

Per usare la funzione di autocomplete si invoca semplicemente:

Codice sorgente - presumibilmente Plain Text

  1. Autocomplete.Bind("input#casella-di-input", "/search.php", {
  2.     params: {"max" : 5}
  3. });



Cosa si potrebbe migliorare?

Testo quotato


var Autocomplete = {

    // Connette un input a una sorgente dati e fornisce una funzione di autocompletamento
    // @param selector selettore CSS per l'input
    // @param datasource URL dove vengono richiesti i dati
    // @options (opzionale) permette di specificare:
    //        delay => quanto tempo deve passare prima che la richiesta alla sorgente venga inviata (calcolata dall'ultima battitura)
    //        params => parametri da passare alla sorgente
    //        timeout => numero di millisecondi prima che la richiesta ajax fallisca
    Bind: function(selector, datasource, options){
        if (options === undefined) options = {};

        var $item = $(selector);

        if ($item.length > 0){

            // Parametri di default
            var delay = options.delay || 500;
            var params = options.params || {};
            var timeout = options.timeout || 10000;
            var data = {
                "term" : ""
            };

            // Copia i parametri in options.param per la richiesta
            for(var p in params){
                data[p] = params[p];
            }

            // Wrappa l'elemento
            if (!$item.parent().hasClass("absolute-container")){
                $item.wrap('<div class="absolute-container"></div>');
            }

            // Se non c'e' l'elemento nel DOM...
            if (!$item.$autocompleteList){
                var $autocompleteList = $('<ul class="autocomplete-list"></ul>');

                // Definiamo la nostra funzione per cancellare la lista (invece di usare empty)
                // siccome teniamo traccia dell'elemento selezionato al momento tramite tastiera KEY_UP|KEY_DOWN
                $autocompleteList.clear = function(){
                    this.empty();
                    this.currentItemIndex = null;
                };

                // inserisci la lista (e linkala all'oggetto jquery padre)
                $item.after($autocompleteList);
                $item.$autocompleteList = $autocompleteList;
                $item.$autocompleteList.clear(); // inizializza
            }              

            // non inviare le richieste subito
            var timeoutHandle = 0;

            $item.lastSearchedTerm = "";
            $item.keyup(function(event){
                if (event.which == 13){
                    // Premuto il tasto invio
                    var $selected = $item.$autocompleteList.children(".hover");
                    if ($selected.length > 0){
                        $item.val($selected.html());
                        $item.$autocompleteList.clear();
                    }
                }else{
                    if ($item.val() != ""){
                        clearTimeout(timeoutHandle);
                        timeoutHandle = setTimeout(function(){
                            var newTerm = $item.val();

                            // Non mandare se l'utente non ha cambiato il termine di ricerca
                            if ($item.lastSearchedTerm != newTerm){
                                data["term"] = newTerm;
                                $.ajax({
                                    type: "POST",
                                    url: datasource,
                                    data: data,
                                    timeout: timeout,
                                    success: function(data){
                                        if (data.success){
                                            $item.lastSearchedTerm = newTerm;
                                            $item.$autocompleteList.clear();

                                            for (var i in data.results){
                                                $suggestion = $("<li>" + data.results + "</li>");
                                                $item.$autocompleteList.prepend($suggestion);

                                                // On click
                                                $suggestion.click(function(){
                                                    $item.val($(this).html());
                                                    $item.$autocompleteList.clear();
                                                });
                                            }
                                        }
                                    },
                                    dataType: 'json'
                                });
                            }
                        }, delay);
                    }else{
                        $item.$autocompleteList.clear();
                    }
                }
            });    
            
            // Gestione dell'input da tastiera. Gestisce se l'utente preme la freccia giu/su e ESC
            $item.keydown(function(event){
                
                var KEY_UP = 38;
                var KEY_DOWN = 40;
                var KEY_ESC = 27;

                if (event.which == KEY_UP || event.which == KEY_DOWN){

                    // Andiamo su di uno o giu di uno?
                    var delta = null;
                    if (event.which == KEY_DOWN) delta = 1;
                    else if (event.which == KEY_UP) delta = -1;

                    var itemsCount = $item.$autocompleteList.children().length;
                    
                    // Primo evento? (Non abbiamo ancora selezionato un elemento tramite tastiera)
                    if ($item.$autocompleteList.currentItemIndex == null){
                        $item.$autocompleteList.currentItemIndex = (event.which == KEY_DOWN ? 0 : itemsCount - 1);
                        delta = 0; // muovi di zero, usa il valore di inizio
                    }

                    // Ci sono elementi da selezionare?
                    if (itemsCount > 0){
                        // Trova il prossimo
                        var selectItemIndex = $item.$autocompleteList.currentItemIndex + delta;
                        if (selectItemIndex > itemsCount - 1) selectItemIndex = 0;
                        else if (selectItemIndex < 0) selectItemIndex = itemsCount - 1;

                        // Seleziona il nuovo elemento e tieni traccia del nuovo indice
                        $item.$autocompleteList.children().removeClass("hover");
                        $item.$autocompleteList.children(":nth-child(" + (selectItemIndex + 1) + ")").addClass("hover");
                        $item.$autocompleteList.currentItemIndex = selectItemIndex;

                        event.preventDefault();
                    }
                }else if (event.which == KEY_ESC){
                    $item.$autocompleteList.clear();
                }
            });
        }
    }
};



Il sorgente completo e' disponibile su SVN: http://svn.pierotofy.it/listing.php?repname=mobile-devel


pierotofy ha allegato un file: autocomplete.png (5580 bytes)
Clicca qui per guardare l'immagine

Ultima modifica effettuata da pierotofy il 17/09/2013 alle 22:21


Il mio blog: https://piero.dev
PM Quote