Search code examples
jquerytwitter-bootstrap-3datepickermodal-dialogdraggable

Draggable blocking opening of Bootstrap datepicker inside of modal (mobile)


I'm having problems with getting the Bootstrap datepicker to show on mobile devices. The datepicker is inside of a draggable modal, and everything works as expected when viewed on a desktop / laptop.

I'm also using Touch Punch, to handle draggablity on mobile devices.

I've tried:

  • changing the order of including the scripts (currently it's jQuery, jQuery-UI, Bootstrap, Bootstrap Datepicker)
  • disabling the line which makes the modal draggable (datepicker activates on mobile, but the modal is stuck in place)
  • changing when the click event handler is attached (after draggable, before draggable, together with draggable)
  • being cheeky by using this: $('.date-picker2 input').on('click',function(){ $(this).focus().blur();});
  • changing the z-index for the bootstrap datepicker calendar, because I thought it was activating, just not being shown
  • attaching a custom click event with a simple alert("click?"); - which did absolutely nothing, meaning that the click is not registered
  • adding a border around the elements, to check if anything is overlapping anything else, effectively preventing the click from reaching the datepickers

and the issue persists. I'm guessing there was something in the updates for Chrome for Android and iOS which broke the functionality (used to work before).

Can anyone offer any advice on how to proceed?

The pen can be found here: https://codepen.io/hFrantz/full/eYRboew

The code is as follows.

HTML

<div class="calculator-modal">
    <div style="margin: 10px 10px 0px 5px;">
        <button  class="btn btn-sm calculator-modal-close pull-right"><i class="fa fa-times text-danger"></i></button>
    </div>

    <div style="padding:0px 10px 10px 5px;">
        <div class="drag">
            <h5 id="dragMe" class="text-left text-primary" style="width:92%"><strong>Drag me!</strong></h5>
            <h4 class="text-left" >Calculator</h4>
            <div class="hr2"></div>

            <h3 class="text-left" style="margin-top:10px;"><strong class="priceCalculator">123</strong><small> per day</small></h3>
        </div>
        <div class="hr2"></div>

        <div class="calculatorForm">
            <form>
                <label>Date</label>
                <div class="input-group date-picker2 input-daterange" data-date="dd.mm.yyyy" data-date-format="dd.mm.yyyy">
                    <input class="form-control" type="text" id="calcStart" name="calcStart" value="28.09.2021">
                    <span class="input-group-addon"> do </span>
                    <input class="form-control" type="text" id="calcEnd" name="calcEnd" value="28.09.2021">
                </div>
                <br>
                <label>Persons</label>
                    <select class="form-control" id="selPersons">
                        <option class="persons" value="1">1</option>
                        <option class="persons" value="2">2</option>
                        <option class="persons" value="3">3</option>
                        <option class="persons" value="4">4</option>
                        <option class="persons" value="5">5</option>
                </select>
            </form>
        <br>
        <hr style="margin-bottom:10px">
        <div>
            <h4>
                <strong class="pull-left">Total 
                    <i class="fa fa-question-circle cursor-pointer tooltips" data-placement="right" data-original-title="Total cost"></i>
                </strong>
                <strong class="pull-right totalCalculator">123</strong>
            </h4>
        </div>
        </div>
        <br>
        <br>
        <div class="text-right">
            <button class="btn btn-default calculator-modal-close">Close</button>
        </div>
    </div>
</div>
<div class="calculator">
    <button id="calculator-btn" class="btn btn-danger"> <i class="icon-calculator"></i> </button>
</div>

CSS

.calculator {
    display: inline-block;
    padding: 2px;
    text-align: center;
    position: fixed;
    z-index: 1001;
    bottom: 80px;
    left: 10px;
}
#calculator-btn{
    padding: 15px;
    border-radius: 100% !important;
}
#calculator-btn>i{
    font-size: 20px !important;
}
.calculator-modal  {
    height: auto !important;
    width: 400px;
    background-color: #fff;
    display: none;
    padding:  0px 2px 2px 2px;
    text-align: center;
    position: fixed;
    z-index: 9998;
    bottom: 15px;
    left: 80px;
    border-radius: 6px;
    border: 1px solid rgba(0,0,0,.2);
    box-shadow: 0 5px 15px rgba(0,0,0,.5);
}
@media (max-width: 991px) {
    .calculator-modal  {
    /*  overflow-y:scroll;
        max-height: 500px; */
        
        width: 400px; 
    }
}
@media (max-width: 767px) {
    .calculator-modal  {
        max-height: auto;
        width: 350px;
    }
}
@media (max-width: 480px) {
    .calculator-modal  {
        height: auto;
        width: 90%; 
    }
    .datepicker {
        left: 60px !important;
    }
    .mobileNone {
        display: unset;
    }
    .parent {
        position:relative;
    }
    .scrollMeHorizontally {
        overflow-x: scroll !important;
    }
    .parent table {
        width: 110vw !important;
        max-width: 110vw !important;
    }
    .sRight {
        margin-right:-12px;
        transform: scale(0.8) rotate(-90deg);
    }
    .sLeft {
        margin-left:-12px;
        transform: scale(0.8) rotate(90deg);
    }
    .sRight, .sLeft {
        top: 57%;
    }
    table, table > thead > tr > th, table > tbody > tr > td {
        vertical-align: middle !important;
    }
}
.drag{
    cursor:pointer;
}

#dragMe {
    background-color: #428bc2;
    color: #fff;
    padding:7px;
}

JS

$('body').on('click', '#calculator-btn, .openCalculator', function(e){
    e.preventDefault();
    $('.calculator-modal').toggle();
    if($('.calculator-modal').css('display').trim() == 'none') {
        fixCalculator();
    }
});

$('.calculator-modal-close').click(function(e){
    e.preventDefault();
    $('.calculator-modal').hide();
    fixCalculator();
});

$('.date-picker2').datepicker({
    language: 'sr-latin',
    orientation: "left",
    autoclose: true,
    todayHighlight: true
});

$('body').on('click', '#calcStart', function(){ 
    $('.datepicker').removeClass('datepicker-orient-right');
    $('.datepicker').addClass('datepicker-orient-left');
    $('.datepicker2').show();
});

$('body').on('click touchstart', '#calcEnd', function(){
    $('.datepicker').removeClass('datepicker-orient-left');
    $('.datepicker').addClass('datepicker-orient-right');
    $('.datepicker2').show();
});

$('.calculator-modal').draggable();

function fixCalculator() {
    $('.calculator-modal')
        .css('inset','')
        .css('left','')
        .css('right','')
        .css('top','')
        .css('bottom','')
        .css('height','')
        .css('width','')
        .css('display','');
}

Solution

  • The trouble was with the TouchPunch library, as I later found out in this GitHub thread:

    https://github.com/furf/jquery-ui-touch-punch/issues/306

    The issue was resolved with the fix at the bottom of the conversation:

    My fork has implemented a similar solution - it assumes that you mean a click if you hold your finger down for less than 500ms, or if you move your finger less than 10px in any direction

    https://github.com/RWAP/jquery-ui-touch-punch

    Once I replaced the old TouchPunch with the edited version, and added:

    $('.date-picker2 input').on('click',function(){ $(this).focus().blur();});

    the initial problem was gone.