1. ホーム
  2. jquery

[解決済み] jQuery UIオートコンプリートで結果がないことを検出する

2023-03-21 12:49:39

質問

このトピックに関する半ダースの投稿を見直しましたが、なぜこれが機能しないのか、まだ困っています。

私の目標は、オートコンプリートが 0 の結果を生成したときに検出することです。以下はそのコードです。

 $.ajax({
   url:'sample_list.foo2',
   type: 'get',
   success: function(data, textStatus, XMLHttpRequest) {
      var suggestions=data.split(",");

  $("#entitySearch").autocomplete({ 
    source: suggestions,
    minLength: 3,
    select: function(e, ui) {  
     entityAdd(ui.item.value);
     },
    open: function(e, ui) { 
     console.log($(".ui-autocomplete li").size());
     },
    search: function(e,ui) {
     console.log("search returned: " + $(".ui-autocomplete li").size());

    },
    close: function(e,ui) {  
     console.log("on close" +  $(".ui-autocomplete li").size());    
     $("#entitySearch").val("");
    }
   }); 

  $("#entitySearch").autocomplete("result", function(event, data) {

   if (!data) { alert('nothing found!'); }

  })
 }
}); 

検索自体は問題なく動作し、問題なく結果を表示させることができます。私が理解しているように、私は が必要です。 は autocomplete("result") ハンドラで結果を傍受することができるはずです。この場合、それはまったく発火しません。(結果の数を参照しない一般的なアラートまたは console.log でさえ、決して発生しません)。open イベント ハンドラは正しい数の結果を表示し (結果がある場合)、search および close イベント ハンドラは常に 1 ステップ遅れた結果サイズを報告します。

ここで何か明白な、目に見えるものを見逃しているような気がしますが、私にはそれが見えません。

どのように解決するのですか?

jQueryUI 1.9

jQueryUI 1.9では、オートコンプリートウィジェットに response イベントが追加され、結果が返されなかった場合にそれを検出するために利用できるようになりました。

検索が完了した後、メニューが表示される前にトリガされます。カスタムソースオプションコールバックが必要ない場合、サジェストデータのローカル操作に便利です。このイベントは、結果がない、またはオートコンプリートが無効であるためにメニューが表示されない場合でも、検索が完了すると常にトリガーされます。

ということで、それを踏まえて、jQueryUI 1.8でやらなければならなかったハッキングを、次のように置き換えます。

$(function() {
    $("input").autocomplete({
        source: /* */,
        response: function(event, ui) {
            // ui.content is the array that's about to be sent to the response callback.
            if (ui.content.length === 0) {
                $("#empty-message").text("No results found");
            } else {
                $("#empty-message").empty();
            }
        }
    });
});​

http://jsfiddle.net/andrewwhitaker/x5q6Q/


jQueryUI 1.8

jQueryUIのAPIでこれを行う簡単な方法は見つかりませんでしたが、このような場合、以下のように置き換えることができます。 autocomplete._response 関数を独自の関数に置き換えて、デフォルトのjQueryUI関数( を更新してオートコンプリートの prototype オブジェクト) :

var __response = $.ui.autocomplete.prototype._response;
$.ui.autocomplete.prototype._response = function(content) {
    __response.apply(this, [content]);
    this.element.trigger("autocompletesearchcomplete", [content]);
};

そして、イベントハンドラを autocompletesearchcomplete イベント(contents は検索結果である配列)にバインドします。

$("input").bind("autocompletesearchcomplete", function(event, contents) {
    $("#results").html(contents.length);
});

ここで起こっていることは、オートコンプリートの保存している response 関数を変数 ( __response ) に変換し apply を使って再度呼び出すことができます。 デフォルトのメソッドを呼び出しているので、このメソッドによる悪影響は想像できません。 オブジェクトのプロトタイプを変更しているので、これはすべてのオートコンプリートウィジェットに対して機能します。

以下は動作例です。 : http://jsfiddle.net/andrewwhitaker/VEhyV/

私の例ではデータソースとしてローカルの配列を使っていますが、それは問題ではないと思います。


更新しました。 また、新しい機能を独自のウィジェットにラップし、デフォルトのオートコンプリート機能を拡張することもできます。

$.widget("ui.customautocomplete", $.extend({}, $.ui.autocomplete.prototype, {

  _response: function(contents){
      $.ui.autocomplete.prototype._response.apply(this, arguments);
      $(this.element).trigger("autocompletesearchcomplete", [contents]);
  }
}));

から呼び出しを変更する .autocomplete({...}); に変更します。

$("input").customautocomplete({..});

そして、カスタムの autocompletesearchcomplete イベントにバインドします。

$("input").bind("autocompletesearchcomplete", function(event, contents) {
    $("#results").html(contents.length);
});

例をご覧ください。 : http://jsfiddle.net/andrewwhitaker/VBTGJ/


この質問と回答が注目されたので、この回答を更新して、これを達成するためのさらに別の方法を紹介しようと思います。この方法は 1 のオートコンプリートウィジェットがある場合に有効です。この方法は、リモートまたはローカルのソースを使用するオートコンプリートウィジェットに適用することができます。

var src = [...];

$("#auto").autocomplete({
    source: function (request, response) {
        var results = $.ui.autocomplete.filter(src, request.term);

        if (!results.length) {
            $("#no-results").text("No results found!");
        } else {
            $("#no-results").empty();
        }

        response(results);
    }
});

の中は if の中に、結果が出なかったときに実行するカスタムロジックを配置します。

例です。 http://jsfiddle.net/qz29K/

リモートデータソースを使用している場合は、このように言ってください。

$("#auto").autocomplete({
    source: "my_remote_src"
});

次に、AJAXコールを自分で行い、結果が0件になったときに検出できるように、コードを変更する必要があります。

$("#auto").autocomplete({
    source: function (request, response) {
        $.ajax({
            url: "my_remote_src", 
            data: request,
            success: function (data) {
                response(data);
                if (data.length === 0) {
                    // Do logic for empty result.
                }
            },
            error: function () {
                response([]);
            }
        });
    }
});