web-dev-qa-db-fra.com

À quoi ressemble la réponse demande/serveur autocomplete?

Cela semble être un trou noir: après une heure de recherche de jQuery UI website, de Stack Overflow et de Google, je n'ai pas encore trouvé les informations les plus élémentaires sur la façon d'écrire le côté serveur de la saisie semi-automatique.

Quel paramètre est transmis au serveur et à quoi doit ressembler la réponse JSON?

Je dois manquer quelque chose, car comment tout le monde a-t-il appris à faire cela? Les sites ne semblent discuter que du code JavaScript côté client et jamais du protocole ou des exemples côté serveur.

J'ai besoin d'assez pour que l'exemple à distance le plus simple fonctionne.

60
Pete Alvin

Quel paramètre est transmis au serveur

Vous devez passer request.term à votre code côté serveur (à partir de la documentation): 

Un objet de requête, avec un seul propriété appelée "terme", qui fait référence à la valeur actuellement dans le texte contribution.

En gros, dans votre code autocomplete, vous aurez quelque chose comme ceci:

$("#autocomplete").autocomplete({
    // request.term needs to be passed up to the server.
    source: function(request, response) { ... }
});

et à quoi devrait ressembler la réponse JSON comme?

Le widget autocomplete attend un tableau d'objets JSON avec les propriétés label et value (bien que si vous ne spécifiez que value, il sera utilisé comme libellé). Donc, dans le cas le plus simple, vous pouvez simplement renvoyer des données qui ressemblent à ceci:

[
    { label: 'C++', value: 'C++' }, 
    { label: 'Java', value: 'Java' }
    { label: 'COBOL', value: 'COBOL' }
]

Si vous avez besoin de quelque chose de plus compliqué, vous pouvez utiliser l'argument success de la fonction $.ajax pour normaliser les données que vous récupérez avant que la complétion automatique ne les obtienne:

source: function( request, response ) {
    $.ajax({
        /* Snip */
        success: function(data) {
            response($.map( data.geonames, function( item ) {
                return {
                    label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
                    value: item.name
                }
            }));
         }
    });

Ce code provient de l'exemple here (il s'agit d'un bon exemple global de travaux ajax + autocomplete dans un scénario plus complexe). 

En gros, si une demande ajax est acceptée, les données reçues sont normalisées (à l'aide de $.map) par rapport aux attentes du widget de saisie semi-automatique.

J'espère que cela pourra aider.

67
Andrew Whitaker

En plus de la réponse parfaite d'Andrew Whitaker, une méthode alternative à $ .map consiste à remplacer le rendu, un exemple est présenté sur la page de démonstration de jQuery UI.

J'ai utilisé cette fonctionnalité en utilisant un appel JSON comme ceci:

Réponse JSON

{
   "Records": [
       {
           "WI_ID": "1",
           "Project": "ExampleProject",
           "Work_Item": "ExampleWorkItem",
           "Purchase_Order": "",
           "Price": "",
           "Comments": "",
           "Quoted_Hours": "",
           "Estimated_Hours": "",
           "Achieved": "False",
           "Used_Hours": "0"
       }
   ]
}

jQuery

$("#WorkItem").autocomplete({
      source: function(request, response){
           $.ajax({
               type: "POST",
               url: "ASPWebServiceURL.asmx/WorkItems",
               data: "{'Project_ID':'1'}",
               contentType: "application/json; charset=utf-8",
               dataType: "json",
               success: function (msg) {
                   response($.parseJSON(msg.d).Records);
               },
               error: function (msg) {
                   alert(msg.status + ' ' + msg.statusText);
               }
           })
       },

       select: function (event, ui) {
           $("#WorkItem").val(ui.item.Work_Item);
           return false;
       }
})
.data("autocomplete")._renderItem = function (ul, item) {
    return $("<li></li>")
    .data("item.autocomplete", item)
    .append("<a>" + item.Work_Item + "</a>")
    .appendTo(ul);
};

Dans cet exemple, la fonction _renderItem est remplacée de sorte que la liste des résultats de la recherche (c'est-à-dire la liste qui apparaît sous la zone de texte) soit renseignée à l'aide des attributs des enregistrements extraits de la réponse JSON.

Bien que cela ne soit pas aussi simple, cela vous permet d’obtenir des informations intéressantes (en utilisant plusieurs bits de données d’une réponse JSON, par exemple).

24
James Boyden

Jusqu'à présent, les deux réponses sont complexes et trompeuses. Une compréhension clé de jQuery UI Auto Complete est la fonction anonyme de succès, vous avez le contrôle/le gain du format de votre réponse JSON côté serveur en raison du rappel de succès d'AutoComplete. Le libellé, le format de valeur est un bon exemple à suivre, mais vous pouvez définir le format JSON de votre choix. La clé est la définition de votre fonction de réussite:

 <input id="refPaymentTerms" class="form-control">

$("#refPaymentTerms").autocomplete({
                source: function (request, response) {
                    $.ajax({
                        type: "POST",
                        url: "/admin/JobPaymentRefs",
                        dataType: "json",
                        data: {
                            term: request.termCode
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            alert('Error: ' + xhr.responseText);
                        },
                        success: function (data) {
                            response($.map(data, function (item) {
                                return {
                                    label: item.label,
                                    value: item.value
                                }
                            }));
                        }
                    });
                }
            });

Contrôleur MVC:

public JsonResult JobPaymentRefs()
    {
        var query = from REFTerm in _db.REFTerms
                     select new
                    {
                        label = REFTerm.TermCode,
                        value = REFTerm.TermCode
                    };
        //var refTerms = _db.REFTerms.Select(x => x.TermCode);

        return Json(query.ToArray());
    }

Nous voyons ici une liaison automatique très standard avec un backend ASP.NET.

Vous pouvez renvoyer n'importe quel format de JSON souhaité côté serveur, à condition de le mapper correctement dans le rappel anonyme avec saisie semi-automatique. La paire nom/valeur nom-valeur est suffisante pour la plupart des exigences, mais faites comme si vous étiez côté serveur avec votre JSON et que vous le mappiez correctement dans le rappel de réussite de la saisie semi-automatique.

7
Brian Ogden

Vous êtes non requis pour ajuster le script côté serveur afin d'utiliser la complétion automatique de l'interface utilisateur jQuery. Vous pouvez spécifier une fonction JavaScript en tant que source pour créer des demandes personnalisées (par exemple, utilisez POST ou GET, utilisez les paramètres de chaîne de requête attendus par le script côté serveur) et gérez les réponses arbitraires ( par exemple, gérer les réponses XML).

Cela dit, lorsque vous utilisez une chaîne comme paramètre source, alors:

[...] le plugin Autocomplete s'attend à ce que cette chaîne pointe vers une URL ressource qui renverra des données JSON. Il peut être sur le même hôte ou sur un autre (doit fournir JSONP). Le plugin Autocomplete ne le fait pas Pour filtrer les résultats, une chaîne de requête est ajoutée avec un champ term, que le script côté serveur doit utiliser pour filtrer les résultats. Pour Par exemple, si l’option source est définie sur http://example.com et le type d’utilisateur foo, une requête GET serait adressée à http://example.com?term=foo. Les données elles-mêmes peuvent être dans le même format comme les données locales décrites ci-dessus.

En ce qui concerne "Les données elles-mêmes peuvent être au même format que les données locales décrites ci-dessus", les formats JSON (ou JSONP) suivants fonctionneront:

// no matching entries
[]

// array of strings
[
"Option 1",
"Option 2"
]

// array of objects with label property
[{
    "label": "Option 1"
}, {
    "label": "Option 2"
}]

// array of objects with value property
[{
    "value": "Option 1"
}, {
    "value": "Option 2"
}]

// array of objects with label and value properties
[{
    "label": "Option 1",
    "value": 1
}, {
    "label": "Option 2",
    "value": 2
}]

Pour les tableaux d'objets, vous êtes libre de spécifier des propriétés supplémentaires en plus de label et/ou de value. Toutes les propriétés seront disponibles dans les rappels.

2
Salman A

Le code suivant fonctionne pour moi. Cela nécessite des données encodées JSON pour fonctionner. Une fois que nous obtenons des données, elles sont modifiées en fonction du format de saisie semi-automatique jQuery et permettent également la sélection.

var $url = "http://some-url/get-json";
//name is the id of the textbox where autocomplete needs to be shown
$('#name').autocomplete(
{ 
source: function(request,response)  
{ 

  //gets data from the url in JSON format
  $.get($url, function(data)
  {         
    obj = JSON.parse(data);   //parse the data in JSON (if not already)
    response($.map(obj, function(item)
    {
      return {
        label: item.full_name,
        value: item.full_name,
        id:item.id,
        email:item.email,
        phone:item.phone,
      }
    }
  ));        //end response
});          //end get
},
select:function(event, ui)
{ 
 console.log(ui.item.full_name);
 console.log(ui.item.email);
}   

}); //end of autocomplete
1
Nava Bogatee
<!doctype html>

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>jQuery UI Autocomplete - Categories</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
        <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
        <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
        <link rel="stylesheet" href="/resources/demos/style.css" />
        <style>
            .ui-autocomplete-category {
                font-weight: bold;
                padding: .2em .4em;
                margin: .8em 0 .2em;
                line-height: 1.5;
            }
            body {
                font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif";
                font-size: 62.5%;
            }
        </style>
        <script>
            $.widget("custom.catcomplete", $.ui.autocomplete, {
                _renderMenu : function(ul, items) {
                    var that = this, currentCategory = "";
                    $.each(items, function(index, item) {
                        if (item.category != currentCategory) {
                            ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
                            currentCategory = item.category;
                        }
                        that._renderItemData(ul, item);
                    });
                }
            });
        </script>
        <script>
            $(function() {
                $("#search").catcomplete({
                    delay : 0,
                    source : function(request, response) {
                        $.ajax({
                            url : "search",
                            dataType : "json",
                            data :"searchText=hk",
                            success : function(data) {
                                response(data);
                            } //success
                        });
                    }
                });
            });
        </script>
    </head>
    <body>enter code here
        <label for="search">Search: </label>
        <input id="search" />
    </body>
</html>
0
Hari Agarwal

La saisie semi-automatique suivante provient de https://jqueryui.com/autocomplete/#remote-jsonp

Un lien de démonstration: https://jqueryui.com/resources/demos/autocomplete/remote-jsonp.html

Voici le code source:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>jQuery UI Autocomplete - Remote JSONP datasource</title>
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <link rel="stylesheet" href="/resources/demos/style.css">
    <style>
    .ui-autocomplete-loading {
        background: white url("images/ui-anim_basic_16x16.gif") right center no-repeat;
    }
    </style>
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <script>
    $( function() {
        function log( message ) {
            $( "<div>" ).text( message ).prependTo( "#log" );
            $( "#log" ).scrollTop( 0 );
        }

        $( "#birds" ).autocomplete({
            source: function( request, response ) {
                $.ajax( {
                    url: "search.php",
                    dataType: "jsonp",
                    data: {
                        term: request.term
                    },
                    success: function( data ) {
                        response( data );
                    }
                } );
            },
            minLength: 2,
            select: function( event, ui ) {
                log( "Selected: " + ui.item.value + " aka " + ui.item.id );
            }
        } );
    } );
    </script>
</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>

0
caot