Bind jQuery UI autocomplete using .live()
Asked Answered
E

12

65

I've searched everywhere, but I can't seem to find any help...

I have some textboxes that are created dynamically via JS, so I need to bind all of their classes to an autocomplete. As a result, I need to use the new .live() option.

As an example, to bind all items with a class of .foo now and future created:

$('.foo').live('click', function(){
  alert('clicked');
});

It takes (and behaves) the same as .bind(). However, I want to bind an autocomplete...

This doesn't work:

$('.foo').live('autocomplete', function(event, ui){
  source: 'url.php' // (surpressed other arguments)
});

How can I use .live() to bind autocomplete?

UPDATE

Figured it out with Framer:

$(function(){
  $('.search').live('keyup.autocomplete', function(){
    $(this).autocomplete({
      source : 'url.php'
    });
  });
});
Excursionist answered 29/12, 2010 at 3:19 Comment(2)
As an update, live() is deprecated, now on() is used to do this, like: $(document).on("keyup.autocomplete", '.autocomplete', function(){ $(this).autocomplete({ ... }); })...Multifid
Is there any way to achieve this behavior without calling the autocomplete method for every element added, instead calling the autocomplete method once and only once?Photomicroscope
S
18

If you are using the jquery.ui.autocomplete.js try this instead

.bind("keydown.autocomplete") or .live("keydown.autocomplete")

if not, use the jquery.ui.autocomplete.js and see if it'll work

If that doesn't apply, I don't know how to help you bro

Sojourn answered 29/12, 2010 at 3:30 Comment(3)
I am using ui.autocomplete, and you binding works :). I can trigger an alert... but that doesn't actually make it an autocomplete... If i try what I've updated in my answer, I get syntax errors...Excursionist
This doesn't make any sense to me. autocomplete still hasn't been added to the new element yet so you can't bind to any events it generates. the correct answer is the one below by Dan.Basle
This answer is garbled, here is correct answer that should be accepted https://mcmap.net/q/299122/-bind-jquery-ui-autocomplete-using-livePornocracy
M
70

jQuery UI autocomplete function automatically adds the class "ui-autocomplete-input" to the element. I'd recommend live binding the element on focus without the "ui-autocomplete-input" class to prevent re-binding on every keydown event within that element.

$(".foo:not(.ui-autocomplete-input)").live("focus", function (event) {
    $(this).autocomplete(options);
});

Edit

My answer is now out of date since jQuery 1.7, see Nathan Strutz's comment for use with the new .on() syntax.

Memnon answered 31/5, 2011 at 21:30 Comment(5)
This is the correct answer. Binding on keyup does not seem to bind for the very first keystroke. Very clever thinking. Thanks.Matriculate
I adapted this to work with the datepicker and updated it to use the newer on() syntax. Here's my code (sorry for the lack of formatting): $(document).on("focus", ".dateField:not(.ui-datepicker-input)", function(event) { $(this).datepicker({dateFormat:"mm/dd/yy"}); });Murchison
@NathanStrutz You just saved me! When you do an AJAX refresh of form elements in Drupal 7, your code is the only thing which still worked! Thanks!Pavo
$( document ).on( "focus",".foo:not(.ui-autocomplete-input)",function (event) { $(this).autocomplete(options); });Sennar
This is brilliant, I was concerned the autocomplete would be bound more than once. Your answer removes my concerns :)Carrasquillo
S
18

If you are using the jquery.ui.autocomplete.js try this instead

.bind("keydown.autocomplete") or .live("keydown.autocomplete")

if not, use the jquery.ui.autocomplete.js and see if it'll work

If that doesn't apply, I don't know how to help you bro

Sojourn answered 29/12, 2010 at 3:30 Comment(3)
I am using ui.autocomplete, and you binding works :). I can trigger an alert... but that doesn't actually make it an autocomplete... If i try what I've updated in my answer, I get syntax errors...Excursionist
This doesn't make any sense to me. autocomplete still hasn't been added to the new element yet so you can't bind to any events it generates. the correct answer is the one below by Dan.Basle
This answer is garbled, here is correct answer that should be accepted https://mcmap.net/q/299122/-bind-jquery-ui-autocomplete-using-livePornocracy
R
9

Just to add, you can use the .livequery plugin for this:

$('.foo').livequery(function() {

    // This will fire for each matched element.
    // It will also fire for any new elements added to the DOM.
    $(this).autocomplete(options);
});
Roseberry answered 29/12, 2010 at 3:42 Comment(2)
This is the best, and ever coolest plugin i ever found! This will works also with datepicker i suppose! I was searching for this since i work with jquery... I can only vote up one time.... my bad...Maxie
Very Recommended Plugin, this will remove your headacheZealot
R
8

To get autocomplete working when loaded dynamically for the on() event used in jQuery > 1.7, using the syntax Nathan Strutz provides in his comment:

$(document).on('focus', '.my-field:not(.ui-autocomplete-input)', function (e) {
    $(this).autocomplete(options)
});

where .my-field is a selector for your autocomplete input element.

Relume answered 25/7, 2013 at 16:24 Comment(0)
A
5

.live() does not work with focus. also keyup.autocmplete does not make any sense. Instead the thing I have tried and working is this

 $(document).ready(function(){
$('.search').live('keyup' , function()
  { 
    $(this).autocomplete({ source : 'url.php' }); 
  });
})

This works perfectly fine.

Adsorbate answered 7/7, 2011 at 20:23 Comment(0)
R
3

You can't. .live() only supports actual JavaScript events, not any custom event. This is a fundamental limitation of how .live() works.

Rigsdaler answered 29/12, 2010 at 3:27 Comment(0)
B
2

You can try using this:

$('.foo').live('focus.autocomplete', function() {
    $(this).autocomplete({...});
});
Brittaniebrittany answered 12/1, 2012 at 14:24 Comment(0)
S
2

After reading and testing everyone else's answers I have updated it for the current version of JQuery and made a few tweaks.

The problem with using keydown as the event that calls .autocomplete() is that it fails to autocomplete for that first letter typed. Using focus is the better choice.

Another thing I have noticed is that all of the given solutions result in .autocomplete() being called multiple times. If you are adding an element dynamically to the page that will not be removed again, the event should only be fired once. Even if the item is to be removed and added again, the event should be removed and then added back each time the element is removed or added so that focusing on the field again will not unnecessarily call .autocomplete() every time.

My final code is as follows:

$(document).on('focus.autocomplete', '#myAutocomplete', function(e){
    $(this).autocomplete(autocompleteOptions);
    $(document).off('focus.autocomplete', '#myAutocomplete');
});
Stygian answered 28/2, 2013 at 19:55 Comment(2)
This is the best answer I've seen but still not what I was looking for. I thought the point of the 'on' method was that you bind to the nearest parent that you know WON'T get replaced so you only ever bind once. Here you are one time binding to a function that binds the autocomplete every time new elements are added. Doesn't this miss the point a little bit? I.e. the autocomplete binding is being run every time new input elements are added instead of just once.Photomicroscope
You are correct about on(), but autocomplete is not an event. Each time the element is replaced the autocomplete function needs to be called on that element again. You could implement it so that calling autocomplete is part of replacing the element or you could set up an event listener that automatically calls autocomplete when you focus on any element that has the "autocomplete" class. One way or another autocomplete needs to be called every time the element is replaced. I am open to other people's solutions and I hope the jQuery team addresses this drawback in a future release.Stygian
C
1

autocomplete is not an event rather a function that enables autocomplete functionality for a textbox.

So if you can modify the js that creates the textboxes dynamically to wrap the textbox element in as a jquery object and call autocomplete on that object.

Cottingham answered 29/12, 2010 at 3:27 Comment(0)
S
1

I just noticed you edited your post with this answer. It was obvious to me so I'm posting it below for others. Thank you.

$(function() 
{
  $('.search').live('keyup.autocomplete', function()
  { 
    $(this).autocomplete({ source : 'url.php' }); 
  });
});
Santos answered 1/4, 2011 at 0:25 Comment(1)
This turns .search elements into an autocompleting element after a key is pressed. Autocompletion should be working BEFORE any key is pressed and it should only be initialized once instead of after each keyup event.Stygian
M
1

This works for me:

$(function() 
{
  $('.item_product').live('focus.autocomplete', function()
  { 

    $(this).autocomplete("/source.php/", {
        width: 550,
        matchContains: true,
        mustMatch: false,
        selectFirst: false,
    }); 

  });
});
Millenary answered 16/2, 2012 at 1:11 Comment(0)
H
0

You can just put the autocomplete inside input live event, like this:

$('#input-element').live('input', function(){
  
$("#input-element").autocomplete(options);

});
Hepsiba answered 13/6, 2017 at 16:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.