Display current event time over free/busy grid
This commit is contained in:
parent
267e50cd95
commit
dd5f8e56bd
4 changed files with 103 additions and 22 deletions
|
@ -330,7 +330,7 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
var $dialog = $("#eventedit");
|
||||
var calendar = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar] : { editable:action=='new' };
|
||||
me.selected_event = event;
|
||||
me.selected_event = $.extend({}, event); // clone event object
|
||||
freebusy_needsupdate = false;
|
||||
|
||||
// reset dialog first, enable/disable fields according to editable state
|
||||
|
@ -635,7 +635,7 @@ function rcube_calendar_ui(settings)
|
|||
fb_end.setTime(fb_start.getTime() + 86400000);
|
||||
|
||||
freebusy_data = {};
|
||||
freebusy_ui.loading = 1; // prevent render_freebusy_grid() to load data
|
||||
freebusy_ui.loading = 1; // prevent render_freebusy_grid() to load data yet
|
||||
freebusy_ui.numdays = allday.checked ? 7 : 1;
|
||||
freebusy_ui.interval = allday.checked ? 360 : 60;
|
||||
freebusy_ui.start = fb_start;
|
||||
|
@ -673,6 +673,14 @@ function rcube_calendar_ui(settings)
|
|||
width: 850
|
||||
}).show();
|
||||
|
||||
// adjust dialog size to fit grid without scrolling
|
||||
var gridw = $('#schedule-freebusy-times').width();
|
||||
var overflow = gridw - $('#attendees-freebusy-table td.times').width() + 1;
|
||||
if (overflow > 0) {
|
||||
$dialog.dialog('option', 'width', Math.min((window.innerWidth || document.documentElement.clientWidth) - 40, 850 + overflow));
|
||||
$dialog.dialog('option', 'position', ['center', 'center']);
|
||||
}
|
||||
|
||||
// fetch data from server
|
||||
freebusy_ui.loading = 0;
|
||||
load_freebusy_data(freebusy_ui.start, freebusy_ui.interval);
|
||||
|
@ -714,21 +722,72 @@ function rcube_calendar_ui(settings)
|
|||
times_html += '<tr id="fbrow' + domid + '">' + slots_row + '</tr>';
|
||||
}
|
||||
|
||||
$('#schedule-freebusy-times > thead').html(dates_row + times_row);
|
||||
$('#schedule-freebusy-times > tbody').html(times_html);
|
||||
var table = $('#schedule-freebusy-times');
|
||||
table.children('thead').html(dates_row + times_row);
|
||||
table.children('tbody').html(times_html);
|
||||
|
||||
// if we have loaded free-busy data, show it
|
||||
if (!freebusy_ui.loading) {
|
||||
if (date2unixtime(freebusy_ui.start) < freebusy_data.start || date2unixtime(freebusy_ui.end) > freebusy_data.end || freebusy_ui.interval != freebusy_data.interval) {
|
||||
load_freebusy_data(freebusy_ui.start, freebusy_ui.interval)
|
||||
return;
|
||||
load_freebusy_data(freebusy_ui.start, freebusy_ui.interval);
|
||||
}
|
||||
|
||||
else {
|
||||
for (var email, i=0; i < event_attendees.length; i++) {
|
||||
if ((email = event_attendees[i].email))
|
||||
update_freebusy_display(email);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render current event date/time selection over grid table
|
||||
// use timeout to let the dom attributes (width/height/offset) be set first
|
||||
window.setTimeout(function(){ render_freebusy_overlay(); }, 10);
|
||||
};
|
||||
|
||||
// render overlay element over the grid to visiualize the current event date/time
|
||||
var render_freebusy_overlay = function()
|
||||
{
|
||||
var overlay = $('#schedule-event-time');
|
||||
if (me.selected_event.end.getTime() < freebusy_ui.start.getTime() || me.selected_event.start.getTime() > freebusy_ui.end.getTime()) {
|
||||
overlay.hide();
|
||||
}
|
||||
else {
|
||||
var table = $('#schedule-freebusy-times'),
|
||||
width = 0,
|
||||
pos = { top:table.children('thead').height(), left:0 },
|
||||
eventstart = Math.floor(me.selected_event.start.getTime() / 1000),
|
||||
eventend = Math.floor(me.selected_event.end.getTime() / 1000),
|
||||
slotstart = Math.floor(freebusy_ui.start.getTime() / 1000),
|
||||
slotsize = freebusy_ui.interval * 60,
|
||||
slotend, fraction, $cell;
|
||||
|
||||
// iterate through slots to determine position and size of the overlay
|
||||
table.children('thead').find('td').each(function(i, cell){
|
||||
slotend = slotstart + slotsize - 60;
|
||||
// event starts in this slot: compute left
|
||||
if (eventstart >= slotstart && eventstart <= slotend) {
|
||||
fraction = 1 - (slotend - eventstart) / slotsize;
|
||||
pos.left = Math.round(cell.offsetLeft + cell.offsetWidth * fraction);
|
||||
}
|
||||
// event ends in this slot: compute width
|
||||
else if (eventend >= slotstart && eventend <= slotend) {
|
||||
fraction = 1 - (slotend - eventend) / slotsize;
|
||||
width = Math.round(cell.offsetLeft + cell.offsetWidth * fraction) - pos.left;
|
||||
}
|
||||
|
||||
slotstart = slotstart + slotsize;
|
||||
});
|
||||
|
||||
if (!width)
|
||||
width = table.width() - pos.left;
|
||||
|
||||
// overlay is visible
|
||||
if (width > 0)
|
||||
overlay.css({ width: (width-5)+'px', height:(table.children('tbody').height() - 4)+'px', left:pos.left+'px', top:pos.top+'px' }).show();
|
||||
else
|
||||
overlay.hide();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// fetch free-busy information for each attendee from server
|
||||
|
@ -1376,8 +1435,10 @@ function rcube_calendar_ui(settings)
|
|||
// callback for clicks in all-day box
|
||||
dayClick: function(date, allDay, e, view) {
|
||||
var now = new Date().getTime();
|
||||
if (now - day_clicked_ts < 400 && day_clicked == date.getTime()) // emulate double-click on day
|
||||
return event_edit_dialog('new', { start:date, end:date, allDay:allDay, calendar:me.selected_calendar });
|
||||
if (now - day_clicked_ts < 400 && day_clicked == date.getTime()) { // emulate double-click on day
|
||||
var enddate = new Date(); enddate.setTime(date.getTime() + 86400000 - 60000);
|
||||
return event_edit_dialog('new', { start:date, end:enddate, allDay:allDay, calendar:me.selected_calendar });
|
||||
}
|
||||
|
||||
if (!ignore_click) {
|
||||
view.calendar.gotoDate(date);
|
||||
|
@ -1577,7 +1638,7 @@ function rcube_calendar_ui(settings)
|
|||
$('#edit-enddate, input.edit-alarm-date').datepicker(datepicker_settings);
|
||||
$('#edit-startdate').datepicker(datepicker_settings).datepicker('option', 'onSelect', shift_enddate).change(function(){ shift_enddate(this.value); });
|
||||
$('#edit-enddate').datepicker('option', 'onSelect', event_times_changed).change(event_times_changed);
|
||||
$('#edit-allday').click(function(){ $('#edit-starttime, #edit-endtime')[(this.checked?'hide':'show')](); });
|
||||
$('#edit-allday').click(function(){ $('#edit-starttime, #edit-endtime')[(this.checked?'hide':'show')](); event_times_changed(); });
|
||||
|
||||
// configure drop-down menu on time input fields based on jquery UI autocomplete
|
||||
$('#edit-starttime, #edit-endtime, input.edit-alarm-time')
|
||||
|
@ -1637,13 +1698,13 @@ function rcube_calendar_ui(settings)
|
|||
event_freebusy_dialog();
|
||||
});
|
||||
|
||||
$('#shedule-freebusy-prev').button().click(function(){ render_freebusy_grid(-1); });
|
||||
$('#shedule-freebusy-next').button().click(function(){ render_freebusy_grid(1); }).parent().buttonset();
|
||||
$('#shedule-freebusy-prev').html(bw.ie6 ? '<<' : '◄').button().click(function(){ render_freebusy_grid(-1); });
|
||||
$('#shedule-freebusy-next').html(bw.ie6 ? '>>' : '►').button().click(function(){ render_freebusy_grid(1); }).parent().buttonset();
|
||||
|
||||
$('#schedule-freebusy-wokinghours').click(function(){
|
||||
$('#workinghourscss').remove();
|
||||
if (this.checked)
|
||||
$('<style type="text/css" id="workinghourscss"> td.offhours { display:none } </style>').appendTo('head');
|
||||
$('<style type="text/css" id="workinghourscss"> td.offhours { opacity:0.3; filter:alpha(opacity=30) } </style>').appendTo('head');
|
||||
});
|
||||
|
||||
// add proprietary css styles if not IE
|
||||
|
|
|
@ -594,7 +594,10 @@ class calendar_ui
|
|||
html::div(array('id' => 'schedule-attendees-list'), '')
|
||||
);
|
||||
$table->add('times',
|
||||
html::div('scroll', html::tag('table', array('id' => 'schedule-freebusy-times', 'border' => 0, 'cellspacing' => 0), html::tag('thead') . html::tag('tbody')))
|
||||
html::div('scroll',
|
||||
html::tag('table', array('id' => 'schedule-freebusy-times', 'border' => 0, 'cellspacing' => 0), html::tag('thead') . html::tag('tbody')) .
|
||||
html::div(array('id' => 'schedule-event-time', 'style' => 'display:none'), ' ')
|
||||
)
|
||||
);
|
||||
|
||||
return $table->show($attrib);
|
||||
|
|
|
@ -36,6 +36,7 @@ body.calendarmain {
|
|||
|
||||
#datepicker .ui-datepicker {
|
||||
width: 97% !important;
|
||||
box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
}
|
||||
|
@ -656,6 +657,7 @@ td.topalign {
|
|||
}
|
||||
|
||||
#attendees-freebusy-table div.scroll {
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
|
@ -665,10 +667,6 @@ td.topalign {
|
|||
border-color: #ccc;
|
||||
}
|
||||
|
||||
#attendees-freebusy-table div.timesheader {
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
#schedule-attendees-list div.attendee {
|
||||
padding: 3px 20px 3px 6px;
|
||||
border-top: 1px solid #ccc;
|
||||
|
@ -693,6 +691,7 @@ td.topalign {
|
|||
border-width: 0 1px 0 1px;
|
||||
}
|
||||
|
||||
#attendees-freebusy-table div.timesheader,
|
||||
#schedule-freebusy-times tr.times td {
|
||||
min-width: 30px;
|
||||
font-size: 9px;
|
||||
|
@ -700,6 +699,15 @@ td.topalign {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
#schedule-event-time {
|
||||
position: absolute;
|
||||
border: 2px solid #333;
|
||||
background: #777;
|
||||
background: rgba(60, 60, 60, 0.6);
|
||||
opacity: 0.5;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#eventfreebusy .schedule-options {
|
||||
position: relative;
|
||||
margin-bottom: 2em;
|
||||
|
|
|
@ -43,3 +43,12 @@ html #calendartoolbar a.buttonPas {
|
|||
.fc-header-title h2 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#schedule-event-time {
|
||||
filter: alpha(opacity=40);
|
||||
}
|
||||
|
||||
#eventfreebusy .schedule-buttons,
|
||||
#edit-attendees-form #edit-attendee-schedule {
|
||||
right: 0.6em;
|
||||
}
|
Loading…
Add table
Reference in a new issue