forked from extern/egroupware
Calendar display
- Add indicators for events hidden outside of work hours - Show hidden headers for events starting before current displayed time - Fix scroll animation for multi-week views
This commit is contained in:
parent
731e490ade
commit
36b54a7c33
@ -509,25 +509,28 @@ app.classes.calendar = AppJS.extend(
|
||||
}
|
||||
|
||||
// We clone the nodes so we can animate the transition
|
||||
var original = $j(widget.getDOMNode());
|
||||
var original = $j(widget.getDOMNode()).closest('.et2_grid');
|
||||
var cloned = original.clone(true).attr("id","CLONE");
|
||||
var wrapper = $j(document.createElement("div"));
|
||||
original.parent().append(wrapper);
|
||||
|
||||
// This is to hide the scrollbar
|
||||
wrapper.wrap("<div style='overflow:hidden; height:"+original.outerHeight()+"px; width:" + original.outerWidth() + "px;'></div>");
|
||||
wrapper.height(direction == "up" || direction == "down" ? 2 * original.outerHeight() : original.outerHeight());
|
||||
wrapper.width(direction == "left" || direction == "right" ? 2 * original.outerWidth() : original.outerWidth());
|
||||
|
||||
// Moving this stuff around breaks scroll to day start in Chrome
|
||||
// Moving this stuff around scrolls things around too
|
||||
// We need this later
|
||||
var scrollTop = $j('.calendar_calTimeGridScroll',original).scrollTop();
|
||||
|
||||
// This is to hide the scrollbar
|
||||
var wrapper = original.parent();
|
||||
if(direction == "right" || direction == "left")
|
||||
{
|
||||
original.css({"display":"inline-block","width":original.width()+"px"});
|
||||
cloned.css({"display":"inline-block","width":original.width()+"px"});
|
||||
}
|
||||
wrapper.append(original);
|
||||
else
|
||||
{
|
||||
original.css("height",original.height() + "px");
|
||||
cloned.css("height",original.height() + "px");
|
||||
}
|
||||
wrapper.parent().css({overflow:'hidden', height:original.outerHeight()+"px", width:original.outerWidth() + "px"});
|
||||
wrapper.height(direction == "up" || direction == "down" ? 2 * original.outerHeight() : original.outerHeight());
|
||||
wrapper.width(direction == "left" || direction == "right" ? 2 * original.outerWidth() : original.outerWidth());
|
||||
|
||||
// Re-scroll to previous to avoid "jumping"
|
||||
$j('.calendar_calTimeGridScroll',original).scrollTop(scrollTop);
|
||||
@ -538,13 +541,17 @@ app.classes.calendar = AppJS.extend(
|
||||
// Scrolling up
|
||||
// Apply the reverse quickly, then let it animate as the changes are
|
||||
// removed, leaving things where they should be.
|
||||
|
||||
original.parent().append(cloned);
|
||||
wrapper.css({"transform": direction == "up" ? "translateY(-50%)" : "translateX(-50%)"});
|
||||
// Makes it jump to destination
|
||||
wrapper.css({
|
||||
"transition-duration": "0s",
|
||||
"transition-delay": "0s"
|
||||
"transition-delay": "0s",
|
||||
"transform": direction == "up" ? "translateY(-50%)" : "translateX(-50%)"
|
||||
});
|
||||
// Stop browser from caching style by forcing reflow
|
||||
wrapper[0].offsetHeight;
|
||||
|
||||
wrapper.css({
|
||||
"transition-duration": "",
|
||||
"transition-delay": ""
|
||||
@ -567,21 +574,30 @@ app.classes.calendar = AppJS.extend(
|
||||
wrapper.css({"transform": translate});
|
||||
window.setTimeout(function() {
|
||||
var scrollTop = $j('.calendar_calTimeGridScroll',original).scrollTop();
|
||||
// Clean up from animation
|
||||
|
||||
cloned.remove();
|
||||
var parent = wrapper.parent().parent();
|
||||
wrapper.parent().remove();
|
||||
original.appendTo(parent);
|
||||
|
||||
// Makes it jump to destination
|
||||
wrapper.css({
|
||||
"transition-duration": "0s",
|
||||
"transition-delay": "0s"
|
||||
});
|
||||
|
||||
// Clean up from animation
|
||||
wrapper
|
||||
.removeClass("calendar_slide")
|
||||
.css({"transform": '',height: '', width:'',overflow:''});
|
||||
wrapper.parent().css({overflow: '', width: '', height: ''});
|
||||
original.css("display","");
|
||||
// Re-attach events, if widget is still there
|
||||
if(widget && widget.getDOMNode(widget))
|
||||
{
|
||||
widget.attachToDOM();
|
||||
}
|
||||
wrapper[0].offsetHeight;
|
||||
wrapper.css({
|
||||
"transition-duration": "",
|
||||
"transition-delay": ""
|
||||
});
|
||||
|
||||
// Re-scroll to start of day
|
||||
$j('.calendar_calTimeGridScroll',original).scrollTop(scrollTop);
|
||||
|
||||
|
||||
window.setTimeout(function() {
|
||||
if(app.calendar)
|
||||
{
|
||||
|
@ -441,6 +441,90 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea
|
||||
{
|
||||
this._children[c].set_value(events[c]);
|
||||
}
|
||||
|
||||
// Apply styles to hidden events
|
||||
this._out_of_view();
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply styles for out-of-view and partially hidden events
|
||||
*/
|
||||
_out_of_view: function()
|
||||
{
|
||||
// Reset
|
||||
this.header.children('.hiddenEventBefore').remove();
|
||||
this.div.children('.hiddenEventAfter').remove();
|
||||
|
||||
var timegrid = this._parent;
|
||||
|
||||
// elem is jquery div of event
|
||||
function isHidden(elem) {
|
||||
var docViewTop = timegrid.scrolling.scrollTop(),
|
||||
docViewBottom = docViewTop + timegrid.scrolling.height(),
|
||||
elemTop = elem.position().top,
|
||||
elemBottom = elemTop + elem.outerHeight();
|
||||
if((elemBottom <= docViewBottom) && (elemTop >= docViewTop))
|
||||
{
|
||||
// Entirely visible
|
||||
return false;
|
||||
}
|
||||
var visible = {
|
||||
hidden: elemTop > docViewTop ? 'bottom' : 'top',
|
||||
completely: false
|
||||
};
|
||||
visible.completely = visible.hidden == 'top' ? elemBottom < docViewTop : elemTop > docViewBottom;
|
||||
return visible;
|
||||
}
|
||||
|
||||
// Check each event
|
||||
this.iterateOver(function(event) {
|
||||
// Skip whole day events and events missing value
|
||||
if(!event.options || !event.options.value || event.options.value.whole_day) return;
|
||||
|
||||
// Reset
|
||||
event.title.css('top','');
|
||||
event.body.css('padding-top','');
|
||||
|
||||
var hidden = isHidden.call(this,event.div);
|
||||
if(!hidden)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Only top is hidden, move label
|
||||
// Bottom hidden is fine
|
||||
if(hidden.hidden === 'top' && !hidden.completely)
|
||||
{
|
||||
event.title.css('top',timegrid.scrolling.scrollTop() - event.div.position().top);
|
||||
event.body.css('padding-top',timegrid.scrolling.scrollTop() - event.div.position().top);
|
||||
}
|
||||
// Completely out of view, show indicator
|
||||
else if (hidden.completely)
|
||||
{
|
||||
var indicator = '';
|
||||
if(hidden.hidden === 'top' && $j('.hiddenEventBefore',this.header).length == 0)
|
||||
{
|
||||
indicator = $j('<div class="hiddenEventBefore"></div>')
|
||||
.appendTo(this.header);
|
||||
}
|
||||
else if(hidden.hidden === 'bottom')
|
||||
|
||||
{
|
||||
indicator = $j('.hiddenEventAfter',this.div);
|
||||
if(indicator.length == 0)
|
||||
{
|
||||
indicator = $j('<div class="hiddenEventAfter"></div>');
|
||||
this.div.append(indicator);
|
||||
}
|
||||
indicator.css('top',timegrid.scrolling.height() + timegrid.scrolling.scrollTop()-indicator.height());
|
||||
}
|
||||
// Match color to the event
|
||||
if(indicator != '')
|
||||
{
|
||||
// Use border-top-color, Firefox doesn't give a value with border-color
|
||||
indicator.css('border-color', event.div.css('border-top-color'));
|
||||
}
|
||||
}
|
||||
}, this, et2_calendar_event);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -532,7 +532,8 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
|
||||
this.scrolling
|
||||
.css('height', (this.options.height - header_height)+'px')
|
||||
.appendTo(this.div)
|
||||
.empty();
|
||||
.empty()
|
||||
.off().on('scroll', jQuery.proxy(this._scroll, this));
|
||||
|
||||
// Percent
|
||||
var rowHeight = (100/rowsToDisplay).toFixed(1);
|
||||
@ -666,6 +667,9 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
|
||||
|
||||
// Scroll to start of day
|
||||
this.scrolling.scrollTop(this._top_time);
|
||||
|
||||
// Handle not fully visible elements
|
||||
this._scroll();
|
||||
|
||||
// TODO: Figure out how to do this with detached nodes
|
||||
/*
|
||||
@ -681,6 +685,21 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
|
||||
*/
|
||||
},
|
||||
|
||||
/**
|
||||
* Update UI while scrolling within the selected time
|
||||
*
|
||||
* Toggles out of view indicators and adjusts not visible headers
|
||||
* @param {Event} event Scroll event
|
||||
*/
|
||||
_scroll: function(event)
|
||||
{
|
||||
// Loop through days, let them deal with it
|
||||
for(var day = 0; day < this.day_widgets.length; day++)
|
||||
{
|
||||
this.day_widgets[day]._out_of_view();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculate a list of days between start and end date, skipping weekends if
|
||||
* desired.
|
||||
|
@ -246,6 +246,28 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
text-align: center;
|
||||
border-bottom: 1px solid silver;
|
||||
}
|
||||
|
||||
/* Indicators for offscreen events */
|
||||
.calendar_calDayColHeader .hiddenEventBefore, .calendar_calDayCol .hiddenEventAfter {
|
||||
width: 80%;
|
||||
height: 5px;
|
||||
left: 10%;
|
||||
position: absolute;
|
||||
border-radius: 5px;
|
||||
border: 5px solid;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
z-index: 40;
|
||||
}
|
||||
.calendar_calDayColHeader .hiddenEventBefore {
|
||||
bottom: -7px;
|
||||
border-top: none;
|
||||
}
|
||||
.calendar_calDayCol .hiddenEventAfter {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
|
||||
.calendar_calDayColAllDay {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@ -318,6 +340,7 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
padding-left: 3px;
|
||||
z-index: 29;
|
||||
border-bottom: 1px solid silver;
|
||||
min-height: 45px;
|
||||
}
|
||||
#calendar-view_view tbody.ui-sortable {
|
||||
cursor: default;
|
||||
|
@ -13,7 +13,7 @@ Egroupware
|
||||
|
||||
<overlay>
|
||||
<template id="calendar.view">
|
||||
<grid id="view" width="100%" height="100%">
|
||||
<grid id="view" width="100%">
|
||||
<columns>
|
||||
<column/>
|
||||
</columns>
|
||||
|
Loading…
Reference in New Issue
Block a user