From 13f7d167b3ff7058125b8715a48908a2cfdc8e7d Mon Sep 17 00:00:00 2001 From: Adam Shaw Date: Mon, 12 Oct 2009 06:35:33 +0000 Subject: [PATCH] 1.4, getting there, still need testing+docs --- examples/basic.html | 2 + examples/gcal.html | 2 + examples/json.html | 2 + examples/theme.html | 7 +- examples/views.html | 15 +- src/agenda.js | 559 ++++++++++++++++++++++++-------------------- src/css/agenda.css | 211 +++++------------ src/css/main.css | 2 +- src/grid.js | 49 +--- src/main.js | 62 +++-- src/view.js | 43 ++-- tests/basic.html | 24 +- tests/gcal.html | 3 + tests/locale.html | 2 +- tests/methods.html | 4 +- tests/options.html | 2 +- tests/sources.html | 4 +- tests/theming.html | 2 +- tests/triggers.html | 8 +- 19 files changed, 475 insertions(+), 528 deletions(-) diff --git a/examples/basic.html b/examples/basic.html index c765ead..b8885a7 100644 --- a/examples/basic.html +++ b/examples/basic.html @@ -4,12 +4,14 @@ + + diff --git a/examples/gcal.html b/examples/gcal.html index ff901d1..f0eb1a9 100644 --- a/examples/gcal.html +++ b/examples/gcal.html @@ -4,9 +4,11 @@ + + diff --git a/examples/json.html b/examples/json.html index 1603965..de892ee 100644 --- a/examples/json.html +++ b/examples/json.html @@ -4,12 +4,14 @@ + + diff --git a/examples/theme.html b/examples/theme.html index 12ab893..2f89952 100755 --- a/examples/theme.html +++ b/examples/theme.html @@ -5,12 +5,14 @@ + + @@ -35,11 +37,6 @@ $('#calendar').fullCalendar({ theme: true, editable: true, - header: { - left: 'prev,next today', - center: 'title', - right: 'month,basicWeek,basicDay' - }, events: [ { id: 1, diff --git a/examples/views.html b/examples/views.html index 54d277c..cad39c4 100755 --- a/examples/views.html +++ b/examples/views.html @@ -4,12 +4,14 @@ + + @@ -34,9 +36,15 @@ $('#calendar').fullCalendar({ editable: true, header: { - left: 'prev,next today', - center: 'title', - right: 'month,basicWeek,basicDay' + left: 'title', + center: 'month,agendaWeek,basicWeek,agendaDay,basicDay', + right: 'today prev,next' + }, + buttonText: { + agendaWeek: 'agendaWeek', + basicWeek: 'basicWeek', + agendaDay: 'agendaDay', + basicDay: 'basicDay' }, events: [ { @@ -85,7 +93,6 @@ text-align: center; font-size: 14px; font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif; - text-align: left; } #calendar { diff --git a/src/agenda.js b/src/agenda.js index d2689b8..7eb2243 100755 --- a/src/agenda.js +++ b/src/agenda.js @@ -1,18 +1,14 @@ -// todo: scrolling -// todo: check all other options -// cleanup CSS -// optimize moveEvent/resizeEvent, to return revert function - - /* Agenda Views: agendaWeek/agendaDay -----------------------------------------------------------------------------*/ setDefaults({ allDayHeader: true, + allDayText: 'all-day', slotMinutes: 30, defaultEventMinutes: 120, - axisFormat: 'htt', + defaultScrollHour: 6, + axisFormat: 'h(:mm)tt', timeFormat: { agenda: 'h:mm{ - h:mm}' }, @@ -119,6 +115,7 @@ function Agenda(element, options, methods) { var d0 = rtl ? addDays(cloneDate(view.visEnd), -1) : cloneDate(view.visStart), d = cloneDate(d0), + scrollDate = cloneDate(d0), today = clearTime(new Date()); if (!head) { // first time rendering, build from scratch @@ -143,7 +140,7 @@ function Agenda(element, options, methods) { s+= " "; if (options.allDayHeader) { s+= "" + - "all day" + + "" + options.allDayText + "" + "" + "
 
" + " " + @@ -222,6 +219,10 @@ function Agenda(element, options, methods) { } updateSize(); + + scrollDate.setHours(options.defaultScrollHour); + body.scrollTop(timePosition(d0, scrollDate) + 1); // +1 for the border + fetchEvents(renderEvents); }; @@ -350,18 +351,19 @@ function Agenda(element, options, methods) { levelHeight, j, seg, event, - eventClasses, + className, leftDay, leftRounded, rightDay, rightRounded, left, right, - eventElement, anchorElement; + eventElement, anchorElement, + triggerRes; for (i=0; i") + eventElement = $("
") .append(anchorElement = $("") .append($("") - .text(event.title))) - .css({ - position: 'absolute', - top: top, - left: left, - zIndex: 8 - }) - .appendTo(head); - setOuterWidth(eventElement, right-left, true); - if (seg.isEnd) { - view.resizableDayEvent(event, eventElement, colWidth); + .text(event.title))); + if (event.url) { + anchorElement.attr('href', event.url); + } + triggerRes = view.trigger('eventRender', event, event, eventElement); + if (triggerRes !== false) { + if (triggerRes && typeof triggerRes != 'boolean') { + eventElement = $(triggerRes); + } + eventElement + .css({ + position: 'absolute', + top: top, + left: left, + zIndex: 8 + }) + .appendTo(head); + setOuterWidth(eventElement, right-left, true); + view.eventElementHandlers(event, eventElement); + if (event.editable || event.editable == undefined && options.editable) { + draggableDayEvent(event, eventElement, seg.isStart); + if (seg.isEnd) { + view.resizableDayEvent(event, eventElement, colWidth); + } + } + view.reportEventElement(event, eventElement); + levelHeight = Math.max(levelHeight, eventElement.outerHeight(true)); } - draggableDayEvent(event, eventElement, seg.isStart); - view.reportEventElement(event, eventElement); - levelHeight = Math.max(levelHeight, eventElement.outerHeight(true)); } top += levelHeight; rowHeight += levelHeight; @@ -426,7 +441,9 @@ function Agenda(element, options, methods) { top, bottom, tdInner, width, left, - eventElement, anchorElement, timeElement, titleElement; + className, + eventElement, anchorElement, timeElement, titleElement, + triggerRes; for (colI=0; colI") + className = 'fc-event fc-event-vert '; + if (seg.isStart) { + className += 'fc-corner-top '; + } + if (seg.isEnd) { + className += 'fc-corner-bottom '; + } + eventElement = $("
") .append(anchorElement = $("") .append(titleElement = $("") .text(event.title))) - .css({ - position: 'absolute', - zIndex: 8, - top: top, - left: left - }) - .appendTo(bodyContent); - if (event.url) { - anchorElement.attr('href', event.url); - } if (seg.isStart) { - eventElement.addClass('fc-corner-top'); // add the time header anchorElement .prepend(timeElement = $("") @@ -477,18 +490,37 @@ function Agenda(element, options, methods) { }else{ timeElement = null; } - if (seg.isEnd) { - eventElement.addClass('fc-corner-bottom'); - resizableSlotEvent(event, eventElement, timeElement); + if (event.url) { + anchorElement.attr('href', event.url); } - setOuterWidth(eventElement, width, true); - setOuterHeight(eventElement, bottom-top, true); - if (timeElement && eventElement.height() - titleElement.position().top < 10) { - // event title doesn't have enough room, put next to the time - timeElement.text(formatDate(event.start, view.option('timeFormat')) + ' - ' + event.title); - titleElement.remove(); + triggerRes = view.trigger('eventRender', event, event, eventElement); + if (triggerRes !== false) { + if (triggerRes && typeof triggerRes != 'boolean') { + eventElement = $(triggerRes); + } + eventElement + .css({ + position: 'absolute', + zIndex: 8, + top: top, + left: left + }) + .appendTo(bodyContent); + setOuterWidth(eventElement, width, true); + setOuterHeight(eventElement, bottom-top, true); + if (timeElement && eventElement.height() - titleElement.position().top < 10) { + // event title doesn't have enough room, put next to the time + timeElement.text(formatDate(event.start, view.option('timeFormat')) + ' - ' + event.title); + titleElement.remove(); + } + view.eventElementHandlers(event, eventElement); + if (event.editable || event.editable == undefined && options.editable) { + draggableSlotEvent(event, eventElement, timeElement); + if (seg.isEnd) { + resizableSlotEvent(event, eventElement, timeElement); + } + } } - draggableSlotEvent(event, eventElement, timeElement); view.reportEventElement(event, eventElement); } } @@ -506,84 +538,90 @@ function Agenda(element, options, methods) { // when event starts out FULL-DAY function draggableDayEvent(event, eventElement, isStart) { - var origPosition, origWidth, - resetElement, - allDay=true, - matrix; - eventElement.draggable({ - zIndex: 9, - opacity: view.option('month'), // use whatever the month view was using - start: function(ev) { - origPosition = eventElement.position(); - origWidth = eventElement.width(); - resetElement = function() { - if (!allDay) { - eventElement - .width(origWidth) - .height('') - .draggable('option', 'grid', null); - allDay = true; - } - }; - matrix = new HoverMatrix(function(cell) { - eventElement.draggable('option', 'revert', !cell || !cell.rowDelta && !cell.colDelta); - if (cell) { - if (!cell.row) { // on full-days - resetElement(); - view.showOverlay(cell); - }else{ // mouse is over bottom slots - if (isStart && allDay) { - // convert event to temporary slot-event - setOuterHeight( - eventElement.width(colWidth - 10), // don't use entire width - rowHeight * Math.round( - (event.end ? ((event.end - event.start)/MINUTE_MS) : options.defaultEventMinutes) - /options.slotMinutes) - ); - eventElement.draggable('option', 'grid', [colWidth, 1]); - allDay = false; + if (!options.disableDragging && eventElement.draggable) { + var origPosition, origWidth, + resetElement, + allDay=true, + matrix; + eventElement.draggable({ + zIndex: 9, + opacity: view.option('dragOpacity', 'month'), // use whatever the month view was using + revertDuration: options.dragRevertDuration, + start: function(ev, ui) { + view.hideEvents(event, eventElement); + view.trigger('eventDragStart', eventElement, event, ev, ui); + origPosition = eventElement.position(); + origWidth = eventElement.width(); + resetElement = function() { + if (!allDay) { + eventElement + .width(origWidth) + .height('') + .draggable('option', 'grid', null); + allDay = true; + } + }; + matrix = new HoverMatrix(function(cell) { + eventElement.draggable('option', 'revert', !cell || !cell.rowDelta && !cell.colDelta); + if (cell) { + if (!cell.row) { // on full-days + resetElement(); + view.showOverlay(cell); + }else{ // mouse is over bottom slots + if (isStart && allDay) { + // convert event to temporary slot-event + setOuterHeight( + eventElement.width(colWidth - 10), // don't use entire width + rowHeight * Math.round( + (event.end ? ((event.end - event.start)/MINUTE_MS) : options.defaultEventMinutes) + /options.slotMinutes) + ); + eventElement.draggable('option', 'grid', [colWidth, 1]); + allDay = false; + } + view.hideOverlay(); } + }else{ // mouse is outside of everything view.hideOverlay(); } - }else{ // mouse is outside of everything - view.hideOverlay(); + }); + matrix.row(head.find('td')); + bg.find('td').each(function() { + matrix.col(this); + }); + matrix.row(body); + matrix.mouse(ev.pageX, ev.pageY); + }, + drag: function(ev, ui) { + matrix.mouse(ev.pageX, ev.pageY); + }, + stop: function(ev, ui) { + view.hideOverlay(); + view.trigger('eventDragStop', eventElement, event, ev, ui); + var cell = matrix.cell, + dayDelta = dis * ( + allDay ? // can't trust cell.colDelta when using slot grid + (cell ? cell.colDelta : 0) : + Math.floor((ui.position.left - origPosition.left) / colWidth) + ); + if (!cell || !dayDelta && !cell.rowDelta) { + // over nothing (has reverted) + resetElement(); + view.showEvents(event, eventElement); + }else{ + //eventElement.find('a').removeAttr('href'); // prevents safari from visiting the link + view.eventDrop( + this, event, dayDelta, + allDay ? 0 : // minute delta + Math.round((eventElement.offset().top - bodyContent.offset().top) / rowHeight) + * options.slotMinutes + - (event.start.getHours() * 60 + event.start.getMinutes()), + allDay, ev, ui + ); } - }); - view.hideEvents(event, eventElement); - matrix.row(head.find('td')); - bg.find('td').each(function() { - matrix.col(this); - }); - matrix.row(body); - matrix.mouse(ev.pageX, ev.pageY); - }, - drag: function(ev, ui) { - matrix.mouse(ev.pageX, ev.pageY); - }, - stop: function(ev, ui) { - view.hideOverlay(); - var cell = matrix.cell, - dayDelta = dis * ( - allDay ? // can't trust cell.colDelta when using slot grid - (cell ? cell.colDelta : 0) : - Math.floor((ui.position.left - origPosition.left) / colWidth) - ); - if (!cell || !dayDelta && !cell.rowDelta) { - // over nothing (has reverted) - resetElement(); - view.showEvents(event, eventElement); - }else{ - view.eventDrop( - this, event, dayDelta, - allDay ? 0 : // minute delta - Math.round((eventElement.offset().top - bodyContent.offset().top) / rowHeight) - * options.slotMinutes - - (event.start.getHours() * 60 + event.start.getMinutes()), - allDay, ev, ui - ); } - } - }); + }); + } } @@ -591,108 +629,113 @@ function Agenda(element, options, methods) { // when event starts out IN TIMESLOTS function draggableSlotEvent(event, eventElement, timeElement) { - var origPosition, - resetElement, - prevSlotDelta, slotDelta, - allDay=false, - matrix; - eventElement.draggable({ - zIndex: 9, - scroll: false, - grid: [colWidth, rowHeight], - axis: colCnt==1 ? 'y' : false, - opacity: view.option('dragOpacity'), - start: function(ev, ui) { - if ($.browser.msie) { - eventElement.find('span.fc-event-bg').hide(); // nested opacities mess up in IE, just hide - } - origPosition = eventElement.position(); - resetElement = function() { - // convert back to original slot-event - if (allDay) { - if (timeElement) { - timeElement.css('display', ''); // show() was causing display=inline - } - eventElement.draggable('option', 'grid', [colWidth, rowHeight]); - allDay = false; + if (!options.disableDragging && eventElement.draggable) { + var origPosition, + resetElement, + prevSlotDelta, slotDelta, + allDay=false, + matrix; + eventElement.draggable({ + zIndex: 9, + scroll: false, + grid: [colWidth, rowHeight], + axis: colCnt==1 ? 'y' : false, + opacity: view.option('dragOpacity'), + revertDuration: options.dragRevertDuration, + start: function(ev, ui) { + view.hideEvents(event, eventElement); + view.trigger('eventDragStart', eventElement, event, ev, ui); + if ($.browser.msie) { + eventElement.find('span.fc-event-bg').hide(); // nested opacities mess up in IE, just hide } - }; - prevSlotDelta = 0; - matrix = new HoverMatrix(function(cell) { - eventElement.draggable('option', 'revert', !cell); - if (cell) { - if (!cell.row && options.allDayHeader) { // over full days - if (!allDay) { - // convert to temporary all-day event - allDay = true; - if (timeElement) { - timeElement.hide(); - } - eventElement.draggable('option', 'grid', null); + origPosition = eventElement.position(); + resetElement = function() { + // convert back to original slot-event + if (allDay) { + if (timeElement) { + timeElement.css('display', ''); // show() was causing display=inline } - view.showOverlay(cell); - }else{ // on slots - resetElement(); + eventElement.draggable('option', 'grid', [colWidth, rowHeight]); + allDay = false; + } + }; + prevSlotDelta = 0; + matrix = new HoverMatrix(function(cell) { + eventElement.draggable('option', 'revert', !cell); + if (cell) { + if (!cell.row && options.allDayHeader) { // over full days + if (!allDay) { + // convert to temporary all-day event + allDay = true; + if (timeElement) { + timeElement.hide(); + } + eventElement.draggable('option', 'grid', null); + } + view.showOverlay(cell); + }else{ // on slots + resetElement(); + view.hideOverlay(); + } + }else{ view.hideOverlay(); } - }else{ - view.hideOverlay(); + }); + if (options.allDayHeader) { + matrix.row(head.find('td')); } - }); - if (options.allDayHeader) { - matrix.row(head.find('td')); - } - bg.find('td').each(function() { - matrix.col(this); - }); - matrix.row(body); - matrix.mouse(ev.pageX, ev.pageY); - view.hideEvents(event, eventElement); - }, - drag: function(ev, ui) { - slotDelta = Math.round((ui.position.top - origPosition.top) / rowHeight); - if (slotDelta != prevSlotDelta) { - if (timeElement && !allDay) { - // update time header - var minuteDelta = slotDelta*options.slotMinutes, - newStart = addMinutes(cloneDate(event.start), minuteDelta), - newEnd; - if (event.end) { - newEnd = addMinutes(cloneDate(event.end), minuteDelta); + bg.find('td').each(function() { + matrix.col(this); + }); + matrix.row(body); + matrix.mouse(ev.pageX, ev.pageY); + }, + drag: function(ev, ui) { + slotDelta = Math.round((ui.position.top - origPosition.top) / rowHeight); + if (slotDelta != prevSlotDelta) { + if (timeElement && !allDay) { + // update time header + var minuteDelta = slotDelta*options.slotMinutes, + newStart = addMinutes(cloneDate(event.start), minuteDelta), + newEnd; + if (event.end) { + newEnd = addMinutes(cloneDate(event.end), minuteDelta); + } + timeElement.text(formatDates(newStart, newEnd, view.option('timeFormat'))); } - timeElement.text(formatDates(newStart, newEnd, view.option('timeFormat'))); + prevSlotDelta = slotDelta; } - prevSlotDelta = slotDelta; - } - matrix.mouse(ev.pageX, ev.pageY); - }, - stop: function(ev, ui) { - view.hideOverlay(); - var cell = matrix.cell, - dayDelta = dis * ( - allDay ? // can't trust cell.colDelta when using slot grid - (cell ? cell.colDelta : 0) : - Math.floor((ui.position.left - origPosition.left) / colWidth) - ); - if (!cell || !slotDelta && !dayDelta) { - resetElement(); - if ($.browser.msie) { - eventElement - .css('filter', '') // clear IE opacity side-effects - .find('span.fc-event-bg').css('display', ''); // .show() made display=inline + matrix.mouse(ev.pageX, ev.pageY); + }, + stop: function(ev, ui) { + view.hideOverlay(); + view.trigger('eventDragStop', eventElement, event, ev, ui); + var cell = matrix.cell, + dayDelta = dis * ( + allDay ? // can't trust cell.colDelta when using slot grid + (cell ? cell.colDelta : 0) : + Math.floor((ui.position.left - origPosition.left) / colWidth) + ); + if (!cell || !slotDelta && !dayDelta) { + resetElement(); + if ($.browser.msie) { + eventElement + .css('filter', '') // clear IE opacity side-effects + .find('span.fc-event-bg').css('display', ''); // .show() made display=inline + } + eventElement.css(origPosition); // sometimes fast drags make event revert to wrong position + view.showEvents(event, eventElement); + }else{ + //TODO: eventElement.find('a').removeAttr('href'); // prevents safari from visiting the link + view.eventDrop( + this, event, dayDelta, + allDay ? 0 : slotDelta * options.slotMinutes, // minute delta + allDay, ev, ui + ); } - eventElement.css(origPosition); // sometimes fast drags make event revert to wrong position - view.showEvents(event, eventElement); - }else{ - view.eventDrop( - this, event, dayDelta, - allDay ? 0 : slotDelta * options.slotMinutes, // minute delta - allDay, ev, ui - ); } - } - }); - + }); + } } @@ -704,47 +747,51 @@ function Agenda(element, options, methods) { // for TIMESLOT events function resizableSlotEvent(event, eventElement, timeElement) { - var slotDelta, prevSlotDelta; - eventElement - .resizable({ - handles: 's', - grid: rowHeight, - start: function() { - slotDelta = prevSlotDelta = 0; - view.hideEvents(event, eventElement); - if ($.browser.msie && $.browser.version == '6.0') { - eventElement.css('overflow', 'hidden'); - } - eventElement.css('z-index', 9); - }, - resize: function(ev, ui) { - // don't rely on ui.size.height, doesn't take grid into account - slotDelta = Math.round((Math.max(rowHeight, eventElement.height()) - ui.originalSize.height) / rowHeight); - if (slotDelta != prevSlotDelta) { - if (timeElement) { - timeElement.text( - formatDates( - event.start, - (!slotDelta && !event.end) ? null : // no change, so don't display time range - addMinutes(view.eventEnd(event), options.slotMinutes*slotDelta), - view.option('timeFormat') - ) - ); + if (!options.disableResizing && eventElement.resizable) { + var slotDelta, prevSlotDelta; + eventElement + .resizable({ + handles: 's', + grid: rowHeight, + start: function(ev, ui) { + slotDelta = prevSlotDelta = 0; + view.hideEvents(event, eventElement); + if ($.browser.msie && $.browser.version == '6.0') { + eventElement.css('overflow', 'hidden'); + } + eventElement.css('z-index', 9); + view.trigger('eventResizeStart', this, event, ev, ui); + }, + resize: function(ev, ui) { + // don't rely on ui.size.height, doesn't take grid into account + slotDelta = Math.round((Math.max(rowHeight, eventElement.height()) - ui.originalSize.height) / rowHeight); + if (slotDelta != prevSlotDelta) { + if (timeElement) { + timeElement.text( + formatDates( + event.start, + (!slotDelta && !event.end) ? null : // no change, so don't display time range + addMinutes(view.eventEnd(event), options.slotMinutes*slotDelta), + view.option('timeFormat') + ) + ); + } + prevSlotDelta = slotDelta; + } + }, + stop: function(ev, ui) { + view.trigger('eventResizeStop', this, event, ev, ui); + if (slotDelta) { + view.eventResize(this, event, 0, options.slotMinutes*slotDelta, ev, ui); + }else{ + eventElement.css('z-index', 8); + view.showEvents(event, eventElement); + // BUG: if event was really short, need to put title back in span } - prevSlotDelta = slotDelta; } - }, - stop: function(ev, ui) { - if (slotDelta) { - view.eventResize(this, event, 0, options.slotMinutes*slotDelta, ev, ui); - }else{ - eventElement.css('z-index', 8); - view.showEvents(event, eventElement); - // BUG: if event was really short, need to put title back in span - } - } - }) - .find('div.ui-resizable-s').text('='); + }) + .find('div.ui-resizable-s').text('='); + } } diff --git a/src/css/agenda.css b/src/css/agenda.css index a7f0e83..310580b 100755 --- a/src/css/agenda.css +++ b/src/css/agenda.css @@ -1,33 +1,14 @@ -/*.fc-event, -.fc-event a, -.fc-agenda .fc-event-time { - color: #fff; - border-style: solid; - border-color: blue; - background-color: blue; - }*/ +/* Agenda Week View, Agenda Day View +------------------------------------------------------------------------*/ - -.fc .fc-axis { - width: 50px; - padding: 0 4px 0 0; - vertical-align: middle; - white-space: nowrap; - text-align: right; - font-weight: normal; - } - - - - .fc .fc-agenda th, .fc .fc-agenda td { border-width: 1px 0 0 1px; } -.fc-agenda-head tr.fc-all-day th { - height: 35px; +.fc .fc-agenda .fc-leftmost { + border-left: 0; } .fc-agenda tr.fc-first th, @@ -35,160 +16,68 @@ border-top: 0; } -.fc .fc-agenda .fc-leftmost { - border-left: 0; +.fc-agenda-head tr.fc-last th { + border-bottom-width: 1px; } - - - .fc .fc-agenda-head td, .fc .fc-agenda-body td { background: none; } -.fc .fc-agenda-body td div { - height: 20px; - } - - - - -.fc .fc-agenda-body tr.fc-minor th, -.fc .fc-agenda-body tr.fc-minor td { - border-top-style: dotted; +.fc-agenda-head th { + text-align: center; } +/* the time axis running down the left side */ + +.fc-agenda .fc-axis { + width: 50px; + padding: 0 4px; + vertical-align: middle; + white-space: nowrap; + text-align: right; + font-weight: normal; + } + +/* all-day event cells at top */ + +.fc-agenda-head tr.fc-all-day th { + height: 35px; + } + +.fc-agenda-head td { + padding-bottom: 10px; + } - .fc .fc-divider div { font-size: 1px; /* for IE6/7 */ height: 2px; } - - .fc .fc-divider .fc-state-default { - background: #eee; - } - - - -.fc-agenda-head tr.fc-last th { - border-bottom-width: 1px; - } - - - - -.fc-agenda .fc-day-content { - padding: 2px 2px 0; - } - -.fc-agenda-head .fc-day-content { - padding-bottom: 10px; + background: #eee; /* color for divider between all-day and time-slot events */ } +/* body styles */ - - - -/* header styles */ -/* -.fc .fc-agenda-head th.fc-first { - border-left: 0; +.fc .fc-agenda-body td div { + height: 20px; /* slot height */ } -.fc .fc-agenda-head th, -.fc .fc-agenda-head td { - border-width: 1px 0 0 1px; - } - -.fc-agenda-head tr.fc-first th { - border-width: 0 0 0 1px; - } - -.fc-agenda-head tr.fc-last th, -.fc-agenda-head tr.fc-last td { - border-bottom-width: 2px; - } - -.fc-agenda-head tr.fc-last th { - #border-width: 1px 0 1px 1px; - background-image: none; - } - -.fc-agenda-head tr.fc-last th.fc-first { - #border-width: 0 2px 1px 0; - } - -.fc-agenda-head tr.fc-last th.fc-last { - #border-width: 0 0 0 3px; - } - -.fc .fc-agenda-head td { - #border-width: 3px 0 3px 1px; - background: none; - } - -.fc-agenda-body { - #width: 100%; - overflow: auto; - } -*/ - - - -/* -.fc .fc-agenda-body th { - border-width: 1px 0 0 0; - background-image: none; - text-align: right; - font-weight: normal; - vertical-align: middle; - width: 48px; - height: 22px; - padding-right: 2px; - } - -.fc .fc-agenda-body td { - border-width: 1px 0 0 1px; - background: none; - } - .fc .fc-agenda-body tr.fc-minor th, .fc .fc-agenda-body tr.fc-minor td { border-top-style: dotted; } -.fc .fc-agenda-body tr.fc-first th, -.fc .fc-agenda-body tr.fc-first td { - border-top: 0; - } - - - -.fc .fc-agenda-bg td { - border-style: double; - border-width: 0 0 0 3px; - } - -.fc .fc-agenda-bg td.fc-not-today { - background: none; - } - - - .fc-agenda .fc-day-content { - padding: 2px 1px 14px; + padding: 2px 2px 0; /* distance between events and day edges */ } -*/ - - - - -/* vertical events */ + + +/* Vertical Events +------------------------------------------------------------------------*/ .fc-event-vert { border-width: 0 1px; @@ -198,6 +87,8 @@ border-width: 0; } +/* for fake rounded corners */ + .fc-content .fc-corner-top { margin-top: 1px; } @@ -216,6 +107,8 @@ border-bottom-width: 1px; } +/* event content */ + .fc-event-vert span { display: block; position: relative; @@ -226,15 +119,15 @@ white-space: nowrap; _white-space: normal; overflow: hidden; - font-size: 10px; border: 0; + font-size: 10px; } .fc-event-vert span.fc-event-title { line-height: 13px; } -.fc-event-vert span.fc-event-bg { +.fc-event-vert span.fc-event-bg { /* makes the event lighter w/ a semi-transparent overlay */ position: absolute; z-index: 1; top: 0; @@ -243,14 +136,20 @@ height: 100%; background: #fff; opacity: .3; - filter: alpha(opacity=30); + filter: alpha(opacity=30); /* for IE */ } +/* resizable */ + .fc-event-vert .ui-resizable-s { + bottom: 0 !important; /* importants override pre jquery ui 1.7 styles */ + width: 100% !important; + height: 8px !important; + line-height: 8px !important; + font-size: 11px !important; font-family: monospace; - height: 8px; - font-size: 11px; - line-height: 8px; - bottom: 0; text-align: center; - } \ No newline at end of file + cursor: s-resize; + } + + \ No newline at end of file diff --git a/src/css/main.css b/src/css/main.css index 2b434fa..8807040 100755 --- a/src/css/main.css +++ b/src/css/main.css @@ -281,7 +281,7 @@ table.fc-header { display: block; position: absolute; z-index: 99999; - border: 0; /* important overrides pre jquery ui 1.7 styles */ + border: 0 !important; /* important overrides pre jquery ui 1.7 styles */ background: url(data:image/gif;base64,AAAA) !important; /* hover fix for IE */ } diff --git a/src/grid.js b/src/grid.js index 3df750b..009edc8 100755 --- a/src/grid.js +++ b/src/grid.js @@ -241,7 +241,7 @@ function Grid(element, options, methods) { } - updateSize(); + updateSize(); // BUG: quirky widths with weekMode:variable fetchEvents(renderEvents); }; @@ -349,7 +349,7 @@ function Grid(element, options, methods) { levelHeight, k, seg, event, - eventClasses, + className, startElm, endElm, left, right, eventElement, eventAnchor, @@ -376,17 +376,7 @@ function Grid(element, options, methods) { for (k=0; k") + eventElement = $("
") .append(eventAnchor = $("") .append(event.allDay || !seg.isStart ? null : $("") @@ -443,7 +433,7 @@ function Grid(element, options, methods) { eventElement.css('left', left + rtlLeftDiff); } } - eventElementHandlers(event, eventElement); + view.eventElementHandlers(event, eventElement); if (event.editable || event.editable == undefined && options.editable) { draggableEvent(event, eventElement); if (seg.isEnd) { @@ -461,23 +451,6 @@ function Grid(element, options, methods) { } } - function eventElementHandlers(event, eventElement) { - eventElement - .click(function(ev) { - if (!eventElement.hasClass('ui-draggable-dragging')) { - return view.trigger('eventClick', this, event, ev); - } - }) - .hover( - function(ev) { - view.trigger('eventMouseover', this, event, ev); - }, - function(ev) { - view.trigger('eventMouseout', this, event, ev); - } - ); - } - /* Event Dragging @@ -493,6 +466,8 @@ function Grid(element, options, methods) { opacity: view.option('dragOpacity'), revertDuration: options.dragRevertDuration, start: function(ev, ui) { + view.hideEvents(event, eventElement); + view.trigger('eventDragStart', eventElement, event, ev, ui); matrix = new HoverMatrix(function(cell) { eventElement.draggable('option', 'revert', !cell || !cell.rowDelta && !cell.colDelta); if (cell) { @@ -511,8 +486,6 @@ function Grid(element, options, methods) { tds.each(function() { matrix.col(this); }); - view.hideEvents(event, eventElement); - view.trigger('eventDragStart', eventElement, event, ev, ui); matrix.mouse(ev.pageX, ev.pageY); }, drag: function(ev) { diff --git a/src/main.js b/src/main.js index 896d788..f8b5441 100755 --- a/src/main.js +++ b/src/main.js @@ -12,9 +12,9 @@ var defaults = { defaultView: 'month', aspectRatio: 1.35, header: { - left: 'title', - center: '', - right: 'today prev,next' + left: 'prev,next today', + center: 'title', + right: 'month,agendaWeek,agendaDay' }, // editing @@ -72,9 +72,9 @@ var defaults = { // right-to-left defaults var rtlDefaults = { header: { - left: 'next,prev today', - center: '', - right: 'title' + left: 'agendaDay,agendaWeek,month', + center: 'title', + right: 'today next,prev' }, buttonText: { prev: ' ► ', @@ -542,8 +542,7 @@ $.fn.fullCalendar = function(options) { } var prevButton; $.each(this.split(','), function(j) { - var buttonName = this, - buttonNameShort = this.replace(/^(basic|agenda)/, '').toLowerCase(); + var buttonName = this; if (buttonName == 'title') { tr.append("

"); if (prevButton) { @@ -552,8 +551,8 @@ $.fn.fullCalendar = function(options) { prevButton = null; }else{ var buttonClick; - if (publicMethods[buttonNameShort]) { - buttonClick = publicMethods[buttonNameShort]; + if (publicMethods[buttonName]) { + buttonClick = publicMethods[buttonName]; } else if (views[buttonName]) { buttonClick = function() { changeView(buttonName) }; @@ -563,8 +562,8 @@ $.fn.fullCalendar = function(options) { prevButton.addClass(tm + '-no-right'); } var button, - icon = options.theme ? options.buttonIcons[buttonNameShort] : null, - text = options.buttonText[buttonNameShort]; + icon = options.theme ? viewOption(options, 'buttonIcons', buttonName) : null, + text = viewOption(options, 'buttonText', buttonName); if (icon) { button = $(""); @@ -575,6 +574,7 @@ $.fn.fullCalendar = function(options) { } if (button) { button + .click(buttonClick) .mousedown(function() { button.addClass(tm + '-state-down'); }) @@ -591,14 +591,6 @@ $.fn.fullCalendar = function(options) { } ) .appendTo($("").appendTo(tr)); - if (publicMethods[buttonNameShort]) { - button.click(publicMethods[buttonNameShort]); - } - else if (views[buttonName]) { - button.click(function() { - changeView(buttonName); - }); - } if (prevButton) { prevButton.addClass(tm + '-no-right'); }else{ @@ -685,6 +677,29 @@ $.fn.fullCalendar = function(options) { +// TODO: rename + +function viewOption(options, property, viewName) { + var v = options[property]; + if (typeof v == 'object') { + if (v[viewName] != undefined) { + return v[viewName]; + } + var parts = viewName.split(/(?=[A-Z])/), + i=parts.length-1, res; + for (; i>=0; i--) { + res = v[parts[i].toLowerCase()]; + if (res != undefined) { + return res; + } + } + return v['']; + } + return v; +} + + + /* Important Event Utilities -----------------------------------------------------------------------------*/ @@ -707,5 +722,12 @@ function normalizeEvent(event, options) { if (event.allDay == undefined) { event.allDay = options.allDayDefault; } + if (event.className) { + if (typeof event.className == 'string') { + event.className = event.className.split(/\s+/); + } + }else{ + event.className = []; + } } diff --git a/src/view.js b/src/view.js index 7b79070..dc38f83 100755 --- a/src/view.js +++ b/src/view.js @@ -212,7 +212,8 @@ var viewMethods = { handles: view.options.isRTL ? 'w' : 'e', grid: colWidth, minWidth: colWidth/2, // need this or else IE throws errors when too small - containment: view.element, + containment: view.element.parent().parent(), // the main element... + // ... a fix. wouldn't allow extending to last column in agenda views (jq ui bug?) start: function(ev, ui) { eventElement.css('z-index', 9); view.hideEvents(event, eventElement); @@ -235,22 +236,33 @@ var viewMethods = { + // attaches eventClick, eventMouseover, eventMouseout + + eventElementHandlers: function(event, eventElement) { + var view = this; + eventElement + .click(function(ev) { + if (!eventElement.hasClass('ui-draggable-dragging') && + !eventElement.hasClass('ui-resizable-resizing')) { + return view.trigger('eventClick', this, event, ev); + } + }) + .hover( + function(ev) { + view.trigger('eventMouseover', this, event, ev); + }, + function(ev) { + view.trigger('eventMouseout', this, event, ev); + } + ); + }, + + + // get a property from the 'options' object, using smart view naming - option: function(name) { - var v = this.options[name]; - if (typeof v == 'object') { - var parts = this.name.split(/(?=[A-Z])/), - i=parts.length-1, res; - for (; i>=0; i--) { - res = v[parts[i].toLowerCase()]; - if (res != undefined) { - return res; - } - } - return v['']; - } - return v; + option: function(name, viewName) { + return viewOption(this.options, name, this.name || viewName); }, @@ -331,7 +343,6 @@ function stackSegs(segs) { }else{ levels[j] = [seg]; } - //seg.after = 0; } return levels; } diff --git a/tests/basic.html b/tests/basic.html index 947997a..39d59d4 100755 --- a/tests/basic.html +++ b/tests/basic.html @@ -12,20 +12,10 @@ var m = d.getMonth(); $('#calendar').fullCalendar({ - slotMinutes: 30, - //allDayHeader: false, - //weekMode: 'variable', - //theme: true, - //firstDay: 1, - //isRTL: true, - editable: true, - //dragOpacity: .5, - defaultView: 'agendaWeek', header: { - left: 'prev,next today', - center: 'title', - right: 'month,agendaWeek,agendaDay' + right: 'month,agendaWeek,basicWeek,agendaDay,basicDay' }, + editable: true, events: [ { id: 1, @@ -50,7 +40,8 @@ id: 345, title: "Hey Hey", start: new Date(y, m, 9, 4, 0), - allDay: false + allDay: false, + className: 'adam shaw' }, { id: 3, @@ -66,10 +57,7 @@ url: "http://facebook.com/", allDay: false } - ], - dayClick: function(date, allDay) { - alert(date + ' allDay:' + allDay); - } + ] }); }); @@ -85,7 +73,7 @@ } #calendar { - width: 80%; + width: 900px; margin: 0 auto; } diff --git a/tests/gcal.html b/tests/gcal.html index 2515cd6..f968fc0 100755 --- a/tests/gcal.html +++ b/tests/gcal.html @@ -10,6 +10,9 @@ $(document).ready(function() { $('#calendar').fullCalendar({ + header: { + right: 'month,agendaWeek,basicWeek,agendaDay,basicDay' + }, editable: true, eventSources: [ $.fullCalendar.gcalFeed( diff --git a/tests/locale.html b/tests/locale.html index e2cb462..630c485 100644 --- a/tests/locale.html +++ b/tests/locale.html @@ -12,7 +12,7 @@ $('#calendar').fullCalendar({ header: { - center: 'month,basicWeek,basicDay' + left: 'month,agendaWeek,basicWeek,agendaDay,basicDay' }, editable: true, diff --git a/tests/methods.html b/tests/methods.html index 98e9773..5ae89ea 100644 --- a/tests/methods.html +++ b/tests/methods.html @@ -15,9 +15,7 @@ cal = $('#calendar').fullCalendar({ editable: true, header: { - left: 'prev,next today', - center: 'title', - right: 'month,basicWeek,basicDay' + right: 'month,agendaWeek,basicWeek,agendaDay,basicDay' }, loading: function(bool) { if (bool) { diff --git a/tests/options.html b/tests/options.html index 880fde8..bfce9cb 100644 --- a/tests/options.html +++ b/tests/options.html @@ -23,7 +23,7 @@ header: { left: 'title', - center: 'prev,month,basicWeek,basicDay,next', + center: 'prev,month,agendaWeek,basicWeek,agendaDay,basicDay,next', right: 'today' }, diff --git a/tests/sources.html b/tests/sources.html index d600a14..ab482c3 100644 --- a/tests/sources.html +++ b/tests/sources.html @@ -86,9 +86,7 @@ cal = $('#calendar').fullCalendar({ editable: true, header: { - left: 'prev,next today', - center: 'title', - right: 'month,basicWeek,basicDay' + right: 'month,agendaWeek,basicWeek,agendaDay,basicDay' }, //events: staticEvents, eventSources: [ diff --git a/tests/theming.html b/tests/theming.html index 64d2010..d9046d4 100755 --- a/tests/theming.html +++ b/tests/theming.html @@ -18,7 +18,7 @@ //isRTL: true, header: { - center: 'month,basicWeek,basicDay' + right: 'month,agendaWeek,basicWeek,agendaDay,basicDay' }, buttonIcons: { diff --git a/tests/triggers.html b/tests/triggers.html index 62e4af2..449c0f4 100755 --- a/tests/triggers.html +++ b/tests/triggers.html @@ -11,9 +11,7 @@ $(document).ready(function() { $('#calendar').fullCalendar({ header: { - left: 'prev,next today', - center: 'title', - right: 'month,basicWeek,basicDay' + right: 'month,agendaWeek,basicWeek,agendaDay,basicDay' }, editable: true, weekMode: 'variable', @@ -31,8 +29,8 @@ //console.log(this); }, - dayClick: function(dayDate, view) { - console.log('dayClick - ' + dayDate + ' - ' + view.title); + dayClick: function(dayDate, allDay, ev, view) { + console.log('dayClick - ' + dayDate + ', allDay:' + allDay + ' - ' + view.title); //console.log(this); },