小编典典

在jQuery UI自动完成功能上未检测到任何结果

ajax

是的,在您将我指向他们之前,我已经回顾了有关该主题的六篇文章,但是我仍然对为什么这行不通感到困惑。

我的目标是检测自动填充何时产生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也不会触发)。打开事件处理程序显示正确的结果数(有结果时),搜索和关闭事件处理程序报告的结果大小始终落后一步。

我觉得我在这里遗漏了一些明显的东西,但我只是看不到它。


阅读 264

收藏
2020-07-26

共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事件(内容是搜索的结果,一个数组):

$("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/


既然这个问题/答案已经引起了人们的关注,我想我会用另一种方法来完成此问题的更新。当页面上只有 一个
自动完成窗口小部件时,此方法最有用。可以将这种方式应用于使用远程或本地源的自动完成小部件:

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([]);
            }
        });
    }
});
2020-07-26