web-dev-qa-db-ja.com

オートコンプリートリクエスト/サーバーレスポンスはどのようなものですか?

これはブラックホールのようです: jQuery UI Webサイト、Stack Overflow、およびgooglingを1時間検索した後、オートコンプリートのサーバー側

サーバーに渡されるパラメーターとJSON応答はどのようになりますか?

他のみんながどのようにこれを行う方法を学んだのですか?サイトはクライアント側のJavaScriptコードについてのみ議論しているようで、プロトコルやサーバー側の例については議論していません。

最も簡単なリモートの例を機能させるのに十分なものが必要です。

62
Pete Alvin

サーバーに渡されるパラメーター

request.termをサーバー側のコードに渡す必要があります(ドキュメントから):

「term」と呼ばれる単一のプロパティを持つリクエストオブジェクト。現在のテキスト入力の値を参照します。

基本的に、autocompleteコードには次のようなものがあります。

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

また、JSON応答はどのように見えるべきですか?

autocompleteウィジェットは、labelおよびvalueプロパティを持つJSONオブジェクトの配列を期待します(ただし、valueを指定するだけで、ラベルとして使用されます) 。したがって、最も単純なケースでは、次のようなデータを返すことができます。

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

もっと複雑なものが必要な場合は、$.ajax関数のsuccess引数を使用して、オートコンプリートが取得する前に取得するデータを正規化できます。

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
                }
            }));
         }
    });

このコードは、例 here から取られています(これは、より複雑なシナリオでのajax +オートコンプリートの全体的な動作の良い例です)。

基本的に、成功するajaxリクエストでは、受信したデータは($.mapを使用して)オートコンプリートウィジェットが期待するものに正規化されます。

お役に立てば幸いです。

70
Andrew Whitaker

Andrew Whitakerの完璧な答えに加えて、$。mapの代替方法はレンダラーをオーバーライドすることです その例はjQuery UIデモページに表示されます

次のようなJSON呼び出しを使用してこの機能を使用しました。

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);
};

この例では、_renderItem関数がオーバーライドされ、JSON応答から取得したレコードの属性を使用して、検索結果リスト(つまり、テキストボックスの下に表示されるリスト)が埋められます。

それほど単純ではありませんが、かなり興味深いものを引き出すことができます(たとえば、JSON応答からの複数ビットのデータを使用して)

25
James Boyden

これまでの両方の答えは複雑で誤解を招きやすく、jQuery UI Auto Completeの重要な理解は成功匿名関数です。AutoCompleteの成功コールバックにより、サーバー側JSON応答の形式を活用/制御できます。ラベル、値の形式は従うのに適していますが、必要なJSON形式を定義できます。重要なのは、成功関数を定義する方法です。

 <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
                                }
                            }));
                        }
                    });
                }
            });

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());
    }

ここに、ASP.NETバックエンドとの非常に標準的な自動完全バインドがあります。

AutoComplete匿名コールバックで正しくマップしている限り、サーバー側で必要なJSON形式を返すことができます。ラベル、値、名前、値のペアはほとんどの要件に十分ですが、JSONを使用してサーバー側でオートコンプリート成功コールバックで正しくマッピングするだけで十分です。

7
Brian Ogden

JQuery UIオートコンプリートを使用するためにサーバー側スクリプトを微調整する必要はありませんnot。 JavaScript関数を source として指定して、カスタムリクエストを作成できます(例POSTまたはGET、サーバー側のスクリプトが予期するクエリ文字列パラメーターを使用)および任意の応答(XML応答の処理など)を処理します。

そうは言っても、sourceパラメーターとして文字列を使用すると、次のようになります。

[...]オートコンプリートプラグインは、JSONデータを返すURLリソースを指す文字列を想定しています。同じホスト上または異なるホスト上に存在できます(JSONPを提供する必要があります)。オートコンプリートプラグインは結果をフィルタリングせず、代わりに、クエリ文字列にtermフィールドが追加されます。これは、サーバー側スクリプトが結果のフィルタリングに使用する必要があります。たとえば、ソースオプションがhttp://example.comに設定され、ユーザーがfooと入力した場合、GET要求はhttp://example.com?term=fooに対して行われます。データ自体は、上記のローカルデータと同じ形式にすることができます。

「データ自体は上記のローカルデータと同じ形式にすることができます」に関して、次のJSON(またはJSONP)形式が機能します。

// 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
}]

オブジェクトの配列の場合、labelまたはvalue以外の追加のプロパティを自由に指定できます。すべてのプロパティはコールバック内で利用可能になります。

2
Salman A

次のコードは私のために働いています。これを実行するには、jsonでエンコードされたデータが必要です。データを取得すると、jQueryオートコンプリート形式に従ってデータを変更し、選択も可能にします

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

次のオートコンプリートは https://jqueryui.com/autocomplete/#remote-jsonp からのものです

デモリンク: https://jqueryui.com/resources/demos/autocomplete/remote-jsonp.html

ソースコードは次のとおりです。

<!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