diff options
Diffstat (limited to 'library/fullcalendar/fullcalendar.js')
-rw-r--r-- | library/fullcalendar/fullcalendar.js | 665 |
1 files changed, 409 insertions, 256 deletions
diff --git a/library/fullcalendar/fullcalendar.js b/library/fullcalendar/fullcalendar.js index 779a313c7..648938fee 100644 --- a/library/fullcalendar/fullcalendar.js +++ b/library/fullcalendar/fullcalendar.js @@ -1,23 +1,20 @@ -/** - * @preserve - * FullCalendar v1.5.3 - * http://arshaw.com/fullcalendar/ - * +/*! + * FullCalendar v1.6.0 + * Docs & License: http://arshaw.com/fullcalendar/ + * (c) 2013 Adam Shaw + */ + +/* * Use fullcalendar.css for basic styling. * For event drag & drop, requires jQuery UI draggable. * For event resizing, requires jQuery UI resizable. - * - * Copyright (c) 2011 Adam Shaw - * Dual licensed under the MIT and GPL licenses, located in - * MIT-LICENSE.txt and GPL-LICENSE.txt respectively. - * - * Date: Mon Feb 6 22:40:40 2012 -0800 - * */ (function($, undefined) { +;; + var defaults = { // display @@ -29,6 +26,9 @@ var defaults = { right: 'today prev,next' }, weekends: true, + weekNumbers: false, + weekNumberCalculation: 'iso', + weekNumberTitle: 'W', // editing //editable: false, @@ -66,10 +66,10 @@ var defaults = { dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'], dayNamesShort: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'], buttonText: { - prev: ' ◄ ', - next: ' ► ', - prevYear: ' << ', - nextYear: ' >> ', + prev: "<span class='fc-text-arrow'>‹</span>", + next: "<span class='fc-text-arrow'>›</span>", + prevYear: "<span class='fc-text-arrow'>«</span>", + nextYear: "<span class='fc-text-arrow'>»</span>", today: 'today', month: 'month', week: 'week', @@ -98,10 +98,10 @@ var rtlDefaults = { right: 'title' }, buttonText: { - prev: ' ► ', - next: ' ◄ ', - prevYear: ' >> ', - nextYear: ' << ' + prev: "<span class='fc-text-arrow'>›</span>", + next: "<span class='fc-text-arrow'>‹</span>", + prevYear: "<span class='fc-text-arrow'>»</span>", + nextYear: "<span class='fc-text-arrow'>«</span>" }, buttonIcons: { prev: 'circle-triangle-e', @@ -111,7 +111,9 @@ var rtlDefaults = { -var fc = $.fullCalendar = { version: "1.5.3" }; +;; + +var fc = $.fullCalendar = { version: "1.6.0" }; var fcViews = fc.views = {}; @@ -177,6 +179,8 @@ function setDefaults(d) { +;; + function Calendar(element, options, eventSources) { var t = this; @@ -258,6 +262,9 @@ function Calendar(element, options, eventSources) { if (options.isRTL) { element.addClass('fc-rtl'); } + else { + element.addClass('fc-ltr'); + } if (options.theme) { element.addClass('ui-widget'); } @@ -674,6 +681,8 @@ function Calendar(element, options, eventSources) { } +;; + function Header(calendar, options) { var t = this; @@ -747,54 +756,47 @@ function Header(calendar, options) { var text = smartProperty(options.buttonText, buttonName); // why are we using smartProperty here? var button = $( "<span class='fc-button fc-button-" + buttonName + " " + tm + "-state-default'>" + - "<span class='fc-button-inner'>" + - "<span class='fc-button-content'>" + - (icon ? - "<span class='fc-icon-wrap'>" + - "<span class='ui-icon ui-icon-" + icon + "'/>" + - "</span>" : - text - ) + - "</span>" + - "<span class='fc-button-effect'><span></span></span>" + - "</span>" + + (icon ? + "<span class='fc-icon-wrap'>" + + "<span class='ui-icon ui-icon-" + icon + "'/>" + + "</span>" : + text + ) + "</span>" - ); - if (button) { - button - .click(function() { - if (!button.hasClass(tm + '-state-disabled')) { - buttonClick(); - } - }) - .mousedown(function() { + ) + .click(function() { + if (!button.hasClass(tm + '-state-disabled')) { + buttonClick(); + } + }) + .mousedown(function() { + button + .not('.' + tm + '-state-active') + .not('.' + tm + '-state-disabled') + .addClass(tm + '-state-down'); + }) + .mouseup(function() { + button.removeClass(tm + '-state-down'); + }) + .hover( + function() { button .not('.' + tm + '-state-active') .not('.' + tm + '-state-disabled') - .addClass(tm + '-state-down'); - }) - .mouseup(function() { - button.removeClass(tm + '-state-down'); - }) - .hover( - function() { - button - .not('.' + tm + '-state-active') - .not('.' + tm + '-state-disabled') - .addClass(tm + '-state-hover'); - }, - function() { - button - .removeClass(tm + '-state-hover') - .removeClass(tm + '-state-down'); - } - ) - .appendTo(e); - if (!prevButton) { - button.addClass(tm + '-corner-left'); - } - prevButton = button; + .addClass(tm + '-state-hover'); + }, + function() { + button + .removeClass(tm + '-state-hover') + .removeClass(tm + '-state-down'); + } + ) + .appendTo(e); + disableTextSelection(button); + if (!prevButton) { + button.addClass(tm + '-corner-left'); } + prevButton = button; } } }); @@ -839,6 +841,8 @@ function Header(calendar, options) { } +;; + fc.sourceNormalizers = []; fc.sourceFetchers = []; @@ -914,6 +918,16 @@ function EventManager(options, _sources) { _fetchEventSource(source, function(events) { if (fetchID == currentFetchID) { if (events) { + + if (options.eventDataTransform) { + events = $.map(events, options.eventDataTransform); + } + if (source.eventDataTransform) { + events = $.map(events, source.eventDataTransform); + } + // TODO: this technique is not ideal for static array event sources. + // For arrays, we'll want to process all events right in the beginning, then never again. + for (var i=0; i<events.length; i++) { events[i].source = source; normalizeEvent(events[i]); @@ -1227,6 +1241,8 @@ function EventManager(options, _sources) { } +;; + fc.addDays = addDays; fc.cloneDate = cloneDate; @@ -1581,10 +1597,38 @@ var dateFormatters = { return 'th'; } return ['st', 'nd', 'rd'][date%10-1] || 'th'; + }, + w : function(d, o) { // local + return o.weekNumberCalculation(d); + }, + W : function(d) { // ISO + return iso8601Week(d); } }; +fc.dateFormatters = dateFormatters; + + +/* thanks jQuery UI (https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js) + * + * Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. + * @param date Date - the date to get the week for + * @return number - the number of the week within the year that contains this date + */ +function iso8601Week(date) { + var time; + var checkDate = new Date(date.getTime()); + + // Find Thursday of this week starting on Monday + checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); + + time = checkDate.getTime(); + checkDate.setMonth(0); // Compare with Jan 1 + checkDate.setDate(1); + return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; +} +;; fc.applyAll = applyAll; @@ -1658,7 +1702,7 @@ function sliceSegs(events, visEventEnds, start, end) { msLength: segEnd - segStart }); } - } + } return segs.sort(segCmp); } @@ -1742,29 +1786,26 @@ function setOuterHeight(element, height, includeMargins) { } -// TODO: curCSS has been deprecated (jQuery 1.4.3 - 10/16/2010) - - function hsides(element, includeMargins) { return hpadding(element) + hborders(element) + (includeMargins ? hmargins(element) : 0); } function hpadding(element) { - return (parseFloat($.curCSS(element[0], 'paddingLeft', true)) || 0) + - (parseFloat($.curCSS(element[0], 'paddingRight', true)) || 0); + return (parseFloat($.css(element[0], 'paddingLeft', true)) || 0) + + (parseFloat($.css(element[0], 'paddingRight', true)) || 0); } function hmargins(element) { - return (parseFloat($.curCSS(element[0], 'marginLeft', true)) || 0) + - (parseFloat($.curCSS(element[0], 'marginRight', true)) || 0); + return (parseFloat($.css(element[0], 'marginLeft', true)) || 0) + + (parseFloat($.css(element[0], 'marginRight', true)) || 0); } function hborders(element) { - return (parseFloat($.curCSS(element[0], 'borderLeftWidth', true)) || 0) + - (parseFloat($.curCSS(element[0], 'borderRightWidth', true)) || 0); + return (parseFloat($.css(element[0], 'borderLeftWidth', true)) || 0) + + (parseFloat($.css(element[0], 'borderRightWidth', true)) || 0); } @@ -1774,20 +1815,20 @@ function vsides(element, includeMargins) { function vpadding(element) { - return (parseFloat($.curCSS(element[0], 'paddingTop', true)) || 0) + - (parseFloat($.curCSS(element[0], 'paddingBottom', true)) || 0); + return (parseFloat($.css(element[0], 'paddingTop', true)) || 0) + + (parseFloat($.css(element[0], 'paddingBottom', true)) || 0); } function vmargins(element) { - return (parseFloat($.curCSS(element[0], 'marginTop', true)) || 0) + - (parseFloat($.curCSS(element[0], 'marginBottom', true)) || 0); + return (parseFloat($.css(element[0], 'marginTop', true)) || 0) + + (parseFloat($.css(element[0], 'marginBottom', true)) || 0); } function vborders(element) { - return (parseFloat($.curCSS(element[0], 'borderTopWidth', true)) || 0) + - (parseFloat($.curCSS(element[0], 'borderBottomWidth', true)) || 0); + return (parseFloat($.css(element[0], 'borderTopWidth', true)) || 0) + + (parseFloat($.css(element[0], 'borderBottomWidth', true)) || 0); } @@ -1956,6 +1997,7 @@ function firstDefined() { } +;; fcViews.month = MonthView; @@ -2003,12 +2045,14 @@ function MonthView(element, calendar) { t.end = end; t.visStart = visStart; t.visEnd = visEnd; - renderBasic(6, rowCnt, nwe ? 5 : 7, true); + renderBasic(rowCnt, nwe ? 5 : 7, true); } } +;; + fcViews.basicWeek = BasicWeekView; function BasicWeekView(element, calendar) { @@ -2049,12 +2093,14 @@ function BasicWeekView(element, calendar) { t.end = end; t.visStart = visStart; t.visEnd = visEnd; - renderBasic(1, 1, weekends ? 7 : 5, false); + renderBasic(1, weekends ? 7 : 5, false); } } +;; + fcViews.basicDay = BasicDayView; //TODO: when calendar's date starts out on a weekend, shouldn't happen @@ -2086,12 +2132,14 @@ function BasicDayView(element, calendar) { t.title = formatDate(date, opt('titleFormat')); t.start = t.visStart = cloneDate(date, true); t.end = t.visEnd = addDays(cloneDate(t.start), 1); - renderBasic(1, 1, 1, false); + renderBasic(1, 1, false); } } +;; + setDefaults({ weekMode: 'fixed' }); @@ -2144,6 +2192,7 @@ function BasicView(element, calendar, viewName) { // locals + var table; var head; var headCells; var body; @@ -2156,6 +2205,7 @@ function BasicView(element, calendar, viewName) { var viewWidth; var viewHeight; var colWidth; + var weekNumberWidth; var rowCnt, colCnt; var coordinateGrid; @@ -2164,9 +2214,12 @@ function BasicView(element, calendar, viewName) { var rtl, dis, dit; var firstDay; - var nwe; + var nwe; // no weekends? a 0 or 1 for easy computations var tm; var colFormat; + var showWeekNumbers; + var weekNumberTitle; + var weekNumberFormat; @@ -2177,17 +2230,17 @@ function BasicView(element, calendar, viewName) { disableTextSelection(element.addClass('fc-grid')); - function renderBasic(maxr, r, c, showNumbers) { + function renderBasic(r, c, showNumbers) { rowCnt = r; colCnt = c; updateOptions(); var firstTime = !body; if (firstTime) { - buildSkeleton(maxr, showNumbers); + buildEventContainer(); }else{ clearEvents(); } - updateCells(firstTime); + buildTable(showNumbers); } @@ -2205,124 +2258,141 @@ function BasicView(element, calendar, viewName) { nwe = opt('weekends') ? 0 : 1; tm = opt('theme') ? 'ui' : 'fc'; colFormat = opt('columnFormat'); + + // week # options. (TODO: bad, logic also in other views) + showWeekNumbers = opt('weekNumbers'); + weekNumberTitle = opt('weekNumberTitle'); + if (opt('weekNumberCalculation') != 'iso') { + weekNumberFormat = "w"; + } + else { + weekNumberFormat = "W"; + } } - function buildSkeleton(maxRowCnt, showNumbers) { - var s; + function buildEventContainer() { + daySegmentContainer = + $("<div style='position:absolute;z-index:8;top:0;left:0'/>") + .appendTo(element); + } + + + + function buildTable(showNumbers) { + var html = ''; + var i, j; var headerClass = tm + "-widget-header"; var contentClass = tm + "-widget-content"; - var i, j; - var table; - - s = - "<table class='fc-border-separate' style='width:100%' cellspacing='0'>" + - "<thead>" + - "<tr>"; + var month = t.start.getMonth(); + var today = clearTime(new Date()); + var cellDate; // not to be confused with local function. TODO: better names + var cellClasses; + var cell; + + html += "<table class='fc-border-separate' style='width:100%' cellspacing='0'>" + + "<thead>" + + "<tr>"; + + if (showWeekNumbers) { + html += "<th class='fc-week-number " + headerClass + "'/>"; + } + for (i=0; i<colCnt; i++) { - s += - "<th class='fc- " + headerClass + "'/>"; // need fc- for setDayID + html += "<th class='fc-day-header fc-" + dayIDs[i] + " " + headerClass + "'/>"; } - s += - "</tr>" + - "</thead>" + - "<tbody>"; - for (i=0; i<maxRowCnt; i++) { - s += - "<tr class='fc-week" + i + "'>"; + + html += "</tr>" + + "</thead>" + + "<tbody>"; + + for (i=0; i<rowCnt; i++) { + html += "<tr class='fc-week'>"; + + if (showWeekNumbers) { + html += "<td class='fc-week-number " + contentClass + "'>" + + "<div/>" + + "</td>"; + } + for (j=0; j<colCnt; j++) { - s += - "<td class='fc- " + contentClass + " fc-day" + (i*colCnt+j) + "'>" + // need fc- for setDayID - "<div>" + - (showNumbers ? - "<div class='fc-day-number'/>" : - '' - ) + - "<div class='fc-day-content'>" + - "<div style='position:relative'> </div>" + - "</div>" + - "</div>" + - "</td>"; + cellDate = _cellDate(i, j); // a little confusing. cellDate is local variable. _cellDate is private function + + cellClasses = [ + 'fc-day', + 'fc-' + dayIDs[cellDate.getDay()], + contentClass + ]; + if (cellDate.getMonth() != month) { + cellClasses.push('fc-other-month'); + } + if (+cellDate == +today) { + cellClasses.push('fc-today'); + cellClasses.push(tm + '-state-highlight'); + } + + html += "<td" + + " class='" + cellClasses.join(' ') + "'" + + " data-date='" + formatDate(cellDate, 'yyyy-MM-dd') + "'" + + ">" + + "<div>"; + if (showNumbers) { + html += "<div class='fc-day-number'>" + cellDate.getDate() + "</div>"; + } + html += "<div class='fc-day-content'>" + + "<div style='position:relative'> </div>" + + "</div>" + + "</div>" + + "</td>"; } - s += - "</tr>"; + + html += "</tr>"; } - s += - "</tbody>" + - "</table>"; - table = $(s).appendTo(element); - + html += "</tbody>" + + "</table>"; + + lockHeight(); // the unlock happens later, in setHeight()... + if (table) { + table.remove(); + } + table = $(html).appendTo(element); + head = table.find('thead'); - headCells = head.find('th'); + headCells = head.find('.fc-day-header'); 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'); + bodyCells = body.find('.fc-day'); + bodyFirstCells = bodyRows.find('td:first-child'); + bodyCellTopInners = bodyRows.eq(0).find('.fc-day-content > div'); 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 - - dayBind(bodyCells); - - daySegmentContainer = - $("<div style='position:absolute;z-index:8;top:0;left:0'/>") - .appendTo(element); - } + bodyRows.eq(0).addClass('fc-first'); + bodyRows.filter(':last').addClass('fc-last'); - - - function updateCells(firstTime) { - var dowDirty = firstTime || rowCnt == 1; // could the cells' day-of-weeks need updating? - var month = t.start.getMonth(); - var today = clearTime(new Date()); - var cell; - var date; - var row; - - if (dowDirty) { - headCells.each(function(i, _cell) { - cell = $(_cell); - date = indexDate(i); - cell.html(formatDate(date, colFormat)); - setDayID(cell, date); + if (showWeekNumbers) { + head.find('.fc-week-number').text(weekNumberTitle); + } + + headCells.each(function(i, _cell) { + var date = indexDate(i); + $(_cell).text(formatDate(date, colFormat)); + }); + + if (showWeekNumbers) { + body.find('.fc-week-number > div').each(function(i, _cell) { + var weekStart = _cellDate(i, 0); + $(_cell).text(formatDate(weekStart, weekNumberFormat)); }); } 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'); - } - if (+date == +today) { - cell.addClass(tm + '-state-highlight fc-today'); - }else{ - cell.removeClass(tm + '-state-highlight fc-today'); - } - cell.find('div.fc-day-number').text(date.getDate()); - if (dowDirty) { - setDayID(cell, date); - } - }); - - bodyRows.each(function(i, _row) { - row = $(_row); - if (i < rowCnt) { - row.show(); - if (i == rowCnt-1) { - row.addClass('fc-last'); - }else{ - row.removeClass('fc-last'); - } - }else{ - row.hide(); - } + var date = indexDate(i); + trigger('dayRender', t, date, $(_cell)); }); + + dayBind(bodyCells); } @@ -2352,13 +2422,20 @@ function BasicView(element, calendar, viewName) { } }); + unlockHeight(); } function setWidth(width) { viewWidth = width; colContentPositions.clear(); - colWidth = Math.floor(viewWidth / colCnt); + + weekNumberWidth = 0; + if (showWeekNumbers) { + weekNumberWidth = head.find('th.fc-week-number').outerWidth(); + } + + colWidth = Math.floor((viewWidth - weekNumberWidth) / colCnt); setOuterWidth(headCells.slice(0, -1), colWidth); } @@ -2376,8 +2453,7 @@ function BasicView(element, calendar, viewName) { function dayClick(ev) { if (!opt('selectable')) { // if selectable, SelectionManager will worry about dayClick - var index = parseInt(this.className.match(/fc\-day(\d+)/)[1]); // TODO: maybe use .data - var date = indexDate(index); + var date = parseISO8601($(this).data('date')); trigger('dayClick', this, date, true, ev); } } @@ -2568,15 +2644,34 @@ function BasicView(element, calendar, viewName) { function allDayBounds(i) { + var left = 0; + if (showWeekNumbers) { + left += weekNumberWidth; + } return { - left: 0, + left: left, right: viewWidth }; } - + + + + // makes sure height doesn't collapse while we destroy/render new cells + // (this causes a bad end-user scrollbar jump) + // TODO: generalize this for all view rendering. (also in Calendar.js) + + function lockHeight() { + setMinHeight(element, element.height()); + } + + function unlockHeight() { + setMinHeight(element, 1); + } } +;; + function BasicEventRenderer() { var t = this; @@ -2619,6 +2714,7 @@ function BasicEventRenderer() { function renderEvents(events, modifiedEventId) { reportEvents(events); renderDaySegs(compileSegs(events), modifiedEventId); + trigger('eventAfterAllRender'); } @@ -2718,6 +2814,8 @@ function BasicEventRenderer() { } +;; + fcViews.agendaWeek = AgendaWeekView; function AgendaWeekView(element, calendar) { @@ -2764,6 +2862,8 @@ function AgendaWeekView(element, calendar) { } +;; + fcViews.agendaDay = AgendaDayView; function AgendaDayView(element, calendar) { @@ -2800,6 +2900,8 @@ function AgendaDayView(element, calendar) { } +;; + setDefaults({ allDaySlot: true, allDayText: 'all-day', @@ -2851,7 +2953,8 @@ function AgendaView(element, calendar, viewName) { t.getRowCnt = function() { return 1 }; t.getColCnt = function() { return colCnt }; t.getColWidth = function() { return colWidth }; - t.getSlotHeight = function() { return slotHeight }; + t.getSnapHeight = function() { return snapHeight }; + t.getSnapMinutes = function() { return snapMinutes }; t.defaultSelectionEnd = defaultSelectionEnd; t.renderDayOverlay = renderDayOverlay; t.renderSelection = renderSelection; @@ -2907,7 +3010,10 @@ function AgendaView(element, calendar, viewName) { var colWidth; var gutterWidth; var slotHeight; // TODO: what if slotHeight changes? (see issue 650) - var savedScrollTop; + + var snapMinutes; + var snapRatio; // ratio of number of "selection" slots to normal slots. (ex: 1, 2, 4) + var snapHeight; // holds the pixel hight of a "selection" slot var colCnt; var slotCnt; @@ -2915,6 +3021,7 @@ function AgendaView(element, calendar, viewName) { var hoverListener; var colContentPositions; var slotTopCache = {}; + var savedScrollTop; var tm; var firstDay; @@ -2922,6 +3029,9 @@ function AgendaView(element, calendar, viewName) { var rtl, dis, dit; // day index sign / translate var minMinute, maxMinute; var colFormat; + var showWeekNumbers; + var weekNumberTitle; + var weekNumberFormat; @@ -2959,6 +3069,18 @@ function AgendaView(element, calendar, viewName) { minMinute = parseTime(opt('minTime')); maxMinute = parseTime(opt('maxTime')); colFormat = opt('columnFormat'); + + // week # options. (TODO: bad, logic also in other views) + showWeekNumbers = opt('weekNumbers'); + weekNumberTitle = opt('weekNumberTitle'); + if (opt('weekNumberCalculation') != 'iso') { + weekNumberFormat = "w"; + } + else { + weekNumberFormat = "W"; + } + + snapMinutes = opt('snapMinutes') || opt('slotMinutes'); } @@ -2976,8 +3098,15 @@ function AgendaView(element, calendar, viewName) { s = "<table style='width:100%' class='fc-agenda-days fc-border-separate' cellspacing='0'>" + "<thead>" + - "<tr>" + - "<th class='fc-agenda-axis " + headerClass + "'> </th>"; + "<tr>"; + + if (showWeekNumbers) { + s += "<th class='fc-agenda-axis fc-week-number " + headerClass + "'/>"; + } + else { + s += "<th class='fc-agenda-axis " + headerClass + "'> </th>"; + } + for (i=0; i<colCnt; i++) { s += "<th class='fc- fc-col" + i + ' ' + headerClass + "'/>"; // fc- needed for setDayID @@ -3111,6 +3240,18 @@ function AgendaView(element, calendar, viewName) { var bodyCell; var date; var today = clearTime(new Date()); + + if (showWeekNumbers) { + var weekText = formatDate(colDate(0), weekNumberFormat); + if (rtl) { + weekText = weekText + weekNumberTitle; + } + else { + weekText = weekNumberTitle + weekText; + } + dayHead.find('.fc-week-number').text(weekText); + } + for (i=0; i<colCnt; i++) { date = colDate(i); headCell = dayHeadCells.eq(i); @@ -3149,6 +3290,9 @@ function AgendaView(element, calendar, viewName) { slotScroller.height(bodyHeight - allDayHeight - 1); slotHeight = slotTableFirstInner.height() + 1; // +1 for border + + snapRatio = opt('slotMinutes') / snapMinutes; + snapHeight = slotHeight / snapRatio; if (dateChanged) { resetScroll(); @@ -3337,10 +3481,10 @@ function AgendaView(element, calendar, viewName) { function constrain(n) { return Math.max(slotScrollerTop, Math.min(slotScrollerBottom, n)); } - for (var i=0; i<slotCnt; i++) { + for (var i=0; i<slotCnt*snapRatio; i++) { // adapt slot count to increased/decreased selection slot count rows.push([ - constrain(slotTableTop + slotHeight*i), - constrain(slotTableTop + slotHeight*(i+1)) + constrain(slotTableTop + snapHeight*i), + constrain(slotTableTop + snapHeight*(i+1)) ]); } }); @@ -3381,7 +3525,7 @@ function AgendaView(element, calendar, viewName) { slotIndex--; } if (slotIndex >= 0) { - addMinutes(d, minMinute + slotIndex * opt('slotMinutes')); + addMinutes(d, minMinute + slotIndex * snapMinutes); } return d; } @@ -3544,9 +3688,9 @@ function AgendaView(element, calendar, viewName) { var d2 = cellDate(cell); dates = [ d1, - addMinutes(cloneDate(d1), opt('slotMinutes')), + addMinutes(cloneDate(d1), snapMinutes), // calculate minutes depending on selection slot minutes d2, - addMinutes(cloneDate(d2), opt('slotMinutes')) + addMinutes(cloneDate(d2), snapMinutes) ].sort(cmp); renderSlotSelection(dates[0], dates[3]); }else{ @@ -3603,6 +3747,8 @@ function AgendaView(element, calendar, viewName) { } +;; + function AgendaEventRenderer() { var t = this; @@ -3639,7 +3785,8 @@ function AgendaEventRenderer() { var resizableDayEvent = t.resizableDayEvent; // TODO: streamline binding architecture var getColCnt = t.getColCnt; var getColWidth = t.getColWidth; - var getSlotHeight = t.getSlotHeight; + var getSnapHeight = t.getSnapHeight; + var getSnapMinutes = t.getSnapMinutes; var getBodyContent = t.getBodyContent; var reportEventElement = t.reportEventElement; var showEvents = t.showEvents; @@ -3675,6 +3822,7 @@ function AgendaEventRenderer() { setHeight(); // no params means set to viewHeight } renderSlotSegs(compileSlotSegs(slotEvents), modifiedEventId); + trigger('eventAfterAllRender'); } @@ -3760,7 +3908,7 @@ function AgendaEventRenderer() { vsideCache={}, hsideCache={}, key, val, - contentElement, + titleElement, height, slotSegmentContainer = getSlotSegmentContainer(), rtl, dis, dit, @@ -3849,9 +3997,9 @@ function AgendaEventRenderer() { seg.vsides = val === undefined ? (vsideCache[key] = vsides(eventElement, true)) : val; val = hsideCache[key]; seg.hsides = val === undefined ? (hsideCache[key] = hsides(eventElement, true)) : val; - contentElement = eventElement.find('div.fc-event-content'); - if (contentElement.length) { - seg.contentTop = contentElement[0].offsetTop; + titleElement = eventElement.find('.fc-event-title'); + if (titleElement.length) { + seg.contentTop = titleElement[0].offsetTop; } } } @@ -3865,7 +4013,7 @@ function AgendaEventRenderer() { eventElement[0].style.height = height + 'px'; event = seg.event; if (seg.contentTop !== undefined && height - seg.contentTop < 10) { - // not enough room for title, put it in the time header + // not enough room for title, put it in the time (TODO: maybe make both display:inline instead) eventElement.find('div.fc-event-time') .text(formatDate(event.start, opt('timeFormat')) + ' - ' + event.title); eventElement.find('div.fc-event-title') @@ -3882,16 +4030,15 @@ function AgendaEventRenderer() { var html = "<"; var url = event.url; var skinCss = getSkinCss(event, opt); - var skinCssAttr = (skinCss ? " style='" + skinCss + "'" : ''); - var classes = ['fc-event', 'fc-event-skin', 'fc-event-vert']; + var classes = ['fc-event', 'fc-event-vert']; if (isEventDraggable(event)) { classes.push('fc-event-draggable'); } if (seg.isStart) { - classes.push('fc-corner-top'); + classes.push('fc-event-start'); } if (seg.isEnd) { - classes.push('fc-corner-bottom'); + classes.push('fc-event-end'); } classes = classes.concat(event.className); if (event.source) { @@ -3906,19 +4053,15 @@ function AgendaEventRenderer() { " class='" + classes.join(' ') + "'" + " style='position:absolute;z-index:8;top:" + seg.top + "px;left:" + seg.left + "px;" + skinCss + "'" + ">" + - "<div class='fc-event-inner fc-event-skin'" + skinCssAttr + ">" + - "<div class='fc-event-head fc-event-skin'" + skinCssAttr + ">" + + "<div class='fc-event-inner'>" + "<div class='fc-event-time'>" + htmlEscape(formatDates(event.start, event.end, opt('timeFormat'))) + "</div>" + - "</div>" + - "<div class='fc-event-content'>" + "<div class='fc-event-title'>" + htmlEscape(event.title) + "</div>" + "</div>" + - "<div class='fc-event-bg'></div>" + - "</div>"; // close inner + "<div class='fc-event-bg'></div>"; if (seg.isEnd && isEventResizable(event)) { html += "<div class='ui-resizable-handle ui-resizable-s'>=</div>"; @@ -3968,7 +4111,8 @@ function AgendaEventRenderer() { var dis = opt('isRTL') ? -1 : 1; var hoverListener = getHoverListener(); var colWidth = getColWidth(); - var slotHeight = getSlotHeight(); + var snapHeight = getSnapHeight(); + var snapMinutes = getSnapMinutes(); var minMinute = getMinMinute(); eventElement.draggable({ zIndex: 9, @@ -3999,9 +4143,9 @@ function AgendaEventRenderer() { eventElement.width(colWidth - 10); // don't use entire width setOuterHeight( eventElement, - slotHeight * Math.round( - (event.end ? ((event.end - event.start) / MINUTE_MS) : opt('defaultEventMinutes')) - / opt('slotMinutes') + snapHeight * Math.round( + (event.end ? ((event.end - event.start) / MINUTE_MS) : opt('defaultEventMinutes')) / + snapMinutes ) ); eventElement.draggable('option', 'grid', [colWidth, 1]); @@ -4033,8 +4177,8 @@ function AgendaEventRenderer() { // changed! var minuteDelta = 0; if (!allDay) { - minuteDelta = Math.round((eventElement.offset().top - getBodyContent().offset().top) / slotHeight) - * opt('slotMinutes') + minuteDelta = Math.round((eventElement.offset().top - getBodyContent().offset().top) / snapHeight) + * snapMinutes + minMinute - (event.start.getHours() * 60 + event.start.getMinutes()); } @@ -4067,11 +4211,12 @@ function AgendaEventRenderer() { var hoverListener = getHoverListener(); var colCnt = getColCnt(); var colWidth = getColWidth(); - var slotHeight = getSlotHeight(); + var snapHeight = getSnapHeight(); + var snapMinutes = getSnapMinutes(); eventElement.draggable({ zIndex: 9, scroll: false, - grid: [colWidth, slotHeight], + grid: [colWidth, snapHeight], axis: colCnt==1 ? 'y' : false, opacity: opt('dragOpacity'), revertDuration: opt('dragRevertDuration'), @@ -4105,7 +4250,7 @@ function AgendaEventRenderer() { }, ev, 'drag'); }, drag: function(ev, ui) { - minuteDelta = Math.round((ui.position.top - origPosition.top) / slotHeight) * opt('slotMinutes'); + minuteDelta = Math.round((ui.position.top - origPosition.top) / snapHeight) * snapMinutes; if (minuteDelta != prevMinuteDelta) { if (!allDay) { updateTimeText(minuteDelta); @@ -4142,7 +4287,7 @@ function AgendaEventRenderer() { // convert back to original slot-event if (allDay) { timeElement.css('display', ''); // show() was causing display=inline - eventElement.draggable('option', 'grid', [colWidth, slotHeight]); + eventElement.draggable('option', 'grid', [colWidth, snapHeight]); allDay = false; } } @@ -4155,38 +4300,39 @@ function AgendaEventRenderer() { function resizableSlotEvent(event, eventElement, timeElement) { - var slotDelta, prevSlotDelta; - var slotHeight = getSlotHeight(); + var snapDelta, prevSnapDelta; + var snapHeight = getSnapHeight(); + var snapMinutes = getSnapMinutes(); eventElement.resizable({ handles: { - s: 'div.ui-resizable-s' + s: '.ui-resizable-handle' }, - grid: slotHeight, + grid: snapHeight, start: function(ev, ui) { - slotDelta = prevSlotDelta = 0; + snapDelta = prevSnapDelta = 0; hideEvents(event, eventElement); eventElement.css('z-index', 9); 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(slotHeight, eventElement.height()) - ui.originalSize.height) / slotHeight); - if (slotDelta != prevSlotDelta) { + snapDelta = Math.round((Math.max(snapHeight, eventElement.height()) - ui.originalSize.height) / snapHeight); + if (snapDelta != prevSnapDelta) { timeElement.text( formatDates( event.start, - (!slotDelta && !event.end) ? null : // no change, so don't display time range - addMinutes(eventEnd(event), opt('slotMinutes')*slotDelta), + (!snapDelta && !event.end) ? null : // no change, so don't display time range + addMinutes(eventEnd(event), snapMinutes*snapDelta), opt('timeFormat') ) ); - prevSlotDelta = slotDelta; + prevSnapDelta = snapDelta; } }, stop: function(ev, ui) { trigger('eventResizeStop', this, event, ev, ui); - if (slotDelta) { - eventResize(this, event, 0, opt('slotMinutes')*slotDelta, ev, ui); + if (snapDelta) { + eventResize(this, event, 0, snapMinutes*snapDelta, ev, ui); }else{ eventElement.css('z-index', 8); showEvents(event, eventElement); @@ -4218,6 +4364,8 @@ function countForwardSegs(levels) { +;; + function View(element, calendar, viewName) { var t = this; @@ -4472,6 +4620,8 @@ function View(element, calendar, viewName) { } +;; + function DayEventRenderer() { var t = this; @@ -4609,28 +4759,22 @@ function DayEventRenderer() { for (i=0; i<segCnt; i++) { seg = segs[i]; event = seg.event; - classes = ['fc-event', 'fc-event-skin', 'fc-event-hori']; + classes = ['fc-event', 'fc-event-hori']; if (isEventDraggable(event)) { classes.push('fc-event-draggable'); } + if (seg.isStart) { + classes.push('fc-event-start'); + } + if (seg.isEnd) { + classes.push('fc-event-end'); + } if (rtl) { - if (seg.isStart) { - classes.push('fc-corner-right'); - } - if (seg.isEnd) { - classes.push('fc-corner-left'); - } leftCol = dayOfWeekCol(seg.end.getDay()-1); rightCol = dayOfWeekCol(seg.start.getDay()); left = seg.isEnd ? colContentLeft(leftCol) : minLeft; right = seg.isStart ? colContentRight(rightCol) : maxLeft; }else{ - if (seg.isStart) { - classes.push('fc-corner-left'); - } - if (seg.isEnd) { - classes.push('fc-corner-right'); - } leftCol = dayOfWeekCol(seg.start.getDay()); rightCol = dayOfWeekCol(seg.end.getDay()-1); left = seg.isStart ? colContentLeft(leftCol) : minLeft; @@ -4651,10 +4795,7 @@ function DayEventRenderer() { " class='" + classes.join(' ') + "'" + " style='position:absolute;z-index:8;left:"+left+"px;" + skinCss + "'" + ">" + - "<div" + - " class='fc-event-inner fc-event-skin'" + - (skinCss ? " style='" + skinCss + "'" : '') + - ">"; + "<div class='fc-event-inner'>"; if (!event.allDay && seg.isStart) { html += "<span class='fc-event-time'>" + @@ -4816,7 +4957,7 @@ function DayEventRenderer() { var rowDivs = []; for (i=0; i<rowCnt; i++) { rowDivs[i] = allDayRow(i) - .find('td:first div.fc-day-content > div'); // optimal selector? + .find('div.fc-day-content > div'); // optimal selector? } return rowDivs; } @@ -4859,7 +5000,7 @@ function DayEventRenderer() { function resizableDayEvent(event, element, seg) { var rtl = opt('isRTL'); var direction = rtl ? 'w' : 'e'; - var handle = element.find('div.ui-resizable-' + direction); + var handle = element.find('.ui-resizable-' + direction); // TODO: stop using this class because we aren't using jqui for this var isResizing = false; // TODO: look into using jquery-ui mouse widget for this stuff @@ -4955,6 +5096,8 @@ function DayEventRenderer() { } +;; + //BUG: unselect needs to be triggered when events are dragged+dropped function SelectionManager() { @@ -5052,6 +5195,8 @@ function SelectionManager() { } + +;; function OverlayManager() { var t = this; @@ -5090,6 +5235,8 @@ function OverlayManager() { } +;; + function CoordinateGrid(buildFunc) { var t = this; @@ -5136,6 +5283,8 @@ function CoordinateGrid(buildFunc) { } +;; + function HoverListener(coordinateGrid) { @@ -5194,6 +5343,8 @@ function _fixUIEvent(event) { // for issue 1168 event.pageY = event.originalEvent.pageY; } } +;; + function HorizontalPositionCache(getElement) { var t = this, @@ -5220,5 +5371,7 @@ function HorizontalPositionCache(getElement) { }; } -
-})(jQuery); + +;; + +})(jQuery);
\ No newline at end of file |