Marcoscdoni
Marcoscdoni

Reputation: 985

Select2 Friendly on mobile

I'm aiming to make select2 friendlier on mobile devices and so I'm using css styles to display the result of select2 items above all elements of the page.

I am able to do this, however I have a problem related to the click event in the select. If I call select2 manually (not by the select control), the result is displayed correctly, however when I click directly on the select control, the result is displayed, but apparently the click event on the select control propagates as if it were clicked on an options of the select, causing the results screen to be closed shortly after opening.

Example:

Html:

<body>
    <div id="main" style="margin-top: 150px;">
    <select id="example" class="js-example-basic" style="min-width: 200px; margin-top: 200px">
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
        <option value="3">Option 3</option>
        <option value="4">Option 4</option>
        <option value="5">Option 5</option>
        <option value="6">Option 6</option>
    </select>
    <button id="openSelect">Show as Popup (Correctly)</button>
    </div>
    </body>

Css

.overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0,0,0,0.5);
    z-index: 9999999;
    font-size: 18px;
    -webkit-transition: all .4s;
    transition: all .4s;

}


.select2-results {   
    height: 90% !important;
}




.select2-results__options {
    max-height: 100% !important;
    height: 100% !important;
    overflow-y: scroll !important;
}




    .select2-dropdown--below {
    display: block !important;
    position: fixed !important;
    top: 0px !important;
    left: 0px !important;
    background: white !important;
    width: 250px !important;
    height: 100%;
    z-index: 3000 !important;

}

JQuery

$(document).ready(function() {


$('#example').select2({
});


});

$("#openSelect").click(function() {

$('#example').select2("open");

});


$('#example').on('select2:opening', function (e) {
  $('body').addClass("overlay");
});

$('#example').on('select2:closing', function (e) {
  $('body').removeClass("overlay");
});

https://jsfiddle.net/m7n8Lsgc/

I suppose it might be possible to intercept just the click on the select through the 'select2: opening' event, but I'm not getting any success on it.

Any suggestions on how to get around this?

Upvotes: 2

Views: 6227

Answers (1)

Yoga
Yoga

Reputation: 51

It is old thread, but in case someone still need to get it working.

The behaviour is because the click event is propagated and catched by select2's _attachCloseHandler(). The _attachCloseHandler() will check for an open container, update the selection and close the container.

What I do, I just delay the opening of the dropdown container so that the check in _attachCloseHandler() will fail and the click event is ignored.

So in select2.js I change:

    Select2.prototype.toggleDropdown = function () {
      if (this.isDisabled()) {
        return;
      }

      if (this.isOpen()) {
        this.close();
      } else {
        this.open();
      }
    };

to

    Select2.prototype.toggleDropdown = function () {
      if (this.isDisabled()) {
        return;
      }

      if (this.isOpen()) {
        this.close();
      } else {
        let that=this;
        setTimeout(function() {that.open();}, 5);
      }
    };

The proper way is of course to find out where the click event propagation and cancel it if possible. But after tweaking a little bit, I didn't find where it is and I just needed a working solution fast.

Upvotes: 3

Related Questions