首页 文章

检测jQuery UI自动完成没有结果

提问于
浏览
88

在你指出他之前,是的,我已经回顾了关于这个主题的六个帖子,但我仍然因为这不起作用而受到阻碍 .

我的目标是检测自动完成何时产生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!'); }

  })
 }
});

搜索本身工作正常,我可以得到没有问题的结果 . 据我了解,我应该能够使用自动完成("result")处理程序拦截结果 . 在这种情况下,它根本不会发射 . (即使是不引用结果数量的通用警报或console.log也不会触发) . open事件处理程序显示正确的结果数(当有结果时),search和close事件处理程序报告结果总是落后一步 .

我觉得我错过了一些显而易见的东西,但我只是看不到它 .

8 回答

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

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

    's going on here is that you'将自动完成的 response 函数保存到变量( __response ),然后再使用apply再次调用它 . 我可以't imagine any ill-effects from this method since you'重新调用默认方法 . 由于我们是原型,这适用于所有自动完成小部件 .

    Here's a working examplehttp://jsfiddle.net/andrewwhitaker/VEhyV/

    我的示例使用本地数组作为数据源,但我认为这不重要 .


    Update: 您还可以将新功能包装在自己的小部件中,从而扩展默认的自动完成功能:

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

    See an example herehttp://jsfiddle.net/andrewwhitaker/VBTGJ/


    由于这个问题/答案得到了一些关注,我想我会用另一种方法来更新这个答案 . 当您在页面上只有 one 自动完成小部件时,此方法最有用 . 这种方式可以应用于使用远程或本地源的自动完成小部件:

    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 内部,您可以在未检测到任何结果的情况下放置自定义逻辑 .

    Example: 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([]);
                }
            });
        }
    });
    
  • -1

    每个人似乎都忽略了简单的内置方式:使用消息:noResults事件 .

    $('#field_name').autocomplete({
      source: $('#field_name').data('autocomplete-source'),
      messages: {
        noResults: function(count) {
          console.log("There were no matches.")
        },
        results: function(count) {
          console.log("There were " + count + " matches")
        }
      }
    })
    

    此功能是作为实验性功能(described here)在jQuery 1.9中添加的 . 截至2017年7月,尚未documented in the API .

  • 192

    如果您正在使用远程数据源(如MySQL数据库,PHP,或服务器端的任何其他内容),当没有数据返回客户端时,还有其他一些更简洁的方法来处理这种情况(无需任何数据源)黑客或核心代码UI代码更改) .

    我使用PHP和MySQL作为我的远程数据源和JSON来在它们之间传递信息 . 在我的情况下,如果JSON请求没有从服务器得到某种响应,我似乎得到jQuery异常错误,所以我发现当没有数据然后处理客户端时,从服务器端返回空的JSON响应更容易来自那里的回应:

    if (preg_match("/^[a-zA-Z0-9_]*$/", $_GET['callback'])) {//sanitize callback name
        $callback = $_GET['callback'];
    } else { die(); }
    
    die($callback . "([])");
    

    另一种方法是在服务器的响应中返回一个标志,指示没有匹配的数据,并根据响应中标志的存在(和/或值)执行客户端操作 . 在这种情况下,服务器响应将类似于:

    die($callback . "([{'nodata':true}])");
    

    然后基于此标志操作可以在客户端执行:

    $.getJSON('response.php?callback=?', request, function (response) {
        if (typeof response[0].nodata !== 'undefined' && response[0].nodata === true) {
            alert('No data to display!');
        } else {
            //Do whatever needs to be done in the event that there is actually data to display.
        }
    });
    
  • 0

    初始化自动完成元素后,如果要使用默认 Span 进行消息指示,请设置消息选项:

    $(<yourselector>).autocomplete('option', 'messages', {
        noResults: 'myKewlMessage',
        results: function( amount ) {
            return amount + ( amount > 1 ? " results were" : " result was" ) + " found.";
        }
    });
    

    NOTE :这是一个实验性API(未记录) . jQuery UI开发人员仍在研究字符串操作和国际化的完整解决方案 .

  • 2

    玩了几个小时后,我终于找到了一个在jQuery自动完成中显示 No match found 的技巧 . 查看上面的代码,只需添加 div ,在我的情况下 #ulNoMatch ,其样式设置为 displap:none . 在回调成功方法检查返回的数组是否具有 length == 0 . 如果它在那里,你去,你做了你的一天! :)

    <pre><div class="ui-widget1" style="width: auto;">
        <asp:TextBox ID="txtSearch" class="tb" runat="server" Width="150px">
        </asp:TextBox>
        <ul id="ulNoMatch" class="ui-autocomplete ui-menu ui-widget1 ui-widget1-content ui-corner-all"
            role="listbox" aria-activedescendant="ui-active-menuitem" style="z-index: 16;
            display: none; width: 150px;">
            <li class="ui-menu-item" role="menuitem"><a class="ui-corner-all" tabindex="-1">No Matches
                Found</a></li>
        </ul>
        </div><pre>
    <b>
    <b>
    
    Enter code here
    
    <script>
        $(function () {
            $("input[id$='txtSearch']").autocomplete({
                source: function (request, response) {
                    $.ajax({
                        url: "splah.aspx/GetByName",
                        data: "{ 'strName': '" + request.term.trim() + "' }",
                        dataType: "json",
                        type: "POST",
                        //cacheLength: 1,
                        contentType: "application/json; charset=utf-8",
                        dataFilter: function (data) {
                            return data; },
                        success: function (data) {
                            var found = $.map(data.d, function (item) {
                                return {
                                    value: item.Name,
                                    id: item.id
                                }
                             });
    
                             if (found.length == 0)
                             {
                                 $("#ulNoMatch").show();
                             }
                             else
                             {
                                 $("#ulNoMatch").hide();
                             }
                             response(found);
                        },
                        error: function (XMLHttpRequest, textStatus, errorThrown) {
                            alert(textStatus);
                        }
                    });
                },
                select: function (event, ui) {
                    $("input[id$='txtSearch']").val(ui.item.label);
                    $("input[id$='txtID']").val(ui.item.id);
                    return false;
                },
                minLength: 1
            });
        });
    </script>
    
  • 0

    我不明白为什么带有自定义回调的 source 参数是不够的:

    $("#autocomplete").autocomplete({
        source: function (request, response) {
            $.ajax({
                url: "http://example.com/service.json",
                data: {
                    q: this.term
                },
                success: function (data, textStatus, jqXHR) {
                    // data would be an array containing 0 or more items
                    console.log("[SUCCESS] search returned " + data.length + " item(s)");
                    response(data);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    // triggered when AJAX failed because of, for example, malformed JSON
                    console.log("[FAILURE] search returned error");
                    response([]);
                }
            });
        }
    });
    
  • 3
    function SearchText() {
     $(".autosuggest").autocomplete({
       source: function (request, response) {
        $.ajax({
         type: "POST",
         contentType: "application/json; charset=utf-8",
          url: "Default.aspx/GetAutoCompleteData",
          data: "{'username':'" + document.getElementById('txtSearch').value + "'}",
            dataType: "json",
            success: function (data.d) {
            if ((data.d).length == 0) {
             alert("no result found");
              }
               response(data.d);
             },
             error: function (result) {
                  alert("Error");
             }
             });
            }
         });
      }
    
  • 2
    The easiest straight forward way to do it.
    
    $("#search-box").autocomplete({
                        minLength: 2,
                        source:function (request, response) {
                            $.ajax({
                                url: urlPref + "/Api/SearchItems",
                                data: {
                                    term: request.term
                                },
                                success: function (data) {
                                    if (data.length == 0) {
                                        data.push({
                                            Id: 0,
                                            Title: "No results found"
                                        });
                                    }
                                    response(data);
                                }
                                });
                            },
    

相关问题