jdewit / bootstrap-timepicker

[Deprecated] A simple timepicker component for Twitter Bootstrap
MIT License
1.64k stars 1.09k forks source link

The time picker popup widget was hidden #170

Open wuliupo opened 10 years ago

wuliupo commented 10 years ago

The time picker popup widget was hidden, if the container of time input has class overflow hidden.

How about append the time picker popup widget to BODY by default, like bootstrap-datepicker?

pgelinas commented 10 years ago

Adding the popup widget to the body requires a bit more work: you need to make sure to place the widget at the right place using some CSS manipulation with left-top. I've patched my local version of timepicker.js to make this work, but the patch requires the bootstrap-datepicker CSS to work properly.

I'm currently tidying the patch since my editor screwed the formating and then I'm going to try to make this work on its own. Right now the patch also handles changing the x and y orientation of the widget to make it look good and I think that's what requires the datepicker CSS. I'll keep the issue updated when I've reached certain milestone.

wuliupo commented 10 years ago

Hello @jdewit, @pgelinas This is my workaround,

var element; // this is the input element
element.timepicker();
//...

var timepicker = element.data('timepicker');
var widget = timepicker.$widget;
if (timepicker && widget && timepicker.appendWidgetTo === "body") {
    var widgetHeight = widget.height();
    // Fix the position of the bootstrap-timepicker-widget div, if it is appended to body
    var changePlace = function () {
        var offset = element.offset();
        var inputHeight = element.get(0).offsetHeight;
        var top;
        // Show widget up or below the input box
        if (offset.top + inputHeight + widgetHeight > document.height) {
            widget.addClass('dropdown-up');
            top = offset.top - widgetHeight;
        } else {
            widget.removeClass('dropdown-up');
            top = offset.top + inputHeight;
        }
        widget.css({
            top: top,
            left: offset.left
        });
    };
    element.on('show.timepicker', function (e) {
        changePlace();
    });

    // Watch the window resize event for the position of the time picker widget.
    var win = $(window);
    var resizeHandler = function () {
        if (widget.hasClass('open')) {
            changePlace();
        }
    };
    win.bind('resize', resizeHandler);
}

Two styles of the widget, under/below the input box.

.bootstrap-timepicker-widget.dropdown-menu.dropdown-up:before {
  border-top: 7px solid rgba(0, 0, 0, 0.2);
  border-bottom: none;
  top: 122px;
}
.bootstrap-timepicker-widget.dropdown-menu.dropdown-up:after {
  border-top: 6px solid #FFF;
  border-bottom: none;
  top: 121px;
}

dropdown dropup

pgelinas commented 10 years ago

The problem with your hardcoded height is that it might work for you now, but if someone decides to style the timepicker differently with CSS and it changes the height (like, if timepicker decides to change its padding), this won't work anymore. Neither your dropdown-up style, since the top attributes works only for a certain height.

The automatic placement on resize is a nice addition. The handler should only be active/binded when the widget is shown, otherwise you'll get lots of unwanted event handling when resizing.

wuliupo commented 10 years ago

Hello @jdewit, @pgelinas, After using your merged code https://github.com/jdewit/bootstrap-timepicker/pull/171 There is still a little issue, the positions of the timepicker and datepicker are inconsistent. For the datepicker, the widget is shown downward always, except under the page bottom. For the timepicker, the widget is shown upward if the time input box in upper half part of the window, and shown below if the time input box in the lower half part of the window. please see the snapshot. datetimepicker

Thanks very much for your quickly responsive.

pgelinas commented 10 years ago

Indeed. This isn't a major problem, I'll see if I can pinpoint the issue. Unfortunately I don't have much time to work on this right now, if I can't find it easily someone else will have to look at it.

pgelinas commented 10 years ago

Hmmmmm, I can't reproduce this issue. At first I thought that it was because of the difference in height of the two widget, but both use the exact same code to determine where to place the widget... unless... What version of the datepicker do you use? I based my code on the latest of datepicker, so maybe that's your problem? I know at some point the datepicker code didn't take into account the scroll.

three3211 commented 9 years ago

I had the same issue. The timepicker would only show above the input even though there was plenty of room to show below the input. So I found a workaround that would cause the the timepicker to always show below the input:

// Initialize timepicker
$('#timepickerNote').timepicker({
    minuteStep: 1,
    defaultTime: 'current',
    template: 'dropdown'
}).on('show.timepicker', function(e) {
    setTimeout(function() {
        $('.bootstrap-timepicker-widget').removeClass('timepicker-orient-bottom');
        $('.bootstrap-timepicker-widget').addClass('timepicker-orient-top');
        $('.bootstrap-timepicker-widget').css({top: '402px'});
    }, 1);
});