danwild
danwild

Reputation: 2046

Google Places Autocomplete with Jquery Mobile not working on mobile/touch device

As title suggests I am building a mobile website with JQuery Mobile (1.3.0) and am trying to implement Google Places Autocomplete (API v3) to aid user input of location data.

The autocomplete functions correctly on desktop device, but not when used on a mobile device (I have only tested on iOS 6).

When used on mobile device the dropdown list of relevant locations do appear, but simply disappear when you press one without loading the selection on the map.

I have looked around and seen some solutions that sight the z-index of

.pac-container

as the culprit (see: http://osdir.com/ml/google-maps-js-api-v3/2012-01/msg00823.html).

I have implemented these fixes but to no avail, and I am not convinced that z-index is the problem because I can see that the selected item does change to it's :hover state/colour when pressed on mobile.

Please if anyone has suggestions I am all ears, need any more details let me know.

Upvotes: 7

Views: 7078

Answers (5)

LiamD
LiamD

Reputation: 2028

I've also encountered this bug, and determined fastclick to be the culprit. I was originally going to go with Devin Smith's answer, but epegzz's warning about MutationEvents being deprecated led me to MutationObservers, and since I haven't seen a fix involving them I thought I'd share my solution.

var observer_config = { attributes: false, childList: true, subTree: false, characterData: false }
var observer = new MutationObserver( function(mutations) {
    var self = this;
    mutations.forEach(function(mutation){

        // look for the container being added to the DOM
        var pac_container_added = $(mutation.addedNodes).hasClass('pac-container');
        // if it is, begin observing it
        if (pac_container_added){
            var pac_container = mutation.addedNodes[0];
            self.observe(pac_container, observer_config);
        }

        // look for pac-items being added (as children of pac_container)
        // This will not resolve if the observer on pac-container has not been created
        var pac_item_added = $(mutation.addedNodes).hasClass('pac-item');
        // when pac items are added, add the needsclick class
        if (pac_item_added) {
            $('.pac-item, .pac-item span').addClass('needsclick')
        }
    });
});
observer.observe(document.body, observer_config);

It is more complex than I'd like it to be because we can't just add observer.observe('pac_container') in the top level, since its added asynchronously. Luckily, the solution for that problem is also MutationObservers.

We add another observer to pac_container when it is created. That way, it detects the pac-items being added, and when they are, we add the needsclick class.

This is my first time using MutationObservers, so feedback/improvements would be appreciated. As you can see, I used both jquery, but it should be pretty easy to pull it out.

Upvotes: 2

epegzz
epegzz

Reputation: 865

There is a patch for fastclick that makes it work well with google places autocomplete. See This answer :)

Upvotes: 1

Space Devin
Space Devin

Reputation: 1137

Saravanan's answer is a bit overkill. To fix the conflict with FastClick and PAC, add the needsclick class to both the pac-item and all its children.

$(document).on({
    'DOMNodeInserted': function() {
        $('.pac-item, .pac-item span', this).addClass('needsclick');
    }
}, '.pac-container');

Upvotes: 11

Saravanan S
Saravanan S

Reputation: 1043

Thanks Daniel. But the solution I have given has some performance impact.

I have modifed the FastClick library little bit to accomplish that.

First I have added a param to FastClick constructor, where defaultElCls will be the elements which should not implement fastclick.

function FastClick(layer, defaultElCls) {
    'use strict';
    var oldOnClick, self = this;

    this.defaultElCls = defaultElCls;

Then modify needsClick method:

FastClick.prototype.needsClick = function(target) {
'use strict';
var nodeName = target.nodeName.toLowerCase();

if (nodeName === 'button' || nodeName === 'input') {

    // File inputs need real clicks on iOS 6 due to a browser bug (issue #68)
    // Don't send a synthetic click to disabled inputs (issue #62)
    if ((this.deviceIsIOS && target.type === 'file') || target.disabled) {
        return true;
    }       
} else if (nodeName === 'label' || nodeName === 'video') {
    return true;
}

return ((/\bneedsclick\b/).test(target.className) || (new RegExp(this.defaultElCls).test(target.className)));

};

Then pass pac-item to the FastClick constructor

new FastClick(document.body, "pac-item");

Hope this will be taken care by FastClick library as well :)

Upvotes: 4

danwild
danwild

Reputation: 2046

After much hair pulling I have found the problem to be the "FastClick" library I added to my project.

As @Saravanan Shanmugam points out in this comment https://stackoverflow.com/a/16932543/1177832

FastClick seems to interfere with autocomplete. Also see above link for the workaround he has added to get the two to play nice.

Upvotes: 0

Related Questions