2010-09-19 07:54:35 +02:00
|
|
|
|
|
|
|
setDefaults({
|
|
|
|
weekMode: 'fixed'
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
function BasicView(element, calendar, viewName) {
|
|
|
|
var t = this;
|
|
|
|
|
|
|
|
|
|
|
|
// exports
|
|
|
|
t.renderBasic = renderBasic;
|
|
|
|
t.setHeight = setHeight;
|
|
|
|
t.setWidth = setWidth;
|
|
|
|
t.renderDayOverlay = renderDayOverlay;
|
|
|
|
t.defaultSelectionEnd = defaultSelectionEnd;
|
|
|
|
t.renderSelection = renderSelection;
|
|
|
|
t.clearSelection = clearSelection;
|
2011-01-24 08:10:25 +01:00
|
|
|
t.reportDayClick = reportDayClick; // for selection (kinda hacky)
|
2010-09-19 07:54:35 +02:00
|
|
|
t.dragStart = dragStart;
|
|
|
|
t.dragStop = dragStop;
|
|
|
|
t.defaultEventEnd = defaultEventEnd;
|
|
|
|
t.getHoverListener = function() { return hoverListener };
|
|
|
|
t.colContentLeft = colContentLeft;
|
|
|
|
t.colContentRight = colContentRight;
|
|
|
|
t.dayOfWeekCol = dayOfWeekCol;
|
2010-11-10 07:54:41 +01:00
|
|
|
t.dateCell = dateCell;
|
2010-09-19 07:54:35 +02:00
|
|
|
t.cellDate = cellDate;
|
|
|
|
t.cellIsAllDay = function() { return true };
|
2011-01-24 08:10:25 +01:00
|
|
|
t.allDayRow = allDayRow;
|
2010-09-19 07:54:35 +02:00
|
|
|
t.allDayBounds = allDayBounds;
|
|
|
|
t.getRowCnt = function() { return rowCnt };
|
|
|
|
t.getColCnt = function() { return colCnt };
|
|
|
|
t.getColWidth = function() { return colWidth };
|
|
|
|
t.getDaySegmentContainer = function() { return daySegmentContainer };
|
|
|
|
|
|
|
|
|
|
|
|
// imports
|
|
|
|
View.call(t, element, calendar, viewName);
|
|
|
|
OverlayManager.call(t);
|
|
|
|
SelectionManager.call(t);
|
|
|
|
BasicEventRenderer.call(t);
|
|
|
|
var opt = t.opt;
|
|
|
|
var trigger = t.trigger;
|
|
|
|
var clearEvents = t.clearEvents;
|
|
|
|
var renderOverlay = t.renderOverlay;
|
|
|
|
var clearOverlays = t.clearOverlays;
|
|
|
|
var daySelectionMousedown = t.daySelectionMousedown;
|
|
|
|
var formatDate = calendar.formatDate;
|
|
|
|
|
|
|
|
|
|
|
|
// locals
|
2011-01-24 08:10:25 +01:00
|
|
|
|
|
|
|
var head;
|
|
|
|
var headCells;
|
|
|
|
var body;
|
|
|
|
var bodyRows;
|
|
|
|
var bodyCells;
|
|
|
|
var bodyFirstCells;
|
|
|
|
var bodyCellTopInners;
|
2010-09-19 07:54:35 +02:00
|
|
|
var daySegmentContainer;
|
2011-01-24 08:10:25 +01:00
|
|
|
|
|
|
|
var viewWidth;
|
|
|
|
var viewHeight;
|
|
|
|
var colWidth;
|
|
|
|
|
|
|
|
var rowCnt, colCnt;
|
2010-09-19 07:54:35 +02:00
|
|
|
var coordinateGrid;
|
|
|
|
var hoverListener;
|
|
|
|
var colContentPositions;
|
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
var rtl, dis, dit;
|
|
|
|
var firstDay;
|
|
|
|
var nwe;
|
|
|
|
var tm;
|
|
|
|
var colFormat;
|
|
|
|
|
2010-09-19 07:54:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Rendering
|
|
|
|
------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
disableTextSelection(element.addClass('fc-grid'));
|
|
|
|
|
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
function renderBasic(maxr, r, c, showNumbers) {
|
2010-09-19 07:54:35 +02:00
|
|
|
rowCnt = r;
|
|
|
|
colCnt = c;
|
2011-01-24 08:10:25 +01:00
|
|
|
updateOptions();
|
|
|
|
var firstTime = !body;
|
|
|
|
if (firstTime) {
|
|
|
|
buildSkeleton(maxr, showNumbers);
|
|
|
|
}else{
|
|
|
|
clearEvents();
|
|
|
|
}
|
|
|
|
updateCells(firstTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updateOptions() {
|
2010-09-19 07:54:35 +02:00
|
|
|
rtl = opt('isRTL');
|
|
|
|
if (rtl) {
|
|
|
|
dis = -1;
|
|
|
|
dit = colCnt - 1;
|
|
|
|
}else{
|
|
|
|
dis = 1;
|
|
|
|
dit = 0;
|
|
|
|
}
|
|
|
|
firstDay = opt('firstDay');
|
|
|
|
nwe = opt('weekends') ? 0 : 1;
|
2011-01-24 08:10:25 +01:00
|
|
|
tm = opt('theme') ? 'ui' : 'fc';
|
|
|
|
colFormat = opt('columnFormat');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function buildSkeleton(maxRowCnt, showNumbers) {
|
|
|
|
var s;
|
|
|
|
var headerClass = tm + "-widget-header";
|
|
|
|
var contentClass = tm + "-widget-content";
|
|
|
|
var i, j;
|
|
|
|
var table;
|
2010-09-19 07:54:35 +02:00
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
s =
|
|
|
|
"<table class='fc-border-separate' style='width:100%' cellspacing='0'>" +
|
|
|
|
"<thead>" +
|
|
|
|
"<tr>";
|
|
|
|
for (i=0; i<colCnt; i++) {
|
|
|
|
s +=
|
|
|
|
"<th class='fc- " + headerClass + "'/>";
|
|
|
|
}
|
|
|
|
s +=
|
|
|
|
"</tr>" +
|
|
|
|
"</thead>" +
|
|
|
|
"<tbody>";
|
|
|
|
for (i=0; i<maxRowCnt; i++) {
|
|
|
|
s +=
|
|
|
|
"<tr class='fc-week" + i + "'>";
|
|
|
|
for (j=0; j<colCnt; j++) {
|
|
|
|
s +=
|
|
|
|
"<td class='fc- " + contentClass + " fc-day" + (i*colCnt+j) + "'>" +
|
|
|
|
"<div>" +
|
|
|
|
(showNumbers ?
|
|
|
|
"<div class='fc-day-number'/>" :
|
|
|
|
''
|
|
|
|
) +
|
|
|
|
"<div class='fc-day-content'>" +
|
|
|
|
"<div style='position:relative'> </div>" +
|
|
|
|
"</div>" +
|
|
|
|
"</div>" +
|
|
|
|
"</td>";
|
|
|
|
}
|
|
|
|
s +=
|
|
|
|
"</tr>";
|
|
|
|
}
|
|
|
|
s +=
|
|
|
|
"</tbody>" +
|
|
|
|
"</table>";
|
|
|
|
table = $(s).appendTo(element);
|
2010-09-19 07:54:35 +02:00
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
head = table.find('thead');
|
|
|
|
headCells = head.find('th');
|
|
|
|
body = table.find('tbody');
|
|
|
|
bodyRows = body.find('tr');
|
|
|
|
bodyCells = body.find('td');
|
|
|
|
bodyFirstCells = bodyCells.filter(':first-child');
|
|
|
|
bodyCellTopInners = bodyRows.eq(0).find('div.fc-day-content div');
|
2010-09-19 07:54:35 +02:00
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
markFirstLast(head.add(head.find('tr'))); // marks first+last tr/th's
|
|
|
|
markFirstLast(bodyRows); // marks first+last td's
|
|
|
|
bodyRows.eq(0).addClass('fc-first'); // fc-last is done in updateCells
|
2010-09-19 07:54:35 +02:00
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
dayBind(bodyCells);
|
2010-09-19 07:54:35 +02:00
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
daySegmentContainer =
|
|
|
|
$("<div style='position:absolute;z-index:8;top:0;left:0'/>")
|
|
|
|
.appendTo(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updateCells(firstTime) {
|
|
|
|
var optimize = !firstTime && rowCnt > 1;
|
|
|
|
var month = t.start.getMonth();
|
|
|
|
var today = clearTime(new Date());
|
|
|
|
var cell;
|
|
|
|
var date;
|
|
|
|
var row;
|
|
|
|
|
|
|
|
if (!optimize) {
|
|
|
|
headCells.each(function(i, _cell) {
|
|
|
|
cell = $(_cell);
|
|
|
|
date = indexDate(i);
|
|
|
|
cell.html(formatDate(date, colFormat));
|
|
|
|
setDayID(cell, date);
|
|
|
|
});
|
|
|
|
}
|
2010-09-19 07:54:35 +02:00
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
bodyCells.each(function(i, _cell) {
|
|
|
|
cell = $(_cell);
|
|
|
|
date = indexDate(i);
|
|
|
|
if (date.getMonth() == month) {
|
|
|
|
cell.removeClass('fc-other-month');
|
|
|
|
}else{
|
|
|
|
cell.addClass('fc-other-month');
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
2011-01-24 08:10:25 +01:00
|
|
|
if (+date == +today) {
|
|
|
|
cell.addClass(tm + '-state-highlight fc-today');
|
|
|
|
}else{
|
|
|
|
cell.removeClass(tm + '-state-highlight fc-today');
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
2011-01-24 08:10:25 +01:00
|
|
|
cell.find('div.fc-day-number').text(date.getDate());
|
|
|
|
if (!optimize) {
|
|
|
|
setDayID(cell, date);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
bodyRows.each(function(i, _row) {
|
|
|
|
row = $(_row);
|
|
|
|
if (i < rowCnt) {
|
|
|
|
row.show();
|
|
|
|
if (i == rowCnt-1) {
|
|
|
|
row.addClass('fc-last');
|
2010-09-19 07:54:35 +02:00
|
|
|
}else{
|
2011-01-24 08:10:25 +01:00
|
|
|
row.removeClass('fc-last');
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
2011-01-24 08:10:25 +01:00
|
|
|
}else{
|
|
|
|
row.hide();
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
2011-01-24 08:10:25 +01:00
|
|
|
});
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
|
2010-09-19 07:54:35 +02:00
|
|
|
function setHeight(height) {
|
|
|
|
viewHeight = height;
|
2011-01-24 08:10:25 +01:00
|
|
|
|
|
|
|
var bodyHeight = viewHeight - head.height();
|
|
|
|
var rowHeight;
|
|
|
|
var rowHeightLast;
|
|
|
|
var cell;
|
|
|
|
|
2010-09-19 07:54:35 +02:00
|
|
|
if (opt('weekMode') == 'variable') {
|
2011-01-24 08:10:25 +01:00
|
|
|
rowHeight = rowHeightLast = Math.floor(bodyHeight / (rowCnt==1 ? 2 : 6));
|
2010-09-19 07:54:35 +02:00
|
|
|
}else{
|
2011-01-24 08:10:25 +01:00
|
|
|
rowHeight = Math.floor(bodyHeight / rowCnt);
|
|
|
|
rowHeightLast = bodyHeight - rowHeight * (rowCnt-1);
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
2011-01-24 08:10:25 +01:00
|
|
|
|
|
|
|
bodyFirstCells.each(function(i, _cell) {
|
|
|
|
if (i < rowCnt) {
|
|
|
|
cell = $(_cell);
|
|
|
|
setMinHeight(
|
|
|
|
cell.find('> div'),
|
|
|
|
(i==rowCnt-1 ? rowHeightLast : rowHeight) - vsides(cell)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function setWidth(width) {
|
|
|
|
viewWidth = width;
|
|
|
|
colContentPositions.clear();
|
|
|
|
colWidth = Math.floor(viewWidth / colCnt);
|
2011-01-24 08:10:25 +01:00
|
|
|
setOuterWidth(headCells.slice(0, -1), colWidth);
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Day clicking and binding
|
|
|
|
-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
function dayBind(days) {
|
|
|
|
days.click(dayClick)
|
|
|
|
.mousedown(daySelectionMousedown);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function dayClick(ev) {
|
|
|
|
if (!opt('selectable')) { // SelectionManager will worry about dayClick
|
2011-01-24 08:10:25 +01:00
|
|
|
var index = parseInt(this.className.match(/fc\-day(\d+)/)[1]); // TODO: maybe use .data
|
|
|
|
var date = indexDate(index);
|
2010-09-19 07:54:35 +02:00
|
|
|
trigger('dayClick', this, date, true, ev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Semi-transparent Overlay Helpers
|
|
|
|
------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
function renderDayOverlay(overlayStart, overlayEnd, refreshCoordinateGrid) { // overlayEnd is exclusive
|
|
|
|
if (refreshCoordinateGrid) {
|
|
|
|
coordinateGrid.build();
|
|
|
|
}
|
|
|
|
var rowStart = cloneDate(t.visStart);
|
|
|
|
var rowEnd = addDays(cloneDate(rowStart), colCnt);
|
|
|
|
for (var i=0; i<rowCnt; i++) {
|
|
|
|
var stretchStart = new Date(Math.max(rowStart, overlayStart));
|
|
|
|
var stretchEnd = new Date(Math.min(rowEnd, overlayEnd));
|
|
|
|
if (stretchStart < stretchEnd) {
|
|
|
|
var colStart, colEnd;
|
|
|
|
if (rtl) {
|
|
|
|
colStart = dayDiff(stretchEnd, rowStart)*dis+dit+1;
|
|
|
|
colEnd = dayDiff(stretchStart, rowStart)*dis+dit+1;
|
|
|
|
}else{
|
|
|
|
colStart = dayDiff(stretchStart, rowStart);
|
|
|
|
colEnd = dayDiff(stretchEnd, rowStart);
|
|
|
|
}
|
|
|
|
dayBind(
|
|
|
|
renderCellOverlay(i, colStart, i, colEnd-1)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
addDays(rowStart, 7);
|
|
|
|
addDays(rowEnd, 7);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function renderCellOverlay(row0, col0, row1, col1) { // row1,col1 is inclusive
|
|
|
|
var rect = coordinateGrid.rect(row0, col0, row1, col1, element);
|
|
|
|
return renderOverlay(rect, element);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Selection
|
|
|
|
-----------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
function defaultSelectionEnd(startDate, allDay) {
|
|
|
|
return cloneDate(startDate);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function renderSelection(startDate, endDate, allDay) {
|
2010-11-10 07:54:41 +01:00
|
|
|
renderDayOverlay(startDate, addDays(cloneDate(endDate), 1), true); // rebuild every time???
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function clearSelection() {
|
|
|
|
clearOverlays();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
function reportDayClick(date, allDay, ev) {
|
|
|
|
var cell = dateCell(date);
|
|
|
|
var _element = bodyCells[cell.row*colCnt + cell.col];
|
|
|
|
trigger('dayClick', _element, date, allDay, ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-19 07:54:35 +02:00
|
|
|
|
|
|
|
/* External Dragging
|
|
|
|
-----------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
function dragStart(_dragElement, ev, ui) {
|
|
|
|
hoverListener.start(function(cell) {
|
|
|
|
clearOverlays();
|
|
|
|
if (cell) {
|
|
|
|
renderCellOverlay(cell.row, cell.col, cell.row, cell.col);
|
|
|
|
}
|
|
|
|
}, ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function dragStop(_dragElement, ev, ui) {
|
|
|
|
var cell = hoverListener.stop();
|
|
|
|
clearOverlays();
|
|
|
|
if (cell) {
|
|
|
|
var d = cellDate(cell);
|
|
|
|
trigger('drop', _dragElement, d, true, ev, ui);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Utilities
|
|
|
|
--------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
function defaultEventEnd(event) {
|
|
|
|
return cloneDate(event.start);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
coordinateGrid = new CoordinateGrid(function(rows, cols) {
|
|
|
|
var e, n, p;
|
2011-01-24 08:10:25 +01:00
|
|
|
headCells.each(function(i, _e) {
|
2010-09-19 07:54:35 +02:00
|
|
|
e = $(_e);
|
|
|
|
n = e.offset().left;
|
|
|
|
if (i) {
|
|
|
|
p[1] = n;
|
|
|
|
}
|
|
|
|
p = [n];
|
|
|
|
cols[i] = p;
|
|
|
|
});
|
|
|
|
p[1] = n + e.outerWidth();
|
2011-01-24 08:10:25 +01:00
|
|
|
bodyRows.each(function(i, _e) {
|
|
|
|
if (i < rowCnt) {
|
|
|
|
e = $(_e);
|
|
|
|
n = e.offset().top;
|
|
|
|
if (i) {
|
|
|
|
p[1] = n;
|
|
|
|
}
|
|
|
|
p = [n];
|
|
|
|
rows[i] = p;
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
p[1] = n + e.outerHeight();
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
hoverListener = new HoverListener(coordinateGrid);
|
|
|
|
|
|
|
|
|
|
|
|
colContentPositions = new HorizontalPositionCache(function(col) {
|
2011-01-24 08:10:25 +01:00
|
|
|
return bodyCellTopInners.eq(col);
|
2010-09-19 07:54:35 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
function colContentLeft(col) {
|
|
|
|
return colContentPositions.left(col);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function colContentRight(col) {
|
|
|
|
return colContentPositions.right(col);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-10 07:54:41 +01:00
|
|
|
|
|
|
|
|
|
|
|
function dateCell(date) {
|
|
|
|
return {
|
|
|
|
row: Math.floor(dayDiff(date, t.visStart) / 7),
|
2011-01-24 08:10:25 +01:00
|
|
|
col: dayOfWeekCol(date.getDay())
|
2010-11-10 07:54:41 +01:00
|
|
|
};
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function cellDate(cell) {
|
2011-01-24 08:10:25 +01:00
|
|
|
return _cellDate(cell.row, cell.col);
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-24 08:10:25 +01:00
|
|
|
function _cellDate(row, col) {
|
|
|
|
return addDays(cloneDate(t.visStart), row*7 + col*dis+dit);
|
|
|
|
// what about weekends in middle of week?
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function indexDate(index) {
|
|
|
|
return _cellDate(Math.floor(index/colCnt), index%colCnt);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function dayOfWeekCol(dayOfWeek) {
|
|
|
|
return ((dayOfWeek - Math.max(firstDay, nwe) + colCnt) % colCnt) * dis + dit;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function allDayRow(i) {
|
|
|
|
return bodyRows.eq(i);
|
2010-09-19 07:54:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function allDayBounds(i) {
|
|
|
|
return {
|
|
|
|
left: 0,
|
|
|
|
right: viewWidth
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|