3

Can I use data attribute for the source of my autocomplete?

for example

HTML

 <input type="text" class="autocomplete" data-source="/search.php" />

Javascript

  $(".autocomplete").autocomplete({
        source :  $(this).data('source'),
        minLength:1,
        select: function( event, ui ) {
            console.log( ui.item ?
                "Selected: " + ui.item.value + " aka " + ui.item.id :
                "Nothing selected, input was " + this.value );
        }
    });

I tried it but it always gives me an error. What's wrong with my code?

Uncaught TypeError: Property 'source' of object #<Object> is not a function

2
  • This is not a good solution. On every key press you're reinitializing the autocomplete widget, which means even after moderate use, hundreds of event listeners will be added to each .autocomplete element. I strongly recommend you use another solution. (Perhaps one of the three listed below?) Commented Mar 19, 2012 at 3:49
  • If you fixed it, write an answer. Answers do not go in questions. Commented Mar 20, 2012 at 12:14

4 Answers 4

7

In source you can use this.element which refers to the input

$(".autocomplete").autocomplete({
   source :  this.element.attr('data-source'),
   minLength:1,
   select: function( event, ui ) {
   console.log( ui.item ?
            "Selected: " + ui.item.value + " aka " + ui.item.id :
            "Nothing selected, input was " + this.value );
    }
});
Sign up to request clarification or add additional context in comments.

2 Comments

Good answer. Nice and simple :-)
In my context, this is referring to the window element so this solution doesn't work. I want to avoid referring to the data-source without referring to the .autocomplete class.
6

here's the fix

$('.autocomplete').keypress(function(){ 
    $(this).autocomplete({ 
        source: $(this).data('source'), 
        minLength: 1, 
        select: function(event, ui) { 
            console.log(ui.item ? "Selected: " + ui.item.value + " aka " + ui.item.id : "Nothing selected, input was " + this.value); 
        } 
    }); 
}); 

I added a keypress function so that it will get the current element.

2 Comments

Great solution, always wondered how to do this. Personally I substituted with a .each otherwise (presumably) the whole autocomplete gets rebound each time you have a keypress.
So this is quite bad as it instantiates the autocomplete control every single time a key is pressed in that box. You can just get $('.autocomplete').data('source') separately and then pass that in to the autocomplete call.
1

The this pointer does not refer to the .autocomplete element -- this only equals the selected element inside callbacks executed by jquery. It looks like you want to do something like this:

$(".autocomplete")
    .autocomplete({
        minLength:1,
        select: function( event, ui ) {
            console.log( ui.item ?
                "Selected: " + ui.item.value + " aka " + ui.item.id :
                "Nothing selected, input was " + this.value );
        }
    })
    .each(function() { // Goes through `.autocomplete` elements and sets source
        $(this).autocomplete("option", "source", $(this).data('source'));
    })
;

1 Comment

I'm not 100% sure what you mean, but it sounds like a server side problem. Make sure you're server side code filters your list by the value in the url query parameter called term.
1

every keystroke of autocomplete will trigger a remote request if the source is a url. what you can do to prevent that is to "pre-fetch" the data (make sure to return a JSON-valid array), then add the return data as the source for the autocomplete. that way, data is only fetched once, and autocomplete will reference to that data.

jQuery autocomplete already has a filtering capability. you just need a full list of items and it will filter it for you.

//get all input boxes with class "autocomplete"
$('.autocomplete').each(function(){

    //reference input and get it's url
    var input = $(this);
    var url = input.data('source');

    //get list array only ONCE for each input using their specified urls
    $.get(url, function(data) {

        //when request is received, add autocomplete using the returned data
        input.autocomplete({
            source: data,
            minLength: 1,
            select: function(event, ui) {
                console.log(ui.item ? "Selected: " + ui.item.value + " aka " + ui.item.id : "Nothing selected, input was " + this.value);
            }
        });
    });
});

1 Comment

thanks but I have many autocomplete elements. it only gets the data-source of the first element

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.