un input avec autocomplémentation

Il est parfois utile d’avoir un un input qui propose lors de la frappe les éléments possibles

Jquery apporte encore une fois une solution élégante.

en effet suite à la frappe de x caractères jquery va vori auprès d’une source pour obtenir une liste d’élément qu’il va alors afficher

Il faut bien noter que contrairement à un select-box (voir l’utilisation de chosen), nous utilisons un input et donc la frappe reste libre.

Exemple de liste au format json qu’on souhaite utiliser (fichier search.txt)

[
        {"label" : "Aragorn"},
        {"label" : "Arwen"},
        {"label" : "Bilbo Baggins"},
        {"label" : "Boromir"},
        {"label" : "Frodo Baggins"},
        {"label" : "Gandalf"},
        {"label" : "Gimli"},
        {"label" : "Gollum"},
        {"label" : "Legolas"},
        {"label" : "Meriadoc Merry Brandybuck"},
        {"label" : "Peregrin Pippin Took"},
        {"label" : "Samwise Gamgee"}
]

Il faut noter que:

  • seul le format json est possible avec cette fonction
  • chaque élément doit avoir un id label (qui correspondra à la valeur dans la liste)

le fichier html avec le code javascript

<!doctype html>

<html lang="en">
<head>
        <meta charset="utf-8" />
        <title>jQuery UI Autocomplete - Remote datasource</title>
        <link rel="stylesheet" href="http://test1.fr/css/redmond/jquery-ui-1.10.3.custom.min.css" />
                <script src="http://test1.fr/js/libext/jquery-1.9.1.min.js"></script>
                <script src="http://test1.fr/js/libext/jquery-ui-1.10.3.custom.min.js"></script>
        <link rel="stylesheet" href="style.css" />
        <style>
        .ui-autocomplete-loading {
                background: white url('ui-anim_basic_16x16.gif') right center no-repeat;
        }
        </style>
</head>
<body>

<div class="ui-widget">
        <label for="birds">Birds: </label>
        <input id="birds" />
</div>

<div class="ui-widget" style="margin-top: 2em; font-family: Arial;">
        Result:
        <div id="log" style="height: 200px; width: 300px; overflow: auto;" class="ui-widget-content"></div>
</div>


</body>
</html>

le code javascipt

$(function() {
        function log( message ) {
                $( "<div>" ).text( message ).prependTo( "#log" );
                $( "#log" ).scrollTop( 0 );
        }

        $( "#birds" ).autocomplete({
                source: "search.txt",
                minLength: 2,
                select: function( event, ui ) {
                        log( ui.item ?
                                "Selected: " + ui.item.value :
                                "Nothing selected, input was " + this.value );
                }
        });
});

On peut noter que dans cette exemple on paramètre une action lors de la sélection d’un élément dans la liste affichée.

Si cette exemple est simple il pose deux problèmes majeurs:

  • la liste est fixe et ne tient pas compte des caractères déjà frappé.
  • il n’est pas possible lors de la sélection d’avoir accès à d’autres informations de la liste

On peut modifier le code afin de résoudres ces problèmes via l’utilisation d’un serveur qui va fournir une liste au format json suivant les caractères frappés

exemple de liste retournée après la frappe de “ar”

[
        {"label" : "Aragorn", "id" : "ara"},
        {"label" : "Arwen", "id" : arw}
]

modification du code javascript

$(function() {
        function log( message ) {
                $( "<div>" ).text( message ).prependTo( "#log" );
                $( "#log" ).scrollTop( 0 );
        }

        $( "#birds" ).autocomplete({
                source: function( request, response ) {
                        $.ajax({
                                url: "states_remote.php",
                                dataType: "json",
                                data: {term: request.term},
                                success: function(data) {
                                                        response($.map(data , function(item) {
                                                return {
                                                                label: item.label,
                                                                id: item.id
                                                                };
                                                }));
                                        }
                                });
                        },
                minLength: 2,
                select: function( event, ui ) {
                        log( ui.item ?
                                "Selected: " + ui.item.value + " with id " + ui.item.id :
                                "Nothing selected, input was " + this.value );
                }
        });
});

Note

il existe en python un module json qui permet de générer facilement ce format

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True,
...                  indent=4, separators=(',', ': '))
{
    "4": 5,
    "6": 7
}