Using jQuery 2.1.0 and jQuery.ui 1.11.0 Tested in iOS 7. iPhone and iPad Mini. Works on android and regular browsers.
We recently upgraded from
Building on onlydimon’s solution:
var input = $("#input")
// Initialize autocomplete
input.autocomplete()
// Retrieve the autocomplete list and remove the mouseenter event
// which seems to trip up iOS Safari
input.autocomplete('widget').off('mouseenter')
I narrowed down the list of events to just jQuery's 'mouseenter' event. Removing just this one fixes the bug for me. Also, no need to remove it every time the list is opened; once is enough.
This code works with autoFocus
$("#input").autocomplete({
source: ["Test 1", "Test 2", "Test 3", "Test 4", "Test 5"],
autoFocus: true,
focus: function(event, ui) {
if (navigator.userAgent.match(/(iPod|iPhone|iPad)/) && event.bubbles) {
$(this).data("ui-autocomplete")._trigger("select", "autocompleteselect", {item: ui.item} );
$(this).autocomplete("close");
}
return false;
},
select: function(event, ui) {
$(this).val(ui.item.label);
}
});
Wrote a super nasty hack which seems to do the trick for me. Here's what I did.
(optional) Try once more... in case the set time wasn't long enough for the element to gain the ui-state-focus class.
$('.autocompleteContainer').on('touchstart', 'li.ui-menu-item', function(){
var $container = $(this).closest('.autocompleteContainer'),
$item = $(this);
//if we haven't closed the result box like we should have, simulate a click on the element they tapped on.
function fixitifitneedsit() {
if ($container.is(':visible') && $item.hasClass('ui-state-focus')) {
$item.trigger('click');
return true; // it needed it
}
return false; // it didn't
}
setTimeout(function () {
if (!fixitifitneedsit()) {
setTimeout(fixitifitneedsit, 600);
}
}, 600);
});
Hopefully someone has a nicer solution though!
Based on Liam Johnston
solution, I wrote this one which work for me with autoFocus set to true:
var movedWhildAutocomplete = false;
$(document)
.on('touchstart', '.ui-autocomplete li.ui-menu-item', function(){
$(this).trigger('mouseenter');
movedWhildAutocomplete = false;
})
.on('touchmove', '.ui-autocomplete li.ui-menu-item', function(){
movedWhildAutocomplete = true;
})
.on('touchend', '.ui-autocomplete li.ui-menu-item', function(){
if (!movedWhildAutocomplete) {
var $el = $(this);
if ($el.is(':visible') && $el.hasClass('ui-state-focus')) {
$el.trigger('click');
}
}
movedWhildAutocomplete = false;
});
For some strange reason @onlydimon's
answer didn't work for me. It seems like we do need event mouseenter
. Following answer worked well for me.
open: function (result) {
if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
$('.ui-autocomplete').off('menufocus hover mouseover');
}
},
I have added a condition to make sure that it doesn't break in other devices.
Just a bit later, but
$("#input").autocomplete({
open: function(event, ui) {
$('.ui-autocomplete').off('menufocus hover mouseover mouseenter');
}
});