forked from extern/egroupware
Calendar scrolling
- prevent fast scrolling with a touchpad - animation while changing scrolled dates
This commit is contained in:
parent
804d558e68
commit
7e5873eefa
@ -464,17 +464,22 @@ app.classes.calendar = AppJS.extend(
|
||||
.on('wheel.calendar','.et2_container .calendar_calTimeGrid, .et2_container .calendar_plannerWidget',
|
||||
function(e)
|
||||
{
|
||||
var at_bottom = true;
|
||||
var at_top = true;
|
||||
$j(this).children().each(function() {
|
||||
// Ignore if they're going the other way
|
||||
var direction = e.originalEvent.deltaY > 0 ? 1 : -1;
|
||||
var at_bottom = direction !== -1;
|
||||
var at_top = direction !== 1;
|
||||
|
||||
$j(this).children(":not(.calendar_calGridHeader)").each(function() {
|
||||
at_bottom = at_bottom && this.scrollTop === (this.scrollHeight - this.offsetHeight)
|
||||
}).each(function() {
|
||||
at_top = at_top && this.scrollTop === 0;
|
||||
});
|
||||
if(!at_bottom && !at_top) return;
|
||||
|
||||
|
||||
// Scrolling too fast?
|
||||
if(app.calendar._scroll_disabled) return;
|
||||
|
||||
e.preventDefault();
|
||||
var direction = e.originalEvent.deltaY > 0 ? 1 : -1;
|
||||
var delta = 1;
|
||||
var start = new Date(app.calendar.state.date);
|
||||
var end = null;
|
||||
@ -485,6 +490,80 @@ app.classes.calendar = AppJS.extend(
|
||||
var template = etemplate2.getById(id);
|
||||
if(!template) return;
|
||||
|
||||
// Prevent scrolling too fast
|
||||
app.calendar._scroll_disabled = true;
|
||||
|
||||
// Animate the transition, if possible
|
||||
var widget = null
|
||||
template.widgetContainer.iterateOver(function(w) {
|
||||
if (w.getDOMNode() == this) widget = w;
|
||||
},this,et2_widget);
|
||||
if(widget == null) return;
|
||||
|
||||
// We apply the reverse quickly, then let it animate as the changes are
|
||||
// removed, leaving things where they should be.
|
||||
var original = $j(this);
|
||||
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'></div>");
|
||||
wrapper.height(original.outerHeight() + cloned.outerHeight());
|
||||
wrapper.append(original);
|
||||
if(direction == -1)
|
||||
{
|
||||
// Scrolling up
|
||||
original.parent().append(cloned);
|
||||
wrapper.css({"transform": "translateY(" + (direction * 50) + "%)"});
|
||||
// Makes it jump to destination
|
||||
wrapper.css({
|
||||
"transition-duration": "0s",
|
||||
"transition-delay": "0s"
|
||||
});
|
||||
wrapper.css({
|
||||
"transition-duration": "",
|
||||
"transition-delay": ""
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scrolling down
|
||||
$j(this).parent().prepend(cloned);
|
||||
$j('.calendar_calTimeGridScroll',cloned).scrollTop(10000);
|
||||
}
|
||||
|
||||
// Remove
|
||||
var remove = function() {
|
||||
// Starting animation
|
||||
wrapper.addClass("calendar_slide");
|
||||
wrapper.css({"transform": direction == 1 ? "translateY(-50%)" : ""});
|
||||
window.setTimeout(function() {
|
||||
// Clean up from animation
|
||||
cloned.remove();
|
||||
// Moving this stuff around breaks scroll to day start in Chrome
|
||||
var scrollTop = $j('.calendar_calTimeGridScroll',original).scrollTop();
|
||||
var parent = wrapper.parent().parent();
|
||||
wrapper.parent().remove();
|
||||
original.appendTo(parent);
|
||||
// Also detaches events
|
||||
if(widget)
|
||||
{
|
||||
widget.attachToDOM();
|
||||
}
|
||||
// Re-scroll to start of day
|
||||
$j('.calendar_calTimeGridScroll',original).scrollTop(scrollTop);
|
||||
|
||||
|
||||
window.setTimeout(function() {
|
||||
if(app.calendar)
|
||||
{
|
||||
app.calendar._scroll_disabled = false;
|
||||
}
|
||||
}, 500);
|
||||
},1000);
|
||||
}
|
||||
// If detecting the transition end worked, we wouldn't need to use a timeout.
|
||||
window.setTimeout(remove,100);
|
||||
|
||||
// Get the view to calculate
|
||||
var view = app.classes.calendar.views[app.calendar.state.view] || false;
|
||||
@ -498,6 +577,7 @@ app.classes.calendar = AppJS.extend(
|
||||
// Home - always 1 week
|
||||
// TODO
|
||||
return false;
|
||||
/*
|
||||
var widget = [];
|
||||
var value = [];
|
||||
template.widgetContainer.iterateOver(function(w) {
|
||||
@ -523,6 +603,7 @@ app.classes.calendar = AppJS.extend(
|
||||
app.calendar._need_data([value[i]], state);
|
||||
widget[i].set_value(value[i]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -1419,13 +1500,15 @@ app.classes.calendar = AppJS.extend(
|
||||
}
|
||||
|
||||
// Hide other views
|
||||
var view = app.classes.calendar.views[state.state.view];
|
||||
for(var _view in app.classes.calendar.views)
|
||||
{
|
||||
if(state.state.view != _view && app.classes.calendar.views[_view])
|
||||
{
|
||||
for(var i = 0; i < app.classes.calendar.views[_view].etemplates.length; i++)
|
||||
{
|
||||
if(typeof app.classes.calendar.views[_view].etemplates[i] !== 'string')
|
||||
if(typeof app.classes.calendar.views[_view].etemplates[i] !== 'string' &&
|
||||
view.etemplates.indexOf(app.classes.calendar.views[_view].etemplates[i]) == -1)
|
||||
{
|
||||
$j(app.classes.calendar.views[_view].etemplates[i].DOMContainer).hide();
|
||||
}
|
||||
@ -1469,8 +1552,6 @@ app.classes.calendar = AppJS.extend(
|
||||
// cause infinite loops.
|
||||
this.state_update_in_progress = true;
|
||||
|
||||
var view = app.classes.calendar.views[state.state.view];
|
||||
|
||||
// Sanitize owner so it's always an array
|
||||
if(state.state.owner === null)
|
||||
{
|
||||
@ -1632,11 +1713,12 @@ app.classes.calendar = AppJS.extend(
|
||||
$j(view.etemplates[i].DOMContainer).show();
|
||||
}
|
||||
// Toggle todos
|
||||
if(state.state.view == 'day')
|
||||
if(state.state.view == 'day' || this.state.view == 'day')
|
||||
{
|
||||
if(state.state.owner.length === 1 && !isNaN(state.state.owner) && state.state.owner[0] > 0)
|
||||
if(state.state.view == 'day' && state.state.owner.length === 1 && !isNaN(state.state.owner) && state.state.owner[0] > 0)
|
||||
{
|
||||
view.etemplates[0].widgetContainer.set_width("70%");
|
||||
view.etemplates[0].DOMContainer.style.width = "70%";
|
||||
$j(view.etemplates[1].DOMContainer).css("left","69%");
|
||||
// TODO: Maybe some caching here
|
||||
this.egw.jsonq('calendar_uiviews::ajax_get_todos', [state.state.date, state.state.owner[0]], function(data) {
|
||||
this.getWidgetById('label').set_value(data.label||'');
|
||||
@ -1645,13 +1727,17 @@ app.classes.calendar = AppJS.extend(
|
||||
}
|
||||
else
|
||||
{
|
||||
$j(view.etemplates[1].DOMContainer).hide();
|
||||
view.etemplates[0].widgetContainer.set_width("");
|
||||
$j(app.classes.calendar.views.day.etemplates[1].DOMContainer).show();
|
||||
$j(app.classes.calendar.views.day.etemplates[1].DOMContainer).css("left","100%");
|
||||
window.setTimeout(jQuery.proxy(function() {
|
||||
$j(this).hide();
|
||||
},app.classes.calendar.views.day.etemplates[1].DOMContainer),1000);
|
||||
$j(app.classes.calendar.views.day.etemplates[0].DOMContainer).css("width","100%");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
view.etemplates[0].widgetContainer.set_width("");
|
||||
$j(view.etemplates[0].DOMContainer).css("width","100%");
|
||||
}
|
||||
this.state = jQuery.extend({},state.state);
|
||||
|
||||
|
@ -64,12 +64,15 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea
|
||||
// Main container
|
||||
this.div = $j(document.createElement("div"))
|
||||
.addClass("calendar_calDayCol")
|
||||
.css('width',this.options.width);
|
||||
.css('width',this.options.width)
|
||||
.css('left', this.options.left);
|
||||
this.header = $j(document.createElement('div'))
|
||||
.addClass("calendar_calDayColHeader");
|
||||
.addClass("calendar_calDayColHeader")
|
||||
.css('width',this.options.width)
|
||||
.css('left', this.options.left);
|
||||
this.title = $j(document.createElement('div'))
|
||||
.appendTo(this.header);
|
||||
|
||||
|
||||
this.setDOMNode(this.div[0]);
|
||||
|
||||
// Used for its date calculations - note this is a datetime, parent
|
||||
@ -132,7 +135,24 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea
|
||||
this.display_settings.wd_start = 60*this._parent.options.day_start;
|
||||
this.display_settings.wd_end = 60*this._parent.options.day_end;
|
||||
this.display_settings.granularity = this._parent.options.granularity;
|
||||
this._parent.dayHeader.append(this.header);
|
||||
var header = this._parent.dayHeader.children();
|
||||
|
||||
// Figure out insert index
|
||||
var idx = 0;
|
||||
var siblings = this._parent.getDOMNode(this).childNodes
|
||||
while(idx < siblings.length && siblings[idx] != this.getDOMNode())
|
||||
{
|
||||
idx++;
|
||||
}
|
||||
// Stick header in the right place
|
||||
if(idx == 0)
|
||||
{
|
||||
this._parent.dayHeader.prepend(this.header);
|
||||
}
|
||||
else if(header.length)
|
||||
{
|
||||
header.eq(Math.min(header.length,idx)-1).after(this.header);
|
||||
}
|
||||
}
|
||||
|
||||
this.display_settings.rowsToDisplay = ((this.display_settings.wd_end - this.display_settings.wd_start)/this.display_settings.granularity);
|
||||
@ -295,16 +315,25 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea
|
||||
},
|
||||
|
||||
set_left: function(left) {
|
||||
this.div.css('left',left);
|
||||
// Maybe?
|
||||
window.setTimeout(jQuery.proxy(function() {
|
||||
this.header.css('left',left);
|
||||
if(this.div)
|
||||
{
|
||||
this.div.css('left',left);
|
||||
this.header.css('left',left);
|
||||
}
|
||||
},this),1);
|
||||
|
||||
},
|
||||
set_width: function(width) {
|
||||
this._super.apply(this, arguments);
|
||||
this.header.width(width);
|
||||
this.options.width = width;
|
||||
window.setTimeout(jQuery.proxy(function() {
|
||||
if(this.div)
|
||||
{
|
||||
this.div.width(this.options.width);
|
||||
this.header.width(this.options.width);
|
||||
}
|
||||
},this),1);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -528,8 +557,7 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea
|
||||
if(columns[c][i].options.value.whole_day_on_top)
|
||||
{
|
||||
columns[c][i].div
|
||||
.appendTo(this.header)
|
||||
.css('position', 'relative');
|
||||
.appendTo(this.header);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
@ -578,35 +578,61 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
|
||||
this.day_list = this._calculate_day_list(this.options.start_date, this.options.end_date, this.options.show_weekend);
|
||||
}
|
||||
|
||||
var day_width = (100/this.day_list.length).toFixed(2);
|
||||
|
||||
// Create any needed widgets - otherwise, we'll just recycle
|
||||
// Add any needed day widgets (now showing more days)
|
||||
var add_index = 0;
|
||||
var before = true;
|
||||
while(this.day_list.length > this.day_widgets.length)
|
||||
{
|
||||
var existing_index = this.day_widgets[add_index] ? this.day_list.indexOf(this.day_widgets[add_index].options.date) : -1;
|
||||
before = existing_index > add_index;
|
||||
|
||||
var day = et2_createWidget('calendar-daycol',{
|
||||
owner: this.options.owner
|
||||
owner: this.options.owner,
|
||||
width: (before ? 0 : day_width) + "%"
|
||||
},this);
|
||||
if(this.isInTree())
|
||||
{
|
||||
day.doLoadingFinished();
|
||||
}
|
||||
this.day_widgets.push(day);
|
||||
if(existing_index != -1 && parseInt(this.day_list[add_index]) < parseInt(this.day_list[existing_index]))
|
||||
{
|
||||
this.day_widgets.unshift(day);
|
||||
$j(this.getDOMNode(day)).prepend(day.getDOMNode(day));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.day_widgets.push(day);
|
||||
}
|
||||
add_index++;
|
||||
}
|
||||
// Remove any extra day widgets (now showing less)
|
||||
var delete_index = this.day_widgets.length - 1;
|
||||
before = false;
|
||||
while(this.day_widgets.length > this.day_list.length)
|
||||
{
|
||||
// If we're going down to an existing one, just keep it for cool CSS animation
|
||||
while(this.day_list.indexOf(this.day_widgets[delete_index].options.date) > -1)
|
||||
{
|
||||
delete_index--;
|
||||
before = true;
|
||||
}
|
||||
// Wait until any animations or other timeouts are done
|
||||
window.setTimeout(jQuery.proxy(function() {
|
||||
this.free();
|
||||
},this.day_widgets[delete_index]),1000);
|
||||
|
||||
// Widgets that are before our date shrink, after just get pushed out
|
||||
if(before)
|
||||
{
|
||||
this.day_widgets[delete_index].set_width('0px');
|
||||
}
|
||||
this.day_widgets[delete_index].set_width('0px');
|
||||
this.day_widgets[delete_index].free();
|
||||
this.day_widgets.splice(delete_index--,1);
|
||||
}
|
||||
|
||||
// Create / update day widgets with dates and data
|
||||
var day_width = (100/this.day_list.length).toFixed(2);
|
||||
for(var i = 0; i < this.day_list.length; i++)
|
||||
{
|
||||
day = this.day_widgets[i];
|
||||
@ -619,7 +645,7 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
|
||||
day.set_id(this.day_list[i]);
|
||||
day.set_width(day_width + '%');
|
||||
}
|
||||
|
||||
|
||||
// Don't hold on to value any longer, use the data cache for best info
|
||||
this.value = {};
|
||||
|
||||
|
@ -36,8 +36,16 @@
|
||||
}
|
||||
|
||||
#calendar-todo {
|
||||
float: right;
|
||||
position: absolute;
|
||||
width: 30%;
|
||||
|
||||
/* Nice transition when changing days in a week */
|
||||
transition: 1s ease-in-out;
|
||||
}
|
||||
|
||||
#calendar-view {
|
||||
width: 100%;
|
||||
transition: width 1s ease-in-out;
|
||||
}
|
||||
/* Header classes */
|
||||
tr.dialogHeader td, tr.dialogHeader2 td, tr.dialogHeader3 td, tr.dialogHeader4 td,
|
||||
@ -189,6 +197,7 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
height: 100%;
|
||||
left: 45px;
|
||||
right: 0px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* 12h timeformat with am/pm
|
||||
*/
|
||||
@ -235,12 +244,21 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
line-height: 16px;
|
||||
}
|
||||
.calendar_calDayColHeader {
|
||||
vertical-align: top;
|
||||
height: 100%;
|
||||
/* Nice transition when changing days in a week */
|
||||
transition: width 1s ease-in-out;
|
||||
z-index:30;
|
||||
}
|
||||
.calendar_calDayColHeader > div[data-date] {
|
||||
height: 16px;
|
||||
}
|
||||
.calendar_calGridHeader > div {
|
||||
position: absolute;
|
||||
left: 45px;
|
||||
right: 15px;
|
||||
width: initial;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.calendar_calDayColHeader img {
|
||||
vertical-align: middle;
|
||||
@ -250,15 +268,6 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
right: 0px;
|
||||
/* does not work in IE, but looks better in other browsers then width:100% */
|
||||
text-align: center;
|
||||
font-size: 100%;
|
||||
white-space: nowrap;
|
||||
border-bottom: 1px solid silver;
|
||||
border-right: 1px solid silver;
|
||||
height: 16px;
|
||||
line-height: 12px;
|
||||
z-index: 30;
|
||||
}
|
||||
.calendar_calWeekNavHeader,.calendar_calMonthNavHeader img {
|
||||
vertical-align: middle;
|
||||
@ -397,6 +406,13 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Events in the header (all day)
|
||||
*/
|
||||
.calendar_calDayColHeader .calendar_calEvent {
|
||||
position: static;
|
||||
display: inline-block;
|
||||
}
|
||||
.calendar_calEventTooltip{
|
||||
border-radius: 6px;
|
||||
-moz-border-radius: 6px;
|
||||
@ -792,6 +808,14 @@ img.calendar_print_button, img.calendar_print_appicon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/**
|
||||
* View animation stuff
|
||||
*/
|
||||
.calendar_slide {
|
||||
transition-duration: 1s;
|
||||
transition-delay: 100ms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Home page portlets
|
||||
*/
|
||||
@ -814,4 +838,4 @@ img.calendar_print_button, img.calendar_print_appicon {
|
||||
border-top: 0;
|
||||
margin: 0;
|
||||
padding-right: 3px;
|
||||
}
|
||||
}
|
||||
|
@ -581,9 +581,6 @@ div.calendar {
|
||||
#calendar-edit #calendar-edit_calendar-edit-links span.et2_label {
|
||||
padding: 1em;
|
||||
}
|
||||
#calendar-edit #calendar-edit_calendar-edit-links div.delete {
|
||||
background-image: url("https:://192.168.1.100/egroupware2/pixelegg/images/delete.png");
|
||||
}
|
||||
#calendar-edit #calendar-edit_calendar-edit-alarms tbody {
|
||||
display: table;
|
||||
width: 100%;
|
||||
@ -721,19 +718,8 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
*/
|
||||
.calendar_calDayColHeader,
|
||||
.calendar_calGridHeader {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
right: 0px;
|
||||
/* does not work in IE, but looks better in other browsers then width:100% */
|
||||
text-align: center;
|
||||
font-size: 100%;
|
||||
white-space: nowrap;
|
||||
border-bottom: 1px solid silver;
|
||||
border-right: 1px solid silver;
|
||||
height: 16px;
|
||||
line-height: 12px;
|
||||
}
|
||||
.calendar_calDayColHeader a img,
|
||||
.calendar_calGridHeader a img {
|
||||
@ -802,27 +788,10 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
text-align: left;
|
||||
padding-left: 3px;
|
||||
}
|
||||
/* contains (multiple) events's
|
||||
*/
|
||||
.calendar_calEventCol {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
/* bottom: 0px; does NOT work in IE, IE needs height: 100%! */
|
||||
height: 100%;
|
||||
/* set via inline style on runtime:
|
||||
* left:
|
||||
* width:
|
||||
*/
|
||||
}
|
||||
/* contains one event: header-row & -body
|
||||
*/
|
||||
.calendar_calEvent,
|
||||
.calendar_calEventPrivate {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
overflow: hidden;
|
||||
z-index: 20;
|
||||
border-width: 1px;
|
||||
border-radius: 6px;
|
||||
-moz-border-radius: 6px;
|
||||
|
@ -661,8 +661,6 @@ div.calendar { position: relative; }
|
||||
}
|
||||
|
||||
span.et2_label {padding: 1em;}
|
||||
|
||||
div.delete {background-image: url("https:://192.168.1.100/egroupware2/pixelegg/images/delete.png");}
|
||||
}
|
||||
|
||||
/*###########################################*/
|
||||
@ -767,7 +765,7 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
}
|
||||
.calendar_calWeek{
|
||||
// background: #ffffcc;
|
||||
background-color : @gray_0;
|
||||
background-color : @gray_0;
|
||||
width:auto;
|
||||
margin:0 auto;
|
||||
text-align:center;
|
||||
@ -834,18 +832,8 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
/* header for the dayCol
|
||||
*/
|
||||
.calendar_calDayColHeader,.calendar_calGridHeader{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
right: 0px; /* does not work in IE, but looks better in other browsers then width:100% */
|
||||
text-align: center;
|
||||
font-size: 100%;
|
||||
white-space: nowrap;
|
||||
border-bottom: 1px solid silver;
|
||||
border-right: 1px solid silver;
|
||||
.dimension_height_s;
|
||||
line-height: 12px;
|
||||
|
||||
a {
|
||||
img {
|
||||
@ -927,27 +915,9 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
/* contains (multiple) events's
|
||||
*/
|
||||
.calendar_calEventCol{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
/* bottom: 0px; does NOT work in IE, IE needs height: 100%! */
|
||||
height: 100%;
|
||||
/* set via inline style on runtime:
|
||||
* left:
|
||||
* width:
|
||||
*/
|
||||
}
|
||||
|
||||
/* contains one event: header-row & -body
|
||||
*/
|
||||
.calendar_calEvent,.calendar_calEventPrivate{
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
overflow: hidden;
|
||||
z-index: 20;
|
||||
border-width: 1px;
|
||||
border-radius: 6px;
|
||||
-moz-border-radius: 6px;
|
||||
|
Loading…
Reference in New Issue
Block a user