Fixed smart event segmentation in list view; added table view (derived from list view) as alternative
This commit is contained in:
parent
5f7e3b6029
commit
b45566de9e
7 changed files with 405 additions and 72 deletions
|
@ -739,7 +739,7 @@ function rcube_calendar(settings)
|
|||
header: {
|
||||
left: 'prev,next today',
|
||||
center: 'title',
|
||||
right: 'agendaDay,agendaWeek,month,list'
|
||||
right: 'agendaDay,agendaWeek,month,list,table'
|
||||
},
|
||||
aspectRatio: 1,
|
||||
ignoreTimezone: false, // will translate event dates to the client's timezone
|
||||
|
@ -754,20 +754,25 @@ function rcube_calendar(settings)
|
|||
slotMinutes : 60/settings['timeslots'],
|
||||
timeFormat: {
|
||||
'': settings['time_format'],
|
||||
list: settings['time_format'] + '{ - ' + settings['time_format'] + '}'
|
||||
list: settings['time_format'] + '{ - ' + settings['time_format'] + '}',
|
||||
table: settings['time_format'] + '{ - ' + settings['time_format'] + '}'
|
||||
},
|
||||
axisFormat : settings['time_format'],
|
||||
columnFormat: {
|
||||
month: 'ddd', // Mon
|
||||
week: 'ddd ' + settings['date_short'], // Mon 9/7
|
||||
day: 'dddd ' + settings['date_short'] // Monday 9/7
|
||||
day: 'dddd ' + settings['date_short'], // Monday 9/7
|
||||
list: settings['date_agena'],
|
||||
table: settings['date_agena']
|
||||
},
|
||||
titleFormat: {
|
||||
month: 'MMMM yyyy',
|
||||
week: settings['date_long'].replace(/ yyyy/, '[ yyyy]') + "{ '—' " + settings['date_long'] + "}",
|
||||
day: 'dddd ' + settings['date_long'],
|
||||
list: settings['date_long']
|
||||
list: settings['date_long'],
|
||||
table: settings['date_long']
|
||||
},
|
||||
smartSections: true,
|
||||
defaultView: settings['default_view'],
|
||||
allDayText: rcmail.gettext('all-day', 'calendar'),
|
||||
buttonText: {
|
||||
|
@ -776,7 +781,7 @@ function rcube_calendar(settings)
|
|||
week: rcmail.gettext('week', 'calendar'),
|
||||
month: rcmail.gettext('month', 'calendar'),
|
||||
list: rcmail.gettext('agenda', 'calendar'),
|
||||
basicDay: 'basic'
|
||||
table: rcmail.gettext('table', 'calendar')
|
||||
},
|
||||
selectable: true,
|
||||
selectHelper: true,
|
||||
|
@ -785,7 +790,7 @@ function rcube_calendar(settings)
|
|||
},
|
||||
// event rendering
|
||||
eventRender: function(event, element, view) {
|
||||
if (view.name != 'list')
|
||||
if (view.name != 'list' && view.name != 'table')
|
||||
element.attr('title', event.title);
|
||||
if (view.name == 'month') {
|
||||
/* attempt to limit the number of events displayed
|
||||
|
@ -940,7 +945,7 @@ function rcube_calendar(settings)
|
|||
var shift_enddate = function(dateText) {
|
||||
var newstart = parse_datetime('0', dateText);
|
||||
var newend = new Date(newstart.getTime() + $('#edit-startdate').data('duration') * 1000);
|
||||
$('#edit-enddate').val($.fullCalendar.formatDate(newend, cal.settings['date_format']));
|
||||
$('#edit-enddate').val($.fullCalendar.formatDate(newend, me.settings['date_format']));
|
||||
};
|
||||
|
||||
// init event dialog
|
||||
|
|
|
@ -370,6 +370,7 @@ class calendar extends rcube_plugin
|
|||
else
|
||||
$this->rc->output->show_message('calendar.errorsaving', 'error');
|
||||
|
||||
// TODO: keep view and date selection
|
||||
if ($success && $reload)
|
||||
$this->rc->output->redirect('');
|
||||
}
|
||||
|
@ -478,6 +479,7 @@ class calendar extends rcube_plugin
|
|||
$settings['date_format'] = (string)$this->rc->config->get('calendar_date_format', "yyyy/MM/dd");
|
||||
$settings['date_short'] = (string)$this->rc->config->get('calendar_date_short', "M/d");
|
||||
$settings['date_long'] = (string)$this->rc->config->get('calendar_date_long', "M d yyyy");
|
||||
$settings['date_agena'] = (string)$this->rc->config->get('calendar_date_agenda', "ddd M d");
|
||||
$settings['time_format'] = (string)$this->rc->config->get('calendar_time_format', "HH:mm");
|
||||
$settings['timeslots'] = (int)$this->rc->config->get('calendar_timeslots', 2);
|
||||
$settings['first_day'] = (int)$this->rc->config->get('calendar_first_day', 1);
|
||||
|
|
|
@ -40,6 +40,9 @@ $rcmail_config['calendar_date_short'] = 'M-d';
|
|||
// long date format (used for calendar title)
|
||||
$rcmail_config['calendar_date_long'] = 'MMM d yyyy';
|
||||
|
||||
// date format used for agenda view
|
||||
$rcmail_config['calendar_date_agenda'] = 'ddd MM-dd';
|
||||
|
||||
// timeslots per hour (1, 2, 3, 4, 6)
|
||||
$rcmail_config['calendar_timeslots'] = 2;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
--- js/fullcalendar.js.orig 2011-06-04 13:45:44.000000000 -0600
|
||||
+++ js/fullcalendar.js 2011-06-08 14:30:33.000000000 -0600
|
||||
+++ js/fullcalendar.js 2011-06-10 09:27:50.000000000 -0600
|
||||
@@ -47,12 +47,14 @@
|
||||
titleFormat: {
|
||||
month: 'MMMM yyyy',
|
||||
|
@ -34,7 +34,7 @@
|
|||
+ thisWeek: 'This week',
|
||||
+ nextWeek: 'Next week',
|
||||
+ thisMonth: 'This month',
|
||||
+ nextMonth: 'Next Month',
|
||||
+ nextMonth: 'Next month',
|
||||
+ future: 'Future events'
|
||||
},
|
||||
|
||||
|
@ -59,19 +59,19 @@
|
|||
rangeStart = start;
|
||||
rangeEnd = end;
|
||||
- cache = [];
|
||||
+ cache = typeof src != 'undefined' ? $.grep(cache, function(e) { return !isSourcesEqual(e.source, source); }) : [];
|
||||
+ cache = typeof src != 'undefined' ? $.grep(cache, function(e) { return !isSourcesEqual(e.source, src); }) : [];
|
||||
var fetchID = ++currentFetchID;
|
||||
var len = sources.length;
|
||||
- pendingSourceCnt = len;
|
||||
+ pendingSourceCnt = typeof src == 'undefined' ? len : 1;
|
||||
for (var i=0; i<len; i++) {
|
||||
- fetchEventSource(sources[i], fetchID);
|
||||
+ if (typeof src == 'undefined' || src == sources[i])
|
||||
+ if (typeof src == 'undefined' || isSourcesEqual(sources[i], src))
|
||||
+ fetchEventSource(sources[i], fetchID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5205,4 +5221,307 @@
|
||||
@@ -5205,4 +5221,309 @@
|
||||
|
||||
}
|
||||
|
||||
|
@ -269,6 +269,8 @@
|
|||
+
|
||||
+ lazySegBind(segContainer, seg, bindSeg);
|
||||
+ }
|
||||
+
|
||||
+ markFirstLast(getListContainer());
|
||||
+ }
|
||||
+
|
||||
+ function bindSeg(event, eventElement, seg) {
|
||||
|
@ -364,7 +366,7 @@
|
|||
+ }
|
||||
+
|
||||
+ function setHeight(height, dateChanged) {
|
||||
+ body.css('height', height+'px').css('overflow', 'auto');
|
||||
+ body.css('height', (height-1)+'px').css('overflow', 'auto');
|
||||
+ }
|
||||
+
|
||||
+ function setWidth(width) {
|
||||
|
|
|
@ -48,13 +48,15 @@ var defaults = {
|
|||
month: 'MMMM yyyy',
|
||||
week: "MMM d[ yyyy]{ '—'[ MMM] d yyyy}",
|
||||
day: 'dddd, MMM d, yyyy',
|
||||
list: 'MMM d, yyyy'
|
||||
list: 'MMM d, yyyy',
|
||||
table: 'MMM d, yyyy'
|
||||
},
|
||||
columnFormat: {
|
||||
month: 'ddd',
|
||||
week: 'ddd M/d',
|
||||
day: 'dddd M/d',
|
||||
list: 'dddd, yyyy'
|
||||
list: 'dddd, MMM d, yyyy',
|
||||
table: 'dddd, MMM d, yyyy'
|
||||
},
|
||||
timeFormat: { // for event elements
|
||||
'': 'h(:mm)t' // default
|
||||
|
@ -76,7 +78,8 @@ var defaults = {
|
|||
month: 'month',
|
||||
week: 'week',
|
||||
day: 'day',
|
||||
list: 'list'
|
||||
list: 'list',
|
||||
table: 'table'
|
||||
},
|
||||
listTexts: {
|
||||
from: 'from',
|
||||
|
@ -91,6 +94,9 @@ var defaults = {
|
|||
future: 'Future events'
|
||||
},
|
||||
|
||||
// list options
|
||||
smartSections: false,
|
||||
|
||||
// jquery-ui theming
|
||||
theme: false,
|
||||
buttonIcons: {
|
||||
|
@ -5230,8 +5236,11 @@ function ListEventRenderer() {
|
|||
|
||||
// exports
|
||||
t.renderEvents = renderEvents;
|
||||
t.renderEventTime = renderEventTime;
|
||||
t.compileDaySegs = compileSegs; // for DayEventRenderer
|
||||
t.clearEvents = clearEvents;
|
||||
t.lazySegBind = lazySegBind;
|
||||
t.sortCmp = sortCmp;
|
||||
|
||||
// imports
|
||||
DayEventRenderer.call(t);
|
||||
|
@ -5265,9 +5274,12 @@ function ListEventRenderer() {
|
|||
|
||||
function compileSegs(events) {
|
||||
var segs = [];
|
||||
var colFormat = opt('columnFormat', 'day');
|
||||
var event, i, dd, md, seg, segHash, curSegHash, segDate, curSeg = -1;
|
||||
var colFormat = opt('titleFormat', 'day');
|
||||
var firstDay = opt('firstDay');
|
||||
var smartSegs = opt('smartSections');
|
||||
var event, i, dd, wd, md, seg, segHash, curSegHash, segDate, curSeg = -1;
|
||||
var today = clearTime(new Date());
|
||||
var weekstart = addDays(cloneDate(today), -((today.getDay() - firstDay + 7) % 7));
|
||||
|
||||
for (i=0; i < events.length; i++) {
|
||||
event = events[i];
|
||||
|
@ -5280,40 +5292,33 @@ function ListEventRenderer() {
|
|||
// create smart sections such as today, tomorrow, this week, next week, next month, ect.
|
||||
segDate = cloneDate(event.start < t.start && event.end > t.start ? t.start : event.start, true);
|
||||
dd = dayDiff(segDate, today);
|
||||
wd = Math.floor(dayDiff(segDate, weekstart) / 7);
|
||||
md = segDate.getMonth() + ((segDate.getYear() - today.getYear()) * 12) - today.getMonth();
|
||||
|
||||
// past events
|
||||
if (dd < 0) {
|
||||
// build section title
|
||||
if (!smartSegs) {
|
||||
segHash = formatDate(segDate, colFormat);
|
||||
} else if (dd < 0) {
|
||||
segHash = opt('listTexts', 'past');
|
||||
}
|
||||
// today
|
||||
else if (dd == 0) {
|
||||
} else if (dd == 0) {
|
||||
segHash = opt('listTexts', 'today');
|
||||
}
|
||||
else if (dd == 1) {
|
||||
} else if (dd == 1) {
|
||||
segHash = opt('listTexts', 'tomorrow');
|
||||
}
|
||||
// this week
|
||||
else if (dd < 7) {
|
||||
} else if (wd == 0) {
|
||||
segHash = opt('listTexts', 'thisWeek');
|
||||
}
|
||||
// next week
|
||||
else if (dd >= 7 && dd < 14 && md == 0) {
|
||||
} else if (wd == 1) {
|
||||
segHash = opt('listTexts', 'nextWeek');
|
||||
}
|
||||
else if (md == 0) {
|
||||
} else if (md == 0) {
|
||||
segHash = opt('listTexts', 'thisMonth');
|
||||
}
|
||||
else if (md == 1) {
|
||||
} else if (md == 1) {
|
||||
segHash = opt('listTexts', 'nextMonth');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
segHash = formatDate(segDate, colFormat);
|
||||
}
|
||||
|
||||
// start new segment
|
||||
if (segHash != curSegHash) {
|
||||
segs[++curSeg] = { events: [], start: segDate, title: segHash, daydiff: dd };
|
||||
segs[++curSeg] = { events: [], start: segDate, title: segHash, daydiff: dd, weekdiff: wd, monthdiff: md };
|
||||
curSegHash = segHash;
|
||||
}
|
||||
|
||||
|
@ -5329,11 +5334,9 @@ function ListEventRenderer() {
|
|||
|
||||
function renderSegs(segs, modifiedEventId) {
|
||||
var tm = opt('theme') ? 'ui' : 'fc';
|
||||
var timeFormat = opt('timeFormat');
|
||||
var dateFormat = opt('titleFormat');
|
||||
var headerClass = tm + "-widget-header";
|
||||
var contentClass = tm + "-widget-content";
|
||||
var i, j, seg, event, duration, s, skinCss, skinCssAttr, classes, time, segHeader, segContainer, eventElements;
|
||||
var i, j, seg, event, times, s, skinCss, skinCssAttr, classes, segHeader, segContainer, eventElements;
|
||||
|
||||
for (j=0; j < segs.length; j++) {
|
||||
seg = segs[j];
|
||||
|
@ -5344,7 +5347,7 @@ function ListEventRenderer() {
|
|||
|
||||
for (i=0; i < seg.events.length; i++) {
|
||||
event = seg.events[i];
|
||||
|
||||
times = renderEventTime(event, seg);
|
||||
skinCss = getSkinCss(event, opt);
|
||||
skinCssAttr = (skinCss ? " style='" + skinCss + "'" : '');
|
||||
classes = ['fc-event', 'fc-event-skin', 'fc-event-vert', 'fc-corner-left', 'fc-corner-right', 'fc-corner-top', 'fc-corner-bottom'];
|
||||
|
@ -5352,31 +5355,13 @@ function ListEventRenderer() {
|
|||
classes = classes.concat(event.source.className);
|
||||
}
|
||||
|
||||
// event time/date range to display
|
||||
times = [];
|
||||
duration = event.end.getTime() - event.start.getTime();
|
||||
if (event.start < seg.start) {
|
||||
times.push(opt('listTexts', 'until') + ' ' + formatDate(event.end, (event.allDay || event.end.getDate() != seg.start.getDate()) ? dateFormat : timeFormat));
|
||||
} else if (duration > DAY_MS) {
|
||||
times.push(formatDates(event.start, event.end, dateFormat + '[ - ' + dateFormat + ']'));
|
||||
} else if (seg.daydiff > 1 && seg.daydiff < 7) {
|
||||
times.push(formatDate(event.start, 'ddd'));
|
||||
} else if (seg.daydiff > 1 || seg.daydiff < 0) {
|
||||
times.push(formatDate(event.start, dateFormat));
|
||||
}
|
||||
|
||||
if (!times.length && event.allDay) {
|
||||
times.push(opt('allDayText'));
|
||||
} else if (duration < DAY_MS && !event.allDay) {
|
||||
times.push(formatDates(event.start, event.end, timeFormat))
|
||||
}
|
||||
|
||||
s +=
|
||||
"<div class='" + classes.join(' ') + "'" + skinCssAttr + ">" +
|
||||
"<div class='fc-event-inner fc-event-skin'" + skinCssAttr + ">" +
|
||||
"<div class='fc-event-head fc-event-skin'" + skinCssAttr + ">" +
|
||||
"<div class='fc-event-time'>" +
|
||||
htmlEscape(times.join(' ')) +
|
||||
(times[0] ? '<span class="fc-col-date">' + times[0] + '</span> ' : '') +
|
||||
(times[1] ? '<span class="fc-col-time">' + times[1] + '</span>' : '') +
|
||||
"</div>" +
|
||||
"</div>" +
|
||||
"<div class='fc-event-content'>" +
|
||||
|
@ -5405,7 +5390,7 @@ function ListEventRenderer() {
|
|||
eventElement = $(triggerRes).appendTo(segContainer);
|
||||
}
|
||||
if (event._id === modifiedEventId) {
|
||||
bindSeg(event, eventElement, seg);
|
||||
eventElementHandlers(event, eventElement, seg);
|
||||
} else {
|
||||
eventElement[0]._fci = i; // for lazySegBind
|
||||
}
|
||||
|
@ -5413,16 +5398,44 @@ function ListEventRenderer() {
|
|||
}
|
||||
}
|
||||
|
||||
lazySegBind(segContainer, seg, bindSeg);
|
||||
lazySegBind(segContainer, seg, eventElementHandlers);
|
||||
}
|
||||
|
||||
markFirstLast(getListContainer());
|
||||
}
|
||||
|
||||
function bindSeg(event, eventElement, seg) {
|
||||
eventElementHandlers(event, eventElement);
|
||||
// event time/date range to display
|
||||
function renderEventTime(event, seg) {
|
||||
var timeFormat = opt('timeFormat');
|
||||
var dateFormat = opt('columnFormat');
|
||||
var duration = event.end.getTime() - event.start.getTime();
|
||||
var datestr = '', timestr = '';
|
||||
|
||||
if (!opt('smartSections')) {
|
||||
// no date display if grouped by day
|
||||
} else if (event.start < seg.start) {
|
||||
datestr = opt('listTexts', 'until') + ' ' + formatDate(event.end, (event.allDay || event.end.getDate() != seg.start.getDate()) ? dateFormat : timeFormat);
|
||||
} else if (duration > DAY_MS) {
|
||||
datestr = formatDates(event.start, event.end, dateFormat + '[ - ' + dateFormat + ']');
|
||||
} else if (seg.daydiff == 0) {
|
||||
datestr = opt('listTexts', 'today');
|
||||
} else if (seg.daydiff == 1) {
|
||||
datestr = opt('listTexts', 'tomorrow');
|
||||
} else if (seg.weekdiff == 0 || seg.weekdiff == 1) {
|
||||
datestr = formatDate(event.start, 'dddd');
|
||||
} else if (seg.daydiff > 1 || seg.daydiff < 0) {
|
||||
datestr = formatDate(event.start, dateFormat);
|
||||
}
|
||||
|
||||
if (!datestr && event.allDay) {
|
||||
timestr = opt('allDayText');
|
||||
} else if (duration < DAY_MS && !event.allDay) {
|
||||
timestr = formatDates(event.start, event.end, timeFormat);
|
||||
}
|
||||
|
||||
return [datestr, timestr];
|
||||
}
|
||||
|
||||
|
||||
function lazySegBind(container, seg, bindHandlers) {
|
||||
container.unbind('mouseover').mouseover(function(ev) {
|
||||
var parent = ev.target, e = parent, i, event;
|
||||
|
@ -5526,4 +5539,226 @@ function ListView(element, calendar) {
|
|||
}
|
||||
|
||||
|
||||
/* Additional view: table (by bruederli@kolabsys.com)
|
||||
---------------------------------------------------------------------------------*/
|
||||
|
||||
function TableEventRenderer() {
|
||||
var t = this;
|
||||
|
||||
// imports
|
||||
ListEventRenderer.call(t);
|
||||
var opt = t.opt;
|
||||
var sortCmp = t.sortCmp;
|
||||
var trigger = t.trigger;
|
||||
var compileSegs = t.compileDaySegs;
|
||||
var reportEvents = t.reportEvents;
|
||||
var reportEventClear = t.reportEventClear;
|
||||
var reportEventElement = t.reportEventElement;
|
||||
var eventElementHandlers = t.eventElementHandlers;
|
||||
var renderEventTime = t.renderEventTime;
|
||||
var showEvents = t.showEvents;
|
||||
var hideEvents = t.hideEvents;
|
||||
var getListContainer = t.getDaySegmentContainer;
|
||||
var lazySegBind = t.lazySegBind;
|
||||
var calendar = t.calendar;
|
||||
var formatDate = calendar.formatDate;
|
||||
var formatDates = calendar.formatDates;
|
||||
|
||||
// exports
|
||||
t.renderEvents = renderEvents;
|
||||
t.clearEvents = clearEvents;
|
||||
|
||||
|
||||
/* Rendering
|
||||
--------------------------------------------------------------------*/
|
||||
|
||||
function clearEvents() {
|
||||
reportEventClear();
|
||||
getListContainer().children('tbody').remove();
|
||||
}
|
||||
|
||||
function renderEvents(events, modifiedEventId) {
|
||||
events.sort(sortCmp);
|
||||
reportEvents(events);
|
||||
renderSegs(compileSegs(events), modifiedEventId);
|
||||
}
|
||||
|
||||
function renderSegs(segs, modifiedEventId) {
|
||||
var tm = opt('theme') ? 'ui' : 'fc';
|
||||
var table = getListContainer();
|
||||
var headerClass = tm + "-widget-header";
|
||||
var contentClass = tm + "-widget-content";
|
||||
var i, j, seg, event, times, s, skinCss, skinCssAttr, skinClasses, rowClasses, segHeader, segContainer, eventElements;
|
||||
|
||||
for (j=0; j < segs.length; j++) {
|
||||
seg = segs[j];
|
||||
|
||||
segHeader = $('<tbody class="fc-list-header"><tr><td class="fc-list-header ' + headerClass + '" colspan="5">' + htmlEscape(seg.title) + '</td></tr></tbody>').appendTo(table);
|
||||
segContainer = $('<tbody>').addClass('fc-list-section ' + contentClass).appendTo(table);
|
||||
s = '';
|
||||
|
||||
for (i=0; i < seg.events.length; i++) {
|
||||
event = seg.events[i];
|
||||
times = renderEventTime(event, seg);
|
||||
skinCss = getSkinCss(event, opt);
|
||||
skinCssAttr = (skinCss ? " style='" + skinCss + "'" : '');
|
||||
skinClasses = ['fc-event-skin', 'fc-corner-left', 'fc-corner-right', 'fc-corner-top', 'fc-corner-bottom'];
|
||||
if (event.source && event.source.className) {
|
||||
skinClasses = skinClasses.concat(event.source.className);
|
||||
}
|
||||
rowClasses = ['fc-event', 'fc-event-row', 'fc-'+dayIDs[event.start.getDay()]];
|
||||
if (seg.daydiff == 0) {
|
||||
rowClasses.push('fc-today');
|
||||
}
|
||||
|
||||
s +=
|
||||
"<tr class='" + rowClasses.join(' ') + "'>" +
|
||||
"<td class='fc-event-handle'>" +
|
||||
"<div class='" + skinClasses.join(' ') + "'" + skinCssAttr + ">" +
|
||||
"<span class='fc-event-inner'></span>" +
|
||||
"</div></td>" +
|
||||
"<td class='fc-event-date'>" +
|
||||
htmlEscape(times[0]) +
|
||||
"</td>" +
|
||||
"<td class='fc-event-time'>" +
|
||||
htmlEscape(times[1]) +
|
||||
"</td>" +
|
||||
"<td class='fc-event-title'>" +
|
||||
htmlEscape(event.title) +
|
||||
"</td>" +
|
||||
"<td class='fc-event-location'>" +
|
||||
htmlEscape(event.location) +
|
||||
"</td>" +
|
||||
"</tr>";
|
||||
}
|
||||
|
||||
segContainer[0].innerHTML = s;
|
||||
eventElements = segContainer.children();
|
||||
|
||||
// retrieve elements, run through eventRender callback, bind event handlers
|
||||
for (i=0; i < seg.events.length; i++) {
|
||||
event = seg.events[i];
|
||||
eventElement = $(eventElements[i]); // faster than eq()
|
||||
triggerRes = trigger('eventRender', event, event, eventElement);
|
||||
if (triggerRes === false) {
|
||||
eventElement.remove();
|
||||
} else {
|
||||
if (triggerRes && triggerRes !== true) {
|
||||
eventElement.remove();
|
||||
eventElement = $(triggerRes).appendTo(segContainer);
|
||||
}
|
||||
if (event._id === modifiedEventId) {
|
||||
eventElementHandlers(event, eventElement, seg);
|
||||
} else {
|
||||
eventElement[0]._fci = i; // for lazySegBind
|
||||
}
|
||||
reportEventElement(event, eventElement);
|
||||
}
|
||||
}
|
||||
|
||||
lazySegBind(segContainer, seg, eventElementHandlers);
|
||||
markFirstLast(segContainer);
|
||||
}
|
||||
|
||||
//markFirstLast(table);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
fcViews.table = TableView;
|
||||
|
||||
|
||||
function TableView(element, calendar) {
|
||||
var t = this;
|
||||
|
||||
// exports
|
||||
t.render = render;
|
||||
t.select = dummy;
|
||||
t.unselect = dummy;
|
||||
t.getDaySegmentContainer = function(){ return table; };
|
||||
|
||||
// imports
|
||||
View.call(t, element, calendar, 'table');
|
||||
TableEventRenderer.call(t);
|
||||
var opt = t.opt;
|
||||
var trigger = t.trigger;
|
||||
var clearEvents = t.clearEvents;
|
||||
var reportEventClear = t.reportEventClear;
|
||||
var formatDates = calendar.formatDates;
|
||||
var formatDate = calendar.formatDate;
|
||||
|
||||
// overrides
|
||||
t.setWidth = setWidth;
|
||||
t.setHeight = setHeight;
|
||||
|
||||
// locals
|
||||
var div;
|
||||
var table;
|
||||
var firstDay;
|
||||
var nwe;
|
||||
var tm;
|
||||
var colFormat;
|
||||
|
||||
|
||||
function render(date, delta) {
|
||||
if (delta) {
|
||||
addDays(date, delta);
|
||||
if (!opt('weekends')) {
|
||||
skipWeekend(date, delta < 0 ? -1 : 1);
|
||||
}
|
||||
}
|
||||
t.title = opt('listTexts', 'from') + ' ' + formatDate(date, opt('titleFormat'));
|
||||
t.start = t.visStart = cloneDate(date, true);
|
||||
t.end = addDays(cloneDate(t.start), 1);
|
||||
t.visEnd = addMonths(cloneDate(t.start), 1); // show events one month ahead. Enough?
|
||||
|
||||
updateOptions();
|
||||
|
||||
if (!table) {
|
||||
buildSkeleton();
|
||||
} else {
|
||||
clearEvents();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updateOptions() {
|
||||
firstDay = opt('firstDay');
|
||||
nwe = opt('weekends') ? 0 : 1;
|
||||
tm = opt('theme') ? 'ui' : 'fc';
|
||||
colFormat = opt('columnFormat');
|
||||
}
|
||||
|
||||
|
||||
function buildSkeleton() {
|
||||
var s =
|
||||
"<table class='fc-border-separate' style='width:100%' cellspacing='0'>" +
|
||||
"<colgroup>" +
|
||||
"<col class='fc-event-handle' />" +
|
||||
"<col class='fc-event-date' />" +
|
||||
"<col class='fc-event-time' />" +
|
||||
"<col class='fc-event-title' />" +
|
||||
"<col class='fc-event-location' />" +
|
||||
"</colgroup>" +
|
||||
"</table>";
|
||||
div = $('<div>').addClass('fc-list-content').appendTo(element);
|
||||
table = $(s).appendTo(div);
|
||||
}
|
||||
|
||||
function setHeight(height, dateChanged) {
|
||||
div.css('height', (height-1)+'px').css('overflow', 'auto');
|
||||
}
|
||||
|
||||
function setWidth(width) {
|
||||
// nothing to be done here
|
||||
}
|
||||
|
||||
function dummy() {
|
||||
// Stub.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
})(jQuery);
|
|
@ -461,16 +461,21 @@ a.alarm-action-snooze:after {
|
|||
|
||||
.fc-event-hori .fc-event-time {
|
||||
white-space: nowrap;
|
||||
font-weight: normal;
|
||||
font-weight: normal !important;
|
||||
font-size: 10px;
|
||||
padding-right: 0.6em;
|
||||
}
|
||||
|
||||
.fc-grid .fc-event-time {
|
||||
font-weight: normal !important;
|
||||
padding-right: 0.3em;
|
||||
}
|
||||
|
||||
.fc-event-cateories {
|
||||
font-style:italic;
|
||||
}
|
||||
|
||||
.fc-event-location {
|
||||
div.fc-event-location {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
|
@ -504,6 +509,27 @@ a.alarm-action-snooze:after {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fc-view-list div.fc-list-header,
|
||||
.fc-view-table td.fc-list-header {
|
||||
padding: 3px;
|
||||
background: #dddddd;
|
||||
background-image: -moz-linear-gradient(center top, #f4f4f4, #d2d2d2);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.00, #f4f4f4), color-stop(1.00, #d2d2d2));
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled='true', startColorstr=#f4f4f4, endColorstr=#d2d2d2, GradientType=1);
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.fc-view-list .fc-event-skin .fc-event-content {
|
||||
background: #F6F6F6;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.fc-view-list .fc-event-skin .fc-event-title,
|
||||
.fc-view-list .fc-event-skin .fc-event-location {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* Settings section */
|
||||
|
||||
fieldset #calendarcategories div {
|
||||
|
|
|
@ -619,18 +619,28 @@ table.fc-border-separate {
|
|||
/* List view (by bruederli@kolabsys.com)
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-view-list {
|
||||
.fc-view-list,
|
||||
.fc-view-table {
|
||||
border: 1px solid #ccc;
|
||||
width: 99%;
|
||||
}
|
||||
|
||||
.fc-view-list .fc-list-header {
|
||||
.fc-view-list .fc-list-header,
|
||||
.fc-view-table td.fc-list-header {
|
||||
border-width: 0;
|
||||
border-bottom-width: 1px;
|
||||
padding: 2px;
|
||||
padding: 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fc-view-table td.fc-list-header {
|
||||
_border-top-width: 1px;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-first td.fc-list-header {
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.fc-list-section {
|
||||
padding: 4px 2px;
|
||||
border-width: 0;
|
||||
|
@ -645,3 +655,53 @@ table.fc-border-separate {
|
|||
position: relative;
|
||||
margin: 1px 2px 3px 2px;
|
||||
}
|
||||
|
||||
.fc-view-table tr.fc-event td {
|
||||
padding: 2px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.fc-view-table tr.fc-event td.fc-event-handle {
|
||||
padding: 3px 8px 3px 3px;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-event-handle .fc-event-skin {
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-event-handle .fc-event-inner {
|
||||
display: block;
|
||||
width: 8px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
}
|
||||
|
||||
.fc-view-table table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fc-view-table col.fc-event-handle {
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
.fc-view-table col.fc-event-date {
|
||||
width: 7em;
|
||||
}
|
||||
|
||||
.fc-view-table col.fc-event-time {
|
||||
width: 8em;
|
||||
}
|
||||
|
||||
.fc-view-table col.fc-event-location {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.fc-view-table td.fc-event-date,
|
||||
.fc-view-table td.fc-event-time {
|
||||
white-space: nowrap;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue