9

I'm using jquery-ui-autocomplete (actually, a catcomplete attached to a search box). It works vey well as long as I use a static-defined array of items as source.

For performance reasons, I don't want the autocomplete to send Ajax requests to a PHP script making %like% requests to MySQL. So, I generated a JSON file from the DB, containing every item that can be matched in the search (about 20-30 items, from many sql tables). I'd like to read/parse the file only once, as the page loads or when the user starts to type in the search box.

I'm stuck here. I tried to attach an Ajax call to the .catcomplete() (code below). I also tried to make a getJSON call and create the .catcomplete in its success() method. Both ways fail silently.

I'm kind of new to JS/jQuery stuff, I already like it, but I'm a bit lost. Any help/solution/pointer to usefull doc would be greatly appreciated.

Thank you very much!

Here is the HTML : (real simple)

<form id="searchform" method="get" role="search">
    <input id="searchfield" />
    <input type="submit" name="go" value="go!" />
</form>

Here is my JS code :

$( "#searchfield" ).catcomplete({
delay: 0,
source: function( request, response ) {
    $.ajax({
        url: "/path/to/cache.json",
        dataType: "json",
        data: {term: request.term},
        success: function(data) {
            response($.map(data, function(item) {
                return {
                    label: item.label,
                    category: item.category,
                    desc: item.desc
                };
            }));
        }
    });
},
minlength:0
});

Sample JSON data:

[
{ label: "lbl1", category: "cat1", desc: "desc1"}, 
{ label: "lbl2", category: "cat1", desc: "desc2"}, 
{ label: "lbl3", category: "cat1"}
]
Didier Sampaolo
  • 2,566
  • 4
  • 24
  • 34

2 Answers2

10

Try flipping it around, so on page-load you grab it once, then instantiate the autocomplete.

$(function() {
    $.ajax({
        url: "/path/to/cache.json",
        dataType: "json",
        data: {term: request.term},
        success: function(data) {
            var cat_data = $.map(data, function(item) {
                return {
                    label: item.label,
                    category: item.category,
                    desc: item.desc
                };
            });
            $("#searchfield").catcomplete({
                delay: 0,
                source: cat_data,
                minlength:0
            });
        }
    });
});
000
  • 26,951
  • 10
  • 71
  • 101
  • This answer was helpful to me (thank you very much). Actually, I had a problem with the JSON file (lack of "" around properties names...), this syntax helped me to point that out. Everything works fine. Thanks again ! – Didier Sampaolo Mar 29 '13 at 02:04
  • great tip, specially for larger JSON files! – Iladarsda Jun 28 '13 at 10:24
  • @joe-frambach Can we use limit with this syntax. Let's say every time I need max 10 results? – huzeyfe Aug 06 '13 at 09:03
9

Your datasource is throwing an parse error since the json format is not propper, in json the keys also have to be enclosed within ".

{
  "list" : [{
                "label" : "lbl1",
                "category" : "cat1",
                "desc" : "desc1"
            }, {
                "label" : "lbl2",
                "category" : "cat1",
                "desc" : "desc2"
            }, {
                "label" : "lbl3",
                "category" : "cat1"
            }]
}

Demo: Plunker

If you want the request term based searches, then you will have to make some more changes

  var xhr;
  $( "input" ).catcomplete({
    delay: 0,
    source: function( request, response ) {
      var regex = new RegExp(request.term, 'i');
      if(xhr){
        xhr.abort();
      }
      xhr = $.ajax({
          url: "data.json",
          dataType: "json",
          cache: false,
          success: function(data) {
            response($.map(data.list, function(item) {
              if(regex.test(item.label)){
                return {
                    label: item.label,
                    category: item.category,
                    desc: item.desc
                };
              }
            }));
          }
      });
    },
    minlength:0
  });

Demo: Plunker

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • Actually, I managed to skip the regexp part using a monkeypatch on _renderItemData (which seem to involve only the matching items). I marked your answer as the best one as my real problem was the quotes in the JSON file. Thank you very much for pointing that out ! – Didier Sampaolo Mar 29 '13 at 02:12