/* Agenda Views: agendaWeek/agendaDay -----------------------------------------------------------------------------*/ setDefaults({ allDaySlot: true, allDayText: 'all-day', firstHour: 6, slotMinutes: 30, defaultEventMinutes: 120, axisFormat: 'h(:mm)tt', timeFormat: { agenda: 'h:mm{ - h:mm}' }, dragOpacity: { agenda: .5 }, minTime: 0, maxTime: 24 }); views.agendaWeek = function(element, options) { return new Agenda(element, options, { render: function(date, delta) { if (delta) { addDays(date, delta * 7); } var visStart = this.visStart = cloneDate( this.start = addDays(cloneDate(date), -((date.getDay() - options.firstDay + 7) % 7)) ), visEnd = this.visEnd = cloneDate( this.end = addDays(cloneDate(visStart), 7) ); if (!options.weekends) { skipWeekend(visStart); skipWeekend(visEnd, -1, true); } this.title = formatDates( visStart, addDays(cloneDate(visEnd), -1), this.option('titleFormat'), options ); this.renderAgenda( options.weekends ? 7 : 5, this.option('columnFormat') ); } }); }; views.agendaDay = function(element, options) { return new Agenda(element, options, { render: function(date, delta) { if (delta) { addDays(date, delta); if (!options.weekends) { skipWeekend(date, delta < 0 ? -1 : 1); } } this.title = formatDate(date, this.option('titleFormat'), options); this.start = this.visStart = cloneDate(date, true); this.end = this.visEnd = addDays(cloneDate(this.start), 1); this.renderAgenda( 1, this.option('columnFormat') ); } }); }; function Agenda(element, options, methods) { var head, body, bodyContent, bodyTable, bg, colCnt, axisWidth, colWidth, slotHeight, viewWidth, viewHeight, savedScrollTop, cachedEvents=[], daySegmentContainer, slotSegmentContainer, tm, firstDay, nwe, // no weekends (int) rtl, dis, dit, // day index sign / translate minMinute, maxMinute, colContentPositions = new HorizontalPositionCache(function(col) { return bg.find('td:eq(' + col + ') div div'); }), slotTopCache = {}, // ... view = $.extend(this, viewMethods, methods, { renderAgenda: renderAgenda, renderEvents: renderEvents, rerenderEvents: rerenderEvents, clearEvents: clearEvents, setHeight: setHeight, setWidth: setWidth, beforeHide: function() { savedScrollTop = body.scrollTop(); }, afterShow: function() { body.scrollTop(savedScrollTop); }, defaultEventEnd: function(event) { var start = cloneDate(event.start); if (event.allDay) { return start; } return addMinutes(start, options.defaultEventMinutes); } }); view.init(element, options); /* Time-slot rendering -----------------------------------------------------------------------------*/ element.addClass('fc-agenda'); if (element.disableSelection) { element.disableSelection(); } function renderAgenda(c, colFormat) { colCnt = c; // update option-derived variables tm = options.theme ? 'ui' : 'fc'; nwe = options.weekends ? 0 : 1; firstDay = options.firstDay; if (rtl = options.isRTL) { dis = -1; dit = colCnt - 1; }else{ dis = 1; dit = 0; } minMinute = parseTime(options.minTime); maxMinute = parseTime(options.maxTime); var d0 = rtl ? addDays(cloneDate(view.visEnd), -1) : cloneDate(view.visStart), d = cloneDate(d0), today = clearTime(new Date()); if (!head) { // first time rendering, build from scratch var i, minutes, slotNormal = options.slotMinutes % 15 == 0, //... // head s = "
" + "" + "" + ""; for (i=0; i" + formatDate(d, colFormat, options) + ""; addDays(d, dis); if (nwe) { skipWeekend(d, dis); } } s += ""; if (options.allDaySlot) { s += "" + "" + "" + "" + ""; } s+= "
  
" + options.allDayText + "" + "
 
 
"; head = $(s).appendTo(element); head.find('td').click(slotClick); // all-day event container daySegmentContainer = $("
").appendTo(head); // body d = zeroDate(); var maxd = addMinutes(cloneDate(d), maxMinute); addMinutes(d, minMinute); s = ""; for (i=0; d < maxd; i++) { minutes = d.getMinutes(); s += ""; addMinutes(d, options.slotMinutes); } s += "
" + ((!slotNormal || !minutes) ? formatDate(d, options.axisFormat) : ' ') + "
 
"; body = $("
") .append(bodyContent = $("
") .append(bodyTable = $(s))) .appendTo(element); body.find('td').click(slotClick); // slot event container slotSegmentContainer = $("
").appendTo(bodyContent); // background stripes d = cloneDate(d0); s = "
" + ""; for (i=0; i
 
"; addDays(d, dis); if (nwe) { skipWeekend(d, dis); } } s += "
"; bg = $(s).appendTo(element); }else{ // skeleton already built, just modify it clearEvents(); // redo column header text and class head.find('tr:first th').slice(1, -1).each(function() { $(this).text(formatDate(d, colFormat, options)); this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]); addDays(d, dis); if (nwe) { skipWeekend(d, dis); } }); // change classes of background stripes d = cloneDate(d0); bg.find('td').each(function() { this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]); if (+d == +today) { $(this) .removeClass('fc-not-today') .addClass('fc-today') .addClass(tm + '-state-highlight'); }else{ $(this) .addClass('fc-not-today') .removeClass('fc-today') .removeClass(tm + '-state-highlight'); } addDays(d, dis); if (nwe) { skipWeekend(d, dis); } }); } } function resetScroll() { var d0 = zeroDate(), scrollDate = cloneDate(d0); scrollDate.setHours(options.firstHour); var top = timePosition(d0, scrollDate) + 1, // +1 for the border scroll = function() { body.scrollTop(top); }; scroll(); setTimeout(scroll, 0); // overrides any previous scroll state made by the browser } function setHeight(height, dateChanged) { viewHeight = height; slotTopCache = {}; body.height(height - head.height()); slotHeight = body.find('tr:first div').height() + 1; bg.css({ top: head.find('tr').height(), height: height }); if (dateChanged) { resetScroll(); } } function setWidth(width) { viewWidth = width; colContentPositions.clear(); body.width(width); bodyTable.width(''); var topTDs = head.find('tr:first th'), stripeTDs = bg.find('td'), clientWidth = body[0].clientWidth; bodyTable.width(clientWidth); // time-axis width axisWidth = 0; setOuterWidth( head.find('tr:lt(2) th:first').add(body.find('tr:first th')) .width('') .each(function() { axisWidth = Math.max(axisWidth, $(this).outerWidth()); }), axisWidth ); // column width colWidth = Math.floor((clientWidth - axisWidth) / colCnt); setOuterWidth(stripeTDs.slice(0, -1), colWidth); setOuterWidth(topTDs.slice(1, -2), colWidth); setOuterWidth(topTDs.slice(-2, -1), clientWidth - axisWidth - colWidth*(colCnt-1)); bg.css({ left: axisWidth, width: clientWidth - axisWidth }); } function slotClick(ev) { var col = Math.floor((ev.pageX - bg.offset().left) / colWidth), date = addDays(cloneDate(view.visStart), dit + dis*col), rowMatch = this.className.match(/fc-slot(\d+)/); if (rowMatch) { var mins = parseInt(rowMatch[1]) * options.slotMinutes, hours = Math.floor(mins/60); date.setHours(hours); date.setMinutes(mins%60 + minMinute); view.trigger('dayClick', this, date, false, ev); }else{ view.trigger('dayClick', this, date, true, ev); } } /* Event Rendering -----------------------------------------------------------------------------*/ function renderEvents(events, modifiedEventId) { view.reportEvents(cachedEvents = events); var i, len=events.length, dayEvents=[], slotEvents=[]; for (i=0; i" + "" + "" + "" + htmlEscape(formatDates(event.start, event.end, view.option('timeFormat'))) + "" + "" + htmlEscape(event.title) + "" + "" + ((event.editable || event.editable === undefined && options.editable) && !options.disableResizing && $.fn.resizable ? "
=
" : '') + "
"; } slotSegmentContainer[0].innerHTML = html; // faster than html() eventElements = slotSegmentContainer.children(); // retrieve elements, run through eventRender callback, bind event handlers for (i=0; i= addMinutes(cloneDate(day), maxMinute)) { return bodyContent.height(); } var slotMinutes = options.slotMinutes, minutes = time.getHours()*60 + time.getMinutes() - minMinute, slotI = Math.floor(minutes / slotMinutes), slotTop = slotTopCache[slotI]; if (slotTop === undefined) { slotTop = slotTopCache[slotI] = body.find('tr:eq(' + slotI + ') td div')[0].offsetTop; } return Math.max(0, Math.round( slotTop - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes) )); } function day2col(dayOfWeek) { return ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt)*dis+dit; } } // count the number of colliding, higher-level segments (for event squishing) function countForwardSegs(levels) { var i, j, k, level, segForward, segBack; for (i=levels.length-1; i>0; i--) { level = levels[i]; for (j=0; j