Oppure

Loading
17/09/13 20:20
pierotofy
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:

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


Cosa si potrebbe migliorare?

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[i] + "</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: svn.pierotofy.it/…
Ultima modifica effettuata da pierotofy 17/09/13 20:21
Il mio blog: piero.dev