5

I'm using jquery autocomplete with multiple results and a remote datasource. I'm able to pull the data remotely and select multiple results. But the results list doesn't update based on the first 2 characters input, and the jQueryUI documentation is thin on this issue.

I've researched around, and found this answer here on SO and want to integrate it with the rest of my function, but it doesn't update the results list. Independently, the SO answer works fine, but not when integrated with multiple results and a remote datasource.

From the autocomplete/remote source/multiple function (truncated). This part works fine:

.autocomplete({
                source: function( request, response ) {                            
                     $.ajax({
                        url: "/controller/myfunction",
                        dataType: "json",
                        data: request,
                        success: function(data){
                        if(data.response == 'true') {
                            response(data.message);
                            }
                        }
                    });
                },

Possible solution on SO: (works fine independently, but not with the jquery/remote/multiple code):

var wordlist= [ "about", "above", "within", "without"];

$("#input1").autocomplete({
    source: function(req, responseFn) {
        var re = $.ui.autocomplete.escapeRegex(req.term);
        var matcher = new RegExp( "^" + re, "i" );
        var a = $.grep( wordlist, function(item,index){
            return matcher.test(item);
        });
        responseFn( a );
    }
});

I need to integrate this solution with my code.

Community
  • 1
  • 1
chowwy
  • 1,126
  • 8
  • 26
  • 45
  • Any chance you can filter your results on the server? This way you wouldn't even have to worry about filtering in the JS. – Andrew Whitaker Oct 28 '12 at 23:04
  • @AndrewWhitaker - That would be ideal; I'm working on both options and trying to see which one yields fruit first. – chowwy Oct 28 '12 at 23:16

5 Answers5

3

From jQuery UI Autocomplete: Search from Beginning of String you can try:

$("#YOUR_TEXT_INPUT").autocomplete({
    source: function(req, response) { 
       $.ajax({
        url: "/controller/myfunction",
        dataType: "json",
        success: function( data ) {
            var re = $.ui.autocomplete.escapeRegex(req.term);
            var matcher = new RegExp( "^" + re, "i" );
            response($.grep(data, function(item){return matcher.test(item.value);}) );
            }
        });
     },
      minLength: 2,
      select: function(event, ui) {
          //custom select function if needed
       }
    });
jk.
  • 14,365
  • 4
  • 43
  • 58
  • Thanks for this; the code in your success function is actually the same code as in my question, just in the source function. I moved my code to match this, but unfortunately, it didn't work. – chowwy Oct 28 '12 at 23:06
  • @chowwy Can you show your complete code? Also, you can adjust the db query like others have mentioned to search from the beginning of the string. – jk. Oct 28 '12 at 23:08
  • My code is the remote datasource code from the jQuery Autocomplete site (http://jqueryui.com/autocomplete/#remote), with the adjustments indicated in my question to the source part of the function. – chowwy Oct 28 '12 at 23:17
  • Actually, it's http://jqueryui.com/autocomplete/#multiple-remote (I'm doing the remote datasource with multiple entries option. – chowwy Oct 28 '12 at 23:21
  • 2
    @chowwy Then it sounds like you need to adjust the db query to start its matching at the beginning of the string. – jk. Oct 28 '12 at 23:27
  • I should be able to do both. I'm working on using the DB query to get results, but I should also be able to get the results using jquery. – chowwy Oct 28 '12 at 23:29
  • 1
    @chowwy You shouldn't have to do both. One or the other should work for you. – jk. Oct 29 '12 at 01:23
  • I realize that. My question is about the jquery option, which is working as a datasource, but not filtering based on the input. I already have the code you provided (it's in my question) and jquery doesn't provide this level of detail in their docs. Doesn't look like anyone has done the input filtering + remote datasource + multiple selections. – chowwy Oct 29 '12 at 14:40
1

jQuery autcomplete sends what the user has typed in as a HTTP parameter, so you can use that to alter the results that you fetch from the DB.

Here is an example (in CakePHP). It gets the "term" parameter, which contains what the user typed in, and it uses that to generate the DB query.

Tom Dalling
  • 23,305
  • 6
  • 62
  • 80
  • Thanks, but I've got the query working fine. The issue that I want to customize the results that show beneath the input, based on the first few characters that I type. Right now, all of the results from the database are showing. – chowwy Oct 28 '12 at 22:45
  • If all the results are showing, maybe make the query return less results. – Tom Dalling Oct 28 '12 at 22:49
1

Optimally, it should be the controller that delivers the filtered data in JSON. I suggest you better try filtering the data in the controller rather than in the view. Of if your application is MVC-oriented, you should keep all the querying and filtering inside of the model used within the controller action you specify. I do think the usage of AJAX (Asynchronous Javascript and XML) should be used to pass on as much load to the server as possible. so, your view code would be rather simple

var wordlist= [ "about", "above", "within", "without"];

$("#input1").autocomplete({
    source: 'url-to-controller/myAction', //Notice I'm using a string
    minLength: 2
});

Autocomplete|jQuery Ui - source states that:

... When a string is used, the Autocomplete plugin expects that string to point to a URL resource that will return JSON data. It can be on the same host or on a different one (must provide JSONP). The Autocomplete plugin does not filter the results, instead a query string is added with a term field, which the server-side script should use for filtering the results. For example, if the source option is set to "http://example.com" and the user types foo, a GET request would be made to http://example.com?term=foo. The data itself can be in the same format as the local data described above.

Based on the above, you could modify your controller action so it uses the term GET request so it is used to filter the data in the query.. Be sure to let me know how it goes.

Snivs
  • 1,105
  • 11
  • 20
1

As you are using $.ajax with json dataType then your data.message is an Array which you can filter it by removing unnecessary items.
assuming the ajax msg Array has been built from below sample json,

{"id":"Nycticorax nycticorax","label":"Black-crowned Night Heron","value":"Black-crowned Night Heron"},{"id":"Ardea purpurea","label":"Purple Heron","value":"Purple Heron"},{"id":"Circus cyaneus","label":"Hen Harrier","value":"Hen Harrier"},{"id":"Alcedo atthis","label":"Common Kingfisher","value":"Common Kingfisher"},{"id":"Oxyura leucocephala","label":"White-headed Duck","value":"White-headed Duck"},{"id":"Oenanthe oenanthe","label":"Northern Wheatear","value":"Northern Wheatear"},{"id":"Tadorna tadorna","label":"Common Shelduck","value":"Common Shelduck"},{"id":"Ardea cinerea","label":"Grey Heron","value":"Grey Heron"},{"id":"Ficedula hypoleuca","label":"Eurasian Pied Flycatcher","value":"Eurasian Pied Flycatcher"},{"id":"Motacilla flava","label":"Blue-headed Wagtail","value":"Blue-headed Wagtail"},{"id":"Muscicapa striata","label":"Spotted Flycatcher","value":"Spotted Flycatcher"},{"id":"Accipiter gentilis","label":"Northern Goshawk","value":"Northern Goshawk"}

so what we want is to check 'value's if each begins with the entered term.
you can simply replace your autocomplete code with this one:

.autocomplete({
    source: function( request, response ) {                            
            $.ajax({
            url: "/controller/myfunction",
            dataType: "json",
            data: request,
            success: function(data){
                if(data.response == 'true') {
                    var t = true;
                    var i = 0;
                    var ptrn = new RegExp("^" + request.term, "i");
                    while (t) {
                        if (!ptrn.test(data.message[i].Name)) {
                            data.message.splice(i, 1)
                        } else {
                            i++
                        };
                        if (i == data.message.length) {
                            t = false;
                        }
                    }
                    response(data.message);
                }
            }
        });
    },
    ...
});
Mahyar
  • 681
  • 6
  • 12
0
 $("#certi_name").autocomplete({
                source: "/controller/myfunction",
                minLength: 2,
                select: function(event, ui) {
                    $('#certi_name').val(ui.item.value);
                    $('#certi_id').val(ui.item.id);

                }
            });

Here is my function. I am using it and working fine.

function certificationsAction()
    {
        $cert_obj = new Model_Certification();
        $obj=$this->getRequest();
        $term=$obj->getParam('term');//You will get passing keyword with the name term
        if($term)
        {
            $ins_arrs=$cert_obj->getMatchingCertifications($term);
            $return_arr = array();
            foreach($ins_arrs as $ins)
            {
                $row_arr['id']=$ins['certification_id'];
                $row_arr['value']=$ins['certification_name'];
                array_push($return_arr, $row_arr);
            }
            echo json_encode($return_arr);die;
        }

    }
Amit Garg
  • 3,867
  • 1
  • 27
  • 37