lumapps / lumX

The first responsive front-end framework based on Angular & Google Material Design specifications

Home Page:https://ui.lumapps.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

lx-select with filter closes automaticly on touch on mobile device

Nebulosar opened this issue · comments

Motivation for or Use Case - Users need to be able to use the filter of the lx-select component properly without it clsoing instantly when no touchmove event has been fired.
LumX Version(s) - 1.9.11
Browsers and Operating System - Mobile devices (iOS and Android) browsers (Safari, FireFox Nightly 78.0a1, Chrome Mobile 81.0.4004.138, DuckduckGo 5.55.1 (Yes DDG has an awesome privacy browser))
Reproduce the Error - See the demo site, it has the same functionality or check the snippets in this issue

The lx-select component seems to be automaticly closing when using a mobile device.

This seems default behaviour, for the demo site shows the same behaviour. Although default, it does not seems like a feature.

The problem occurs when a lx-select component with lx-display-filter is used:

<lx-select
        ng-model="awesomePerson"
        lx-allow-clear="true"
        lx-choices="persons"
        lx-display-filter="true"
        lx-filter="getPersons(newValue)"
        lx-helper="!persons.length"
        lx-helper-message="Search for that one person"
        lx-loading="loading"
        ng-disabled="!isAwesomenessNeeded">

        <lx-select-selected>
          {{ $selected.Name}} {{ $selected.levelOfAwesomeness }}
        </lx-select-selected>

        <lx-select-choices>
          {{ $choice.Name}}
        </lx-select-choices>
</lx-select>

I took a look at the source code and I think I found the source of the problem:

$document.on('click touchend', onDocumentClick);

...
function onDocumentClick() {
    $timeout(function nextDigest() {
        LxDropdownService.close(lxDropdown.uuid, true);
    }, 250)
}

function openDropdownMenu()
{
    $document.on('click touchend', onDocumentClick);

    $document.on('touchmove', function onTouchMove(evt) {
        $document.off('touchend', onDocumentClick);
    });
...

The event touchend seems to always be triggered when a touch device taps the screen, this makes the modal close ( $document.on('click touchend', onDocumentClick);)

My wack-around in AngularJs is to fire a touchmove event manually when opening the dropdown:

(function (angular) {
  "use strict";
  /**
   * This directive inject upon the value lx-display-filter of the lx-select component
   * It makes sure a touchmove event is triggered
   * Reason: Touch devices close the dropdown on "touchend"
   * Firing "touchmove" makes sure this "touchend" event is detached for the dropdown mask
   */
  angular.module('myOwnAwesome.directives')
    .directive('lxDisplayFilter', ['$document', '$timeout', function($document, $timeout) {
      return {
        restrict: "A",
        link: function (scope) {
          // only issue this link on touch devices
          if ('ontouchstart' in window || navigator.maxTouchPoints) {

            var $initFilterWatch = scope.$watch(function () {
              var filters = angular.element('.lx-select-choices');
              return filters.length ? filters : false;
            }, function (filters) {
              if (filters) {

                $initFilterWatch();
                _.each(filters, function (filter) {
                  // watch the height of the dropdown to determine if it was opened
                  scope.$watch(function () {
                    return filter.clientHeight;
                  }, function (oldHeight, newHeight) {
                    // newHeight higher than oldHeight? Than it has opened
                    if (newHeight > oldHeight) {
                      // timeout to make sure $digest() has been called
                      $timeout(function () {
                        // trigger "touchmove" event to detach "touchend" event
                        $document.triggerHandler('touchmove');
                      }, 1);
                    }
                  });
                });

              }
            });

          }
        }
      };
    }]);
})(angular);

Any ideas on how to fix this permanently?