Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit the result in jQuery Autocomplete

How can you set a limit on the result from the jQuery autocomplete?

This is my code:

        $.ajax({
            url: "/cache/search/SearchModels.xml",
            dataType: "xml",
            success: function(xmlResponse) {
                var data = $("SearchModel", xmlResponse).map(function() {
                    return {
                        value: $("Name", this).text() + ", " + $("Description", this).text(),
                        id: $("No", this).text(),
                        name: $("Name", this).text(),
                        url: $("URL", this).text()
                    };
                }).get();
                $("#txtTopSearch").autocomplete({
                    source: data,
                    minLength: 2,
                    select: function(event, ui) {
                        BlockUI();
                        if (typeof (ui.item.url) != 'undefined') {
                            window.location = ui.item.url;
                        }
                        else {
                            alert('Page not found!');
                            $.unblockUI();
                        }
                    },
                    search: function(event, ui) {
                        $('#txtTopSearch').addClass('searchInProgress');
                    },
                    close: function(event, ui) {
                        $('#txtTopSearch').removeClass('searchInProgress');
                    }
                }).data("autocomplete")._renderItem = function(ul, item) {
                    return $("<li></li>")
                    .data("item.autocomplete", item)
                    .append("<a><span style='font-size:.9em; font-weight:bold;'>" + item.id + "</span><br /><span style='font-size:.8em;'>" + item.name + "</span></a>")
                    .appendTo(ul);
                };
            },
            error: function(xhr, textStatus, errorThrown) {
                alert('Error: ' + xhr.statusText);
            }
        });

This code return all results in the query, but I want to limit this to just showing 10 results. In the old autocomplete version there was an option for this, but it is now deprecated.

Example of the XML:

<?xml version="1.0"?>
<ArrayOfSearchModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SearchModel>
    <No>1</No>
    <Name>My product</Name>
    <Description>My description</Description>
    <Tags>blue;brown;</Tags>
    <URL>/Products/1</URL>
  </SearchModel>
</ArrayOfSearchModel>
like image 446
Martin at Mennt Avatar asked Nov 01 '10 18:11

Martin at Mennt


4 Answers

The quickest way to limit results is doing it during the "open" event. We can delete part of the content dynamically created by jquery ui, reducing the children element array.

This solution solved the same issue for me:

var maxResults = 10;
$input.autocomplete({
    source: somefile.json,
    open: function(event,ui){
          $(this).data("uiAutocomplete").menu.element.children().slice(maxResults).remove();
         }
})
like image 125
Mirko Bianco Avatar answered Nov 20 '22 02:11

Mirko Bianco


This is what I did based on some reading of the autocomplete API docs

$input.autocomplete({
  source: function( request, response ) {
    $.getJSON('search.php', request, function( data, status, xhr ) {
      // return a max of 10 results.
      response( data.slice(0, 9) );
    });
  }
})

Following this pattern saves having to do any funky stuff in the render layer.

like image 44
Paul Sheldrake Avatar answered Nov 20 '22 03:11

Paul Sheldrake


Final Update
after understanding that in my previous answers i was limiting the whole xml result set and not the results of the autocomplete

As you have overridden the default _renderItem method, you can override the default _renderMenu.

$.ui.autocomplete.prototype._renderMenu = function( ul, items ) {
   var self = this;
   $.each( items, function( index, item ) {
      if (index < 10) // here we define how many results to show
         {self._renderItem( ul, item );}
      });
}

answer is modified from this jQueryUI: how can I custom-format the Autocomplete plug-in results? so thanks go to @cheeso..


Original Answer

In you success callback use $("SearchModel:lt(10)", xmlResponse).map(...

The :lt(10) gets elements with an index of less than 10. So max 10 results will be returned..

(of course the number 10 could be anything you want)

Look at :lt() selector at http://api.jquery.com/lt-selector/

update

Although i cannot understand why the first answer does not work, since the SearchModel is a tag and we target that.. we can move the filtering in the map method..

success: function(xmlResponse) {
                var data = $("SearchModel", xmlResponse).map(function(index) {
                    if (index<10)
                      {
                        return {
                            value: $("Name", this).text() + ", " + $("Description", this).text(),
                            id: $("No", this).text(),
                            name: $("Name", this).text(),
                            url: $("URL", this).text()
                               };
                      }
                      else
                      { return null; }
                }).get();

documentation of map()

like image 11
Gabriele Petrioli Avatar answered Nov 20 '22 03:11

Gabriele Petrioli


Why not limit the data that your query returns from your xml source?

Edit:

You have to remember that the autocomplete functionality is essentially using a regex to match items in the datasource. Having a large datasource is bad because it has to parse so much data simply to find the correct item.

like image 3
Achilles Avatar answered Nov 20 '22 03:11

Achilles