Elastic: Datepicker improvements

- Added real background overlay, to fix issues with clicking outside
  of the datepicker element
- Use better positioning technique
- Re-styling on calendar update
pull/6566/head
Aleksander Machniak 6 years ago
parent 5e4590ce55
commit 58ffbe2a83

@ -14,6 +14,7 @@
.ui-widget-overlay {
background-color: @color-dialog-overlay-background;
opacity: 1 !important; // override jQuery-UI opacity, the color above is semi-transparent
z-index: 10; // above Bootstrap's form controls
}
.ui-widget {
@ -286,11 +287,10 @@
.ui-datepicker {
// Always display datepicker centered, overwriting widgets position
position: fixed !important;
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%);
box-shadow: 10px 10px 10px 1000px @color-dialog-overlay-background;
margin: ~"calc(50vh - 13em) calc(50vw - 10em) !important";
top: 0 !important;
left: 0 !important;
box-shadow: none;
&:not(.ui-datepicker-inline) {
z-index: 120 !important; // fixes datepicker over input-group and dialogs
@ -314,6 +314,7 @@
display: inline-block;
}
}
.ui-icon {
background-image: none !important;
background-position: none !important;
@ -366,15 +367,13 @@
color: @color-datepicker-active;
font-weight: bold;
}
}
html.touch {
.ui-datepicker {
min-width: (@screen-width-mini - 20px);
td a {
font-size: 1.2em;
line-height: 2.2em;
html.touch {
& {
td a {
font-size: 1.2em;
line-height: 2.2em;
}
}
}
}

@ -733,6 +733,39 @@ function rcube_elastic_ui()
$('input.datepicker').each(function() { func(this); });
rcmail.addEventListener('insert-edit-field', func);
}
// Datepicker widget improvements: overlay element, styling updates on calendar element update
// The widget does not provide any event system, so we use MutationObserver
if (window.MutationObserver) {
var overlay, hidden = true,
callback = function(data) {
$.each(data, function(i, v) {
// add/remove overlay on widget show/hide
if (v.type == 'attributes') {
var is_hidden = $(v.target).attr('aria-hidden') == 'true';
if (is_hidden != hidden) {
if (!is_hidden) {
overlay = $('<div>').attr('class', 'ui-widget-overlay')
.appendTo('body')
.click(function(e) { $(this).remove(); });
}
else if (overlay) {
overlay.remove();
}
hidden = is_hidden;
}
}
// apply styles if widget content changed
else if (v.addedNodes.length) {
bootstrap_style(v.target);
}
});
};
$('.ui-datepicker').each(function() {
(new MutationObserver(callback)).observe(this, {childList: true, subtree: false, attributes: true, attributeFilter: ['aria-hidden']});
});
}
};
/**
@ -987,11 +1020,6 @@ function rcube_elastic_ui()
$('a', this).addClass('btn btn-primary');
});
// Style calendar widget (we use setTimeout() because there's no widget event we could bind to)
$('input.datepicker', context).focus(function() {
setTimeout(function() { bootstrap_style($('.ui-datepicker')); }, 5);
});
// Form validation errors (managesieve plugin)
$('.error', context).addClass('is-invalid');
@ -3329,7 +3357,7 @@ function rcube_elastic_ui()
.append(items)
.on('click', 'a.active', function() {
// first close the list, then update the select, the order is important
//for cases when the select might be removed in change event (datepicker)
// for cases when the select might be removed in change event (datepicker)
var val = $(this).data('value'), ret = close_func();
select.val(val).change();
return ret;

Loading…
Cancel
Save