20

This question was answered for the live() method, but the live() method has been deprecated as of jQuery 1.7 and replaced with the .on() method and this answer does not work for on().

Here's where it was answered before: Bind jQuery UI autocomplete using .live()

Anyone know how to do the same thing with on()?

If you change the syntax to something like

$(document).on("keydown.autocomplete",[selector],function(){...});

from

$([selector]).live("keydown.autocomplete",function(){...});

It kind of works, but it interacts with the internal autocomplete events in a weird way. With live(), if you use the select event and access the event.target, it gives you the id of the input element. If you use on(), it gives you the id of the dropdown menu "ui-active-menuitem". Something like this:

$( ".selector" ).autocomplete({
   select: function(event, ui) { 
     console.log(event.target.id);
 }
});

But - if you use the "open" event, it will give you the id I'm looking for - just not at the right time (I need it after it is selected). At this point, I'm using a workaround of grabbing the ID of the input element in the open event function, storing it in a hidden field, then accessing it in the select method where I need it.

Community
  • 1
  • 1
paul
  • 5,298
  • 2
  • 18
  • 23
  • Can you post a working example in [jsFiddle](http://jsfiddle.net)? I've [answered](http://stackoverflow.com/a/9531031/520779) a question that - from my understanding - is similar to your case, but I'm not sure I'm interpretting your question correctly (i.e. what you're trying to achieve). – mgibsonbr Mar 14 '12 at 00:02
  • It will take some time for me to extract my code from the larger application, but I can try. To provide more context, I have a form with an input field with autocomplete running on it. I need to use the live/on functionality to allow additional input fields to be added dynamically by clicking an add button, with the same autocomplete running on them. – paul Mar 14 '12 at 00:46

2 Answers2

23

If I understood correctly, your problem looks very similar to one I saw in another topic. I'll adapt my answer to your case, let's see if it solves your problem:

$(document).on("focus",[selector],function(e) {
    if ( !$(this).data("autocomplete") ) { // If the autocomplete wasn't called yet:
        $(this).autocomplete({             //   call it
            source:['abc','ade','afg']     //     passing some parameters
        });
    }
});

Working example at jsFiddle. I used focus instead of keydown because I need to re-trigger the event, and I don't know how to do it with key/mouse events.

Update: You could also consider using clone, if your additional inputs will have the same autocomplete as an existing one:

var count = 0;
$(cloneButton).click(function() {
    var newid = "cloned_" + (count++); // Generates a unique id
    var clone = $(source) // the input with autocomplete your want to clone
        .clone()
        .attr("id",newid) // Must give a new id with clone
        .val("") // Clear the value (optional)
        .appendTo(target);
});

See the updated fiddle. There are also jQuery template plugins that might make this solution easier (although I haven't used one myself yet, so I can't talk from experience).

Community
  • 1
  • 1
mgibsonbr
  • 21,755
  • 7
  • 70
  • 112
  • Thanks, this almost works. The autocomplete works, but some of the inner workings don't. As mentioned above, I need access to the 'select' event. From the docs: $( ".selector" ).autocomplete({ select: function(event, ui) { ... } }); With live() the 'event' param in the select function correctly holds the autocomplete input element. Try printing/logging event.target.id to see. Using on() with this syntax, event.target.id will always be #ui-active-menuitem, no matter which one was used. But I need to know the id of the input field in use. – paul Mar 14 '12 at 02:22
  • Also I don't think you need the if statement (if ( !$(this).data("autocomplete")) or the trigger and return false ( trigger("focus");return false;). I removed them and it works exactly the same as far as I can tell. – paul Mar 14 '12 at 02:29
  • You're right, the re-trigger would only be necessary if `autocomplete` needed to act on `focus`. As in my comment to your answer below, where key events are only handled from the second key press onwards (since the plugin is not yet called when the first key press happens). As for the `if`, it tries to avoid (attempting to) recreate the plugin at every key press (a well-behaved plugin, such as autocomplete, doesn't break on that, but others could). – mgibsonbr Mar 14 '12 at 22:53
12

This seems just to be some peculiarity of the interaction between .on() and autocomplete. If you want to do this:

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

This works with on():

$(function(){
  $(document).on("keydown.autocomplete",".search",function(e){
    $(this).autocomplete({
      source : 'url.php'
    });
  });
});

You can access the event.target.id of the element that the autocomplete was called on with the parameter of the on() callback function (e in the code above).

The difference is with on(), the event param in the internal events works differently, holding different values. With live(), the event.target.id in the select function will hold the ID of the selected input element. But with on(), the event.target.id in select will hold the ID of the list of autocomplete items (ui-active-menuitem). With on(), you can access the ID of the input element with event.target.id from the change and open functions.

paul
  • 5,298
  • 2
  • 18
  • 23
  • I couldn't reproduce that behavior in [my example](http://jsfiddle.net/mgibsonbr/mcSJC/), both `live` and `on` alerts `ui-active-menuitem`. Also, since the autocomplete is bound to `keyup` and `keydown` instead of `focus`, it only starts working after the second key press (which might be ok depending on your needs...) – mgibsonbr Mar 14 '12 at 22:51