use lookup and/or service url in jquery autocomplete
Asked Answered
M

3

7

I have an autocomplete feature in my application which makes an ajax request to server. However, once I get data from server, I want to use the look up feature instead of using the service url(to minimize calls to server).

Here is what my js looks like

$('#country').autocomplete({
    serviceUrl : './countryCache?',
    paramName : 'countryName',
    transformResult : function(response) {
        return {
            // must convert json to javascript object before process
            suggestions : $.map($.parseJSON(response), function(item) {
                return {
                    data : item.name
                };
            })
        };
    },
    showNoSuggestionNotice:true,
    onSelect: function (value, data) {
        $('#countryId').val(value.data);

    }

});

Here is a sample from my ajax call to countryCache - "India, Iceland, Indonesia". If the user has typed I, the server returns back the result as above. Now when the user types in n after I, I dont want to make a call to server again. Can someone help me achieve it.

Mendy answered 25/10, 2014 at 10:12 Comment(0)
G
6

There is a simple solution for this in the jQuery UI Autocomplete documentation. There you'll find a section titled Remote with caching that shows how to implement what you are looking for.

I adapted the code from that site to this question, and added some comments for clarification:

var cache = {};
$( "#country" ).autocomplete({
    source: function( request, response ) {
        // If the term is in the cache, use the already existing values (no server call)
        var term = request.term;
        if ( term in cache ) {
            response( cache[ term ] );
            return;
        }

        // Add countryName with the same value as the term (particular to this question)
        // If the service reads the parameter "term" instead, this line can be deleted.
        request.countryName = request.term;

        // Call the server only if the value was not in the cache
        $.getJSON( "./countryCache", request, function( data, status, xhr ) {
            cache[ term ] = data;
            response( data );
        });
    },
    select: function (event, data) {
        $('#countryId').val(data.item.value);
    }
});

As I didn't know exaclty the format of the JSON, I just used a basic one that for the text "In" returned: ["India","Indonesia","Spain"] (without ids, just a plain array).


If what you are using is the Ajax AutoComplete plugin for jQuery (the code above looks like it, although the question was tagged with ), then you don't have to worry about caching, because the plugin does it automatically for you.

From the plugin's documentation:

noCache: Boolean value indicating whether to cache suggestion results. Default false.

As you didn't specify any value for nocache, then it will take the default value that is false, and it will perform caching directly.

Gehman answered 15/5, 2015 at 18:44 Comment(3)
Beat me to it :) The link to the documentation will show you everything you need and this example is pretty close to what you'd need. Just look for the "source" and that is where you'd find the logic for the matching and returning, put your condition just ahead of your ajax and you're gold.Parashah
The funny thing is that the code shown in the question is not for jQuery UI Autocomplete, but for the AutoComplete plugin that does caching by default. So the code in the question would be the answer tooGehman
This isn't jQuery UI, it's jquery-autocomplete.Mayle
M
0

I ended up not using this method at all and going with fast, quick searches with a limit of 100. But since I asked, here is how I sent requests using only the first character:

 // global variables: models [], result {}

          lookup: function(query, done) {

                var mdl = $("#autocomplete").val();
                if (mdl.length == 0) {
                    names = [];
                    result.suggestions = models;
                    done(result);
                    return;
                } else if (mdl.length != 1) {
                    result.suggestions = names;
                    console.log(result);
                    done(result);
                    return;
                }

                var jqHXR = $.ajax({url: "search.php",   
                        data: {"q": mdl},
                        dataType: "json",
                        method: "GET" }
                )
                .done(function(data, status, jqXHR){
                    models = [];
                    $.each( data, function( key, val) {
                        names.push({ value: val.u, data: { category: genders[val.g] } });
                    });

                    result.suggestions = names;
                    done(result);
                })
                .fail(function (data, status, errorThrown) {
                        console.log("failed: "+status+"| error: "+errorThrown);
                        console.log(data);
                });
            },
Mayle answered 16/5, 2015 at 6:37 Comment(0)
P
0

A colleague of mine used devbridge and my research seems to verify that there's an attribute for the devbridgeAutocomplete object for minChars and lookupLimit. Maybe there are different instances of devbridgeAutocomplete, but I thought it was worth posting just in case they're similar, though I should assume you would have seen them already :).

Here's the code:

var a =  $('#<%= txtFindName.ClientID %>').devbridgeAutocomplete({
           minChars: 3,
           lookupLimit: 20,
            serviceUrl: 'AutoComplete/ADUsers.aspx',
            onSelect: function (suggestion) {
                $('#<%= txtTo.ClientID %>').val( $('#<%= txtTo.ClientID %>').val() + ',' + suggestion.data);
                $('#<%= txtFindName.ClientID %>').val('');
            }
       });
Parashah answered 21/5, 2015 at 19:41 Comment(3)
minChars is how many characters before it starts the search, I believe.Mayle
Ah I guess you're right. In that case why not just add a condition on the length of the field before running the ajax. I think would be the simplest solution. I'll post it.Parashah
Then I see its in your other answer. Lookup attribute, add your logic there and then no more continuous calls.Parashah

© 2022 - 2024 — McMap. All rights reserved.