4

I'm trying to add FastClick to a site that already uses the Chosen jQuery plugin for selects. With FastClick, the selection boxes simply stop responding to taps on mobile browsers. This can also be replicated with Chrome device emulation.

You can test this for yourself on this simple jsFiddle:

<select id="foo">
    <option>Bar</option>
    <option>Asdf</option>
</select>

$("#foo").chosen()

Steps to replicate with Chome canary:

  1. Load http://fiddle.jshell.net/7ftdo0j3/3/show/
  2. Open developer tools and emulate Google Nexus 7 or Apple iPad 1/2 (others might work as well)
  3. Try to use the select.
OlliM
  • 7,023
  • 1
  • 36
  • 47
  • I've tried to add `needsclick` class to everything, as stated by fastclick documentation, with no luck. – OlliM Nov 19 '14 at 09:24
  • The fiddle you shared isn't working because the external links to chosen are broke... Once I fix the link it [seems to be working fine](http://jsfiddle.net/7ftdo0j3/2/) for me using chrome simulator... – T J Nov 22 '14 at 07:23
  • I tested your link and it's still broken: you can test it with e.g. "Google Nexus 7 2" as the device. (iOS is detected by chosen and the native functionality is used ([see Github](https://github.com/harvesthq/chosen/pull/1388)) – OlliM Nov 24 '14 at 09:11
  • Interestingly, it's working fine in Nexus 10, but if I emulate nexus 7, clicking the select will open a new tab asking to tweet the fiddle o.0 – T J Nov 24 '14 at 15:00
  • Do you get a native select box or the actual chosen box on your Nexus 10? Chosen is disabling itself on some browsers (at least iOS safari), which means that the select box works on those browsers even with FastClick. – OlliM Nov 24 '14 at 15:18
  • I get actual chosen select and I can select the items while emulating nexus 10 on chrome. But if I emulate 7 instead, clicking the select opens a new tab asking to post on twitter rather than opening the select... weird. – T J Nov 24 '14 at 15:30
  • I updated the jsfiddle link and added replication steps, I made a stupid mistake with the original fiddle, FastClick didn't actually load. – OlliM Nov 27 '14 at 09:17
  • Did you read [Disable Chosen on iOS devices](https://github.com/harvesthq/chosen/pull/1388)?Also [Chosen plugin doesn't seem to work on mobile browsers](http://stackoverflow.com/questions/22016578/chosen-plugin-doesnt-seem-to-work-on-mobile-browsers) – Alex Char Nov 27 '14 at 20:21
  • Alex: I've read that, and we have no problems with devices where chosen simply disables itself and we get native components. It's the touch (mobile / tablet) devices that chosen works on that are a problem with FastClick. – OlliM Nov 28 '14 at 07:53

1 Answers1

4

The main problem you have is that you try to use two libraries together, which both either manipulate or interpret touch event weirdly. I wanted to use the phrase "which both do some black magic with touch events", but as I have almost none experience in using the libraries in question, I felt that perhaps it's not appropriate ;)

Joking aside, the solution for your problem is to add FastClick's needsclick class to all DOM elements dynamically created by chosen:

$("#test").chosen();
$(".chosen-container *").addClass("needsclick");
FastClick.attach(document.body);

At least in my tests with the emulator this seemed to work. I'll tell you why I think it works.

I noticed when I added the needsclick class only to div.chosen-container and to its direct children, that sometimes a touch opened the dropdown and sometimes it didn't. When added to all children, touch starts to work flawlessly. I'm quite sure something like this happens there:

  • Chosen creates dynamicly div elements, which mimic a dropdown.
  • When user touches this kind of div, the original top-most element gets stores in the mouse event
    • Eg. if user touches the main text of the dropdown (which is a span element), that element gets stored in the event
  • FastClick checks needsclick only from this element
    • As none of the dynamicly created elements have that magic class, the touch event gets prevented and a click event is sent to that element instead
  • This would work otherwise, but it seems that Chosen does not listen to click events at all. You can test this one by trying to send one to a .chosen-container with jQuery:

$(".chosen-container").trigger('click');

It does not work. But when you send a mousedown event instead, dropdown opens:

$(".chosen-container").trigger('mousedown');

This might mean that perhaps on touch devices Chosen already listens touchstart or touchend events directly, and that would mean you wouldn't need FastClick with Chosen dropdowns even in the first place. Unfortunately I do not have a real test device now with me, so I can not guarantee this kind of happy ending for your voyage :D

We used Chosen in one project, and we had some event-related problems there as well. There is quite a much code related to event bindings in Chosen's source file, so I have to say I'm not completely sure what really happens there. But at least the explanation above made some sense in my wicked mind. Hope it helps you, and hope that you'll get your forms working once again.

cido
  • 454
  • 2
  • 1
  • Thanks for the thorough answer. It's not the silver bullet I was secretly hoping for, but the best (and only) answer to date. The tip about mousedown is really useful, I'll have to look more closely inside the chosen source code. – OlliM Nov 28 '14 at 07:58