jQuery UI 자동 완성에서 결과 없음 감지


89

저를 지적하기 전에 예,이 주제에 대한 6 개의 게시물을 검토했지만 이것이 작동하지 않는 이유에 대해 여전히 불만이 있습니다.

내 목표는 자동 완성이 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!'); }

  })
 }
}); 

검색 자체가 잘 작동하고 결과가 문제없이 표시되도록 할 수 있습니다. 내가 알고있는 것처럼, 내가 해야 자동 완성 ( "결과") 핸들러와 함께 결과를 가로 챌 수 있습니다. 이 경우 전혀 발생하지 않습니다. (결과 수를 참조하지 않는 일반 경고 또는 console.log도 실행되지 않습니다.) 열기 이벤트 핸들러는 정확한 결과 수 (결과가있는 경우)를 표시하고 검색 및 닫기 이벤트 핸들러는 항상 한 단계 뒤쳐진 결과 크기를보고합니다.

여기에서 분명하고 눈부신 무언가를 놓치고있는 것 같지만 그냥 보이지 않습니다.


클라이언트 측 데이터로 구동되는 자동 완성 위젯으로이를 수행하는 쉬운 방법이없는 것 같습니다. 위젯에 원격 소스를 사용하는 것이 옵션입니까?
Andrew Whitaker 2011 년

답변:


200

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

@Andrew, jQuery를 사용하여 "contents"배열의 요소에 액세스 할 수있는 방법은 무엇입니까 ???
Bongs 2011-06-30

1
@Bongs : 당신은 인덱스로 직접 액세스 할 수 있어야합니다contents[0]
앤드류 휘태커

사실은 콘텐츠 배열이 사용자 이름과 이미지로 채워져 인덱스 값을 지정하여 액세스 할 수 없다는 것입니다. 그러나 해결책을 찾았습니다. 다음과 같이 언급해야했습니다. contents [i] .user.username ... :) 답장과 멋진 솔루션에 감사드립니다 ...
Bongs

위의 솔루션은 동일한 jQuery 플러그인을 기반으로하는 PrimeFaces 자동 완성 (2.2.x)에서도 잘 작동합니다.
wrschneider

3
JqueryUI 1.8.19에서 _response 함수는 __response로 이름이 변경되었습니다. ( goo.gl/zAl88 ). 그래서, $ .ui.autocomplete.prototype._response는 $ .ui.autocomplete.prototype .__ 응답이된다
crazyphoton

6

누구나 쉽게 내장 된 방식 인 messages : 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")
    }
  }
})

이 기능은 실험적인 기능으로 jQuery 1.9에 추가되었습니다 ( 여기에서 설명 ). 2017 년 7 월 현재 API에 아직 문서화 되지 않았습니다 .


2

원격 데이터 소스 (예 : 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.
    }
});

2

자동 완성 요소를 초기화 한 후 메시지 표시에 기본 스팬을 사용하려면 메시지 옵션을 설정하십시오.

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

참고 : 이것은 실험적인 API입니다 (문서화되지 않음). jQuery UI 개발자는 여전히 문자열 조작 및 국제화를위한 전체 솔루션을 조사하고 있습니다.


0

몇 시간 동안 플레이 한 후 마침내 No match foundjQuery 자동 완성 에 표시하는 트릭을 발견했습니다 . 위의 코드를보고 단순히 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
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);
                            }
                            });
                        },

이 답변은 새로운 것을 제공하지 않으며 수락 된 답변에는 동일한 코드가 있습니다.
Martin

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

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

이 답변은 새로운 것을 제공하지 않으며 수락 된 답변에는 동일한 코드가 있습니다.
Martin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.