Skip to content

Commit a99ae17

Browse files
committed
Fix the positioning if the timepicker is viewport is changed.
1 parent 57f0805 commit a99ae17

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

jquery.timepicker.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@
211211
last: function() { return widget.last(i) ;},
212212
selected: function() { return widget.selected(i) ;},
213213
open: function() { return widget.open(i) ;},
214+
reposition: function () { return widget.reposition(i); },
214215
close: function() { return widget.close(i) ;},
215216
closed: function() { return widget.closed(i) ;},
216217
destroy: function() { return widget.destroy(i) ;},
@@ -397,6 +398,11 @@
397398
i.element.data('timepicker-user-clicked-outside', true).blur();
398399
}
399400
});
401+
// make sure we reposition the timepicker when the viewport changes
402+
$(window).bind('resize.timepicker-' + i.element.data('timepicker-event-namespace'), i.reposition);
403+
// use vanilla javascript to be able to use event capturing instead of bubbling: otherwise we have to listen
404+
// on all parent containers.
405+
window.addEventListener('scroll', i.reposition, true);
400406

401407
// if a date is already selected and options.dynamic is true,
402408
// arrange the items in the list so the first item is
@@ -517,6 +523,46 @@
517523
return i.element;
518524
},
519525

526+
reposition: function (i) {
527+
var widget = this;
528+
var containerDecorationHeight = widget.container.outerHeight() - widget.container.height(),
529+
zindex = i.options.zindex ? i.options.zindex : i.element.offsetParent().css( 'z-index' ),
530+
elementOffset = i.element.offset();
531+
532+
// position the container right below the element, or as close to as possible.
533+
widget.container.css( {
534+
top: elementOffset.top + i.element.outerHeight(),
535+
left: elementOffset.left
536+
} );
537+
538+
// then show the container so that the browser can consider the timepicker's
539+
// height to calculate the page's total height and decide if adding scrollbars
540+
// is necessary.
541+
widget.container.show();
542+
543+
// now we need to calculate the element offset and position the container again.
544+
// If the browser added scrollbars, the container's original position is not aligned
545+
// with the element's final position. This step fixes that problem.
546+
widget.container.css( {
547+
left: i.element.offset().left,
548+
height: widget.ui.outerHeight() + containerDecorationHeight,
549+
width: i.element.outerWidth(),
550+
zIndex: zindex,
551+
cursor: 'default'
552+
} );
553+
554+
555+
var calculatedWidth = widget.container.width() - ( widget.ui.outerWidth() - widget.ui.width() );
556+
557+
// hardcode ui, viewport and item's width. I couldn't get it to work using CSS only
558+
widget.ui.css( { width: calculatedWidth } );
559+
widget.viewport.css( { width: calculatedWidth } );
560+
i.items.css( { width: calculatedWidth } );
561+
562+
563+
return i.element;
564+
},
565+
520566
close: function(i) {
521567
var widget = this;
522568

@@ -530,6 +576,9 @@
530576
'keydown.timepicker-' + i.element.data('timepicker-event-namespace') + ' ' +
531577
'keyup.timepicker-' + i.element.data('timepicker-event-namespace'));
532578

579+
$(window).unbind('resize.timepicker-' + i.element.data('timepicker-event-namespace'));
580+
window.removeEventListener('scroll', i.reposition, true);
581+
533582
return i.element;
534583
},
535584

@@ -669,6 +718,7 @@
669718
'next',
670719
'previous',
671720
'open',
721+
'reposition',
672722
'close',
673723
'destroy',
674724
'setTime'

0 commit comments

Comments
 (0)