Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Nebulosar opened this issue May 29, 2020 · 0 comments
Open

Comments

@Nebulosar
Copy link

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant