0

Selection of words in an autocomplete input field (within a dialog) is not working properly when using JQuery UI in combination with Touch Punch. It seems to work if the autocomplete field is directly on the HTML page, but not in a dialog. Note that selection by mouse is working perfectly in all cases, but selection by touch (i.e. on mobile device) not.

I have reduced the whole case to a few lines of HTML and JavaScript code. Once with JQuery UI Touch Punch, once without JQuery UI Touch Punch.

I am able to reproduce the error with all combinations of browser and OS, e.g. Chrome on an iPhone, Chrome on an Android mobile as well as with Safari on an iPad,

Would be nice if somebody knows a workaround.

  • Perhaps you can add these few lines of `html` and `js`to your question so that other readers can have a quick look at it. And, if you ever decide to remove your nice example, this question would continue to provide help to other readers. – ventiseis Mar 14 '17 at 20:45

1 Answers1

0

I think this behavior is a result of the fact that on one the one hand Touch Punch developers are not that smart and on the other hand jQuery UI seems to be not very cooperative with Touch Punch.

There are two ways how mouse event might be triggered:

  • browser might simulate click events after touch events
  • some library might simulate click events after touch events

Your example without Touch Punch works because mobile browsers currently simulate click events.

So how Touch Punch works and how it messes things up? If you look at the source code https://github.com/furf/jquery-ui-touch-punch/blob/master/jquery.ui.touch-punch.js you'll see that it wraps $.ui.mouse.prototype._mouseInit with its own code and the main intention is to attach various touch-related listeners for all widgets that inherit $.ui.mouse. So far so good. But what exactly those listeners do? The _touchStart handler runs a check using $.ui.mouse internal API:

self._mouseCapture(event.originalEvent.changedTouches[0])

to check if it needs to simulate mouse events. The logic is: if there is no click handler in the widget, there is no need to simulate click. It looks OK at the first glance but what's going wrong? The autocomplete widget puts its dropdown menu to the outside context of the containing dialog and thus touch events on the menu items actually hit listeners registered by touch-punch for the dialog (or rather for its draggable and resizable sub-components). But the dialog subcomponents have no click listeners and thus events are not simulated by the library. Moreover, draggable in your version (see https://github.com/jquery/jquery-ui/blob/1-11-stable/ui/draggable.js) calls

this._blurActiveElement( event );

unconditionally and this seems to stop browser from generating mouse events. So now neither browser nor library simulate click event.

It seems that in the development branch of jQuery UI the bug is fixed https://github.com/jquery/jquery-ui/commit/8c66934434214ab92cbcf46240beb739154fdfbf but for a bit different reason. This fix seems to be available in the jQuery UI 1.12.1 but not in your 1.12.0

So the simplest solution seems to be to upgrade jQuery UI to 1.12.1

See working demo with jQuery UI 1.12.1 at https://jsfiddle.net/cjvgv102/1/ and http://jsfiddle.net/cjvgv102/1/embedded/result/

Ugly hack (stop here unless you really have to)

If for some reasons you can't upgrade jQuery UI, you can do a hack by explicitly creating a fake mouse object on the dropdown and calling its _mouseInit so event will not be handled by dialog's sub-components.

  $( "#demoDlg" ).dialog({
  autoOpen: false,
  modal: true,
  buttons: {
    "Close": function() {
      $( this ).dialog( "close" );
    }
  },
  open: function(event, ui) {
    $( "#words" ).autocomplete({
      source: ["these", "are", "some", "words"]
    });
    // super-hack
    $( "#words" ).autocomplete("instance").menu.element.mouse().mouse("instance")._mouseInit();
  }
});

See full demo at https://jsfiddle.net/3ptgks3t/1/

SergGr
  • 23,570
  • 2
  • 30
  • 51
  • Thanks SergGr Unfortunately, the JQuery UI 1.12.1 version doesn't seem to work either. But the "super-hack" does. Thanks for your analysis and help! – texasWINthem Mar 15 '17 at 19:15
  • @texasWINthem, It looks like my original JSFiddle link was wrong and still used jQuery UI 1.12.0. I updated link to actually use jQuery UI 1.12.1 (https://jsfiddle.net/cjvgv102/1/embedded/result/) and it seem to work for me on my iPad. Please, let me know if you still need a "hack" anyway, and tell me what device you use for testing. – SergGr Mar 15 '17 at 19:50
  • you are right, with the new link and 1.12.1 it is working as expected. Thanks! – texasWINthem Mar 17 '17 at 11:18