diff --git a/app/assets/javascripts/fullcalendar.js b/app/assets/javascripts/fullcalendar.js index 99e25e3..0d43e58 100755 --- a/app/assets/javascripts/fullcalendar.js +++ b/app/assets/javascripts/fullcalendar.js @@ -1,23 +1,20 @@ -/** - * @preserve - * FullCalendar v1.5.4 - * http://arshaw.com/fullcalendar/ - * +/*! + * FullCalendar v1.6.1 + * 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: Tue Sep 4 23:38:33 2012 -0700 - * */ (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: "", + next: "", + prevYear: "«", + nextYear: "»", today: 'today', month: 'month', week: 'week', @@ -98,10 +98,10 @@ var rtlDefaults = { right: 'title' }, buttonText: { - prev: ' ► ', - next: ' ◄ ', - prevYear: ' >> ', - nextYear: ' << ' + prev: "", + next: "", + prevYear: "»", + nextYear: "«" }, buttonIcons: { prev: 'circle-triangle-e', @@ -111,7 +111,9 @@ var rtlDefaults = { -var fc = $.fullCalendar = { version: "1.5.4" }; +;; + +var fc = $.fullCalendar = { version: "1.6.1" }; 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 = $( "" + - "" + - "" + - (icon ? - "" + - "" + - "" : - text - ) + - "" + - "" + - "" + + (icon ? + "" + + "" + + "" : + text + ) + "" - ); - 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" + - "" + - ""; - for (i=0; i"; // need fc- for setDayID - } - s += - "" + - "" + - ""; - for (i=0; i"; - for (j=0; j" + // need fc- for setDayID - "
" + - (showNumbers ? - "
" : - '' - ) + - "
" + - "
 
" + - "
" + - "
" + - ""; - } - s += - ""; - } - s += - "" + - ""; - table = $(s).appendTo(element); - - 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'); - - 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); - + function buildEventContainer() { daySegmentContainer = $("
") .appendTo(element); @@ -2270,55 +2280,120 @@ function BasicView(element, calendar, viewName) { - function updateCells(firstTime) { - var dowDirty = firstTime || rowCnt == 1; // could the cells' day-of-weeks need updating? + function buildTable(showNumbers) { + var html = ''; + var i, j; + var headerClass = tm + "-widget-header"; + var contentClass = tm + "-widget-content"; 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; - var date; - var row; + + html += "" + + "" + + ""; + + if (showWeekNumbers) { + html += "" + + "" + + ""; + + for (i=0; i" + + "
" + + ""; + } + + for (j=0; j" + + "
"; + if (showNumbers) { + html += "
" + cellDate.getDate() + "
"; + } + html += "
" + + "
 
" + + "
" + + "
" + + ""; + } + + html += ""; + } + html += "
" + + "
"; + } + + for (i=0; i"; + } + + html += "
"; + + lockHeight(); // the unlock happens later, in setHeight()... + if (table) { + table.remove(); + } + table = $(html).appendTo(element); + + head = table.find('thead'); + headCells = head.find('.fc-day-header'); + body = table.find('tbody'); + bodyRows = body.find('tr'); + 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'); + bodyRows.filter(':last').addClass('fc-last'); - 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); } @@ -2348,13 +2423,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); } @@ -2372,8 +2454,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); } } @@ -2564,15 +2645,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; @@ -2615,6 +2715,7 @@ function BasicEventRenderer() { function renderEvents(events, modifiedEventId) { reportEvents(events); renderDaySegs(compileSegs(events), modifiedEventId); + trigger('eventAfterAllRender'); } @@ -2714,6 +2815,8 @@ function BasicEventRenderer() { } +;; + fcViews.agendaWeek = AgendaWeekView; function AgendaWeekView(element, calendar) { @@ -2760,6 +2863,8 @@ function AgendaWeekView(element, calendar) { } +;; + fcViews.agendaDay = AgendaDayView; function AgendaDayView(element, calendar) { @@ -2796,6 +2901,8 @@ function AgendaDayView(element, calendar) { } +;; + setDefaults({ allDaySlot: true, allDayText: 'all-day', @@ -2847,7 +2954,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; @@ -2903,7 +3011,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; @@ -2911,6 +3022,7 @@ function AgendaView(element, calendar, viewName) { var hoverListener; var colContentPositions; var slotTopCache = {}; + var savedScrollTop; var tm; var firstDay; @@ -2918,6 +3030,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; @@ -2955,6 +3070,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'); } @@ -2972,8 +3099,15 @@ function AgendaView(element, calendar, viewName) { s = "" + "" + - "" + - ""; + ""; + + if (showWeekNumbers) { + s += ""; + } + for (i=0; i"; // fc- needed for setDayID @@ -3107,6 +3241,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= 0) { - addMinutes(d, minMinute + slotIndex * opt('slotMinutes')); + addMinutes(d, minMinute + slotIndex * snapMinutes); } return d; } @@ -3540,9 +3689,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{ @@ -3599,6 +3748,8 @@ function AgendaView(element, calendar, viewName) { } +;; + function AgendaEventRenderer() { var t = this; @@ -3635,7 +3786,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; @@ -3671,6 +3823,7 @@ function AgendaEventRenderer() { setHeight(); // no params means set to viewHeight } renderSlotSegs(compileSlotSegs(slotEvents), modifiedEventId); + trigger('eventAfterAllRender'); } @@ -3756,7 +3909,7 @@ function AgendaEventRenderer() { vsideCache={}, hsideCache={}, key, val, - contentElement, + titleElement, height, slotSegmentContainer = getSlotSegmentContainer(), rtl, dis, dit, @@ -3845,9 +3998,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; } } } @@ -3861,7 +4014,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') @@ -3878,16 +4031,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) { @@ -3902,19 +4054,15 @@ function AgendaEventRenderer() { " class='" + classes.join(' ') + "'" + " style='position:absolute;z-index:8;top:" + seg.top + "px;left:" + seg.left + "px;" + skinCss + "'" + ">" + - "
" + - "
" + + "
" + "
" + htmlEscape(formatDates(event.start, event.end, opt('timeFormat'))) + "
" + - "
" + - "
" + "
" + htmlEscape(event.title) + "
" + "
" + - "
" + - "
"; // close inner + "
"; if (seg.isEnd && isEventResizable(event)) { html += "
=
"; @@ -3964,7 +4112,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, @@ -3995,9 +4144,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]); @@ -4029,8 +4178,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()); } @@ -4063,11 +4212,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'), @@ -4101,7 +4251,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); @@ -4138,7 +4288,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; } } @@ -4151,38 +4301,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); @@ -4214,6 +4365,8 @@ function countForwardSegs(levels) { +;; + function View(element, calendar, viewName) { var t = this; @@ -4468,6 +4621,8 @@ function View(element, calendar, viewName) { } +;; + function DayEventRenderer() { var t = this; @@ -4605,28 +4760,22 @@ function DayEventRenderer() { for (i=0; i" + - ""; + "
"; if (!event.allDay && seg.isStart) { html += "" + @@ -4812,7 +4958,7 @@ function DayEventRenderer() { var rowDivs = []; for (i=0; i div'); // optimal selector? + .find('div.fc-day-content > div'); // optimal selector? } return rowDivs; } @@ -4855,7 +5001,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 @@ -4951,6 +5097,8 @@ function DayEventRenderer() { } +;; + //BUG: unselect needs to be triggered when events are dragged+dropped function SelectionManager() { @@ -5048,6 +5196,8 @@ function SelectionManager() { } + +;; function OverlayManager() { var t = this; @@ -5086,6 +5236,8 @@ function OverlayManager() { } +;; + function CoordinateGrid(buildFunc) { var t = this; @@ -5132,6 +5284,8 @@ function CoordinateGrid(buildFunc) { } +;; + function HoverListener(coordinateGrid) { @@ -5190,6 +5344,8 @@ function _fixUIEvent(event) { // for issue 1168 event.pageY = event.originalEvent.pageY; } } +;; + function HorizontalPositionCache(getElement) { var t = this, @@ -5217,4 +5373,6 @@ function HorizontalPositionCache(getElement) { } -})(jQuery); +;; + +})(jQuery); \ No newline at end of file diff --git a/app/assets/stylesheets/fullcalendar.css b/app/assets/stylesheets/fullcalendar.css index 941a069..acae725 100755 --- a/app/assets/stylesheets/fullcalendar.css +++ b/app/assets/stylesheets/fullcalendar.css @@ -1,12 +1,7 @@ -/* - * FullCalendar v1.5.4 Stylesheet - * - * Copyright (c) 2011 Adam Shaw - * Dual licensed under the MIT and GPL licenses, located in - * MIT-LICENSE.txt and GPL-LICENSE.txt respectively. - * - * Date: Tue Sep 4 23:38:33 2012 -0700 - * +/*! + * FullCalendar v1.6.1 Stylesheet + * Docs & License: http://arshaw.com/fullcalendar/ + * (c) 2013 Adam Shaw */ @@ -59,10 +54,8 @@ html .fc, vertical-align: top; } -.fc-header-title h2{ +.fc-header-title h2 { margin-top: 0; - font-size: 12px; - line-height: 24px; white-space: nowrap; } @@ -81,11 +74,8 @@ html .fc, margin-right: -1px; } -.fc-header .fc-corner-right { - margin-right: 1px; /* back to normal */ - } - -.fc-header .ui-corner-right { +.fc-header .fc-corner-right, /* non-theme */ +.fc-header .ui-corner-right { /* theme */ margin-right: 0; /* back to normal */ } @@ -126,17 +116,17 @@ html .fc, .fc-widget-header, /*
 
"; + } + else { + s += " , usually */ .fc-widget-content { /* , usually */ - border: 1px solid #ccc; + border: 1px solid #ddd; } .fc-state-highlight { /* today cell */ /* TODO: add .fc-today to */ - background: #ffc; + background: #fcf8e3; } .fc-cell-overlay { /* semi-transparent rectangle while dragging */ - background: #9cf; - opacity: .2; - filter: alpha(opacity=20); /* for IE */ + background: #bce8f1; + opacity: .3; + filter: alpha(opacity=30); /* for IE */ } @@ -147,43 +137,54 @@ html .fc, .fc-button { position: relative; display: inline-block; + padding: 0 .6em; + overflow: hidden; + height: 1.9em; + line-height: 1.9em; + white-space: nowrap; cursor: pointer; } .fc-state-default { /* non-theme */ - border-style: solid; - border-width: 1px 0; + border: 1px solid; } - -.fc-button-inner { - position: relative; - float: left; - overflow: hidden; + +.fc-state-default.fc-corner-left { /* non-theme */ + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; } - -.fc-state-default .fc-button-inner { /* non-theme */ - border-style: solid; - border-width: 0 1px; + +.fc-state-default.fc-corner-right { /* non-theme */ + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; } - -.fc-button-content { - position: relative; - float: left; - height: 1.9em; - line-height: 1.9em; - padding: 0 .6em; - white-space: nowrap; + +/* + Our default prev/next buttons use HTML entities like ‹ › « » + and we'll try to make them look good cross-browser. +*/ + +.fc-text-arrow { + margin: 0 .1em; + font-size: 2em; + font-family: "Courier New", Courier, monospace; + vertical-align: baseline; /* for IE7 */ + } + +.fc-button-prev .fc-text-arrow, +.fc-button-next .fc-text-arrow { /* for ‹ › */ + font-weight: bold; } /* icon (for jquery ui) */ -.fc-button-content .fc-icon-wrap { +.fc-button .fc-icon-wrap { position: relative; float: left; top: 50%; } -.fc-button-content .ui-icon { +.fc-button .ui-icon { position: relative; float: left; margin-top: -50%; @@ -191,107 +192,89 @@ html .fc, *top: -50%; } -/* gloss effect */ - -.fc-state-default .fc-button-effect { - position: absolute; - top: 50%; - left: 0; +/* + button states + borrowed from twitter bootstrap (http://twitter.github.com/bootstrap/) +*/ + +.fc-state-default { + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + color: #333; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); } - -.fc-state-default .fc-button-effect span { - position: absolute; - top: -100px; - left: 0; - width: 500px; - height: 100px; - border-width: 100px 0 0 1px; - border-style: solid; - border-color: #fff; - background: #444; - opacity: .09; - filter: alpha(opacity=9); - } - -/* button states (determines colors) */ - -.fc-state-default, -.fc-state-default .fc-button-inner { - border-style: solid; - border-color: #ccc #bbb #aaa; - background: #F3F3F3; - color: #000; - } - + .fc-state-hover, -.fc-state-hover .fc-button-inner { - border-color: #999; - } - .fc-state-down, -.fc-state-down .fc-button-inner { - border-color: #555; - background: #777; - } - .fc-state-active, -.fc-state-active .fc-button-inner { - border-color: #555; - background: #777; - color: #fff; +.fc-state-disabled { + color: #333333; + background-color: #e6e6e6; } - -.fc-state-disabled, -.fc-state-disabled .fc-button-inner { - color: #999; - border-color: #ddd; + +.fc-state-hover { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; } - + +.fc-state-down, +.fc-state-active { + background-color: #cccccc; + background-image: none; + outline: 0; + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + } + .fc-state-disabled { cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + box-shadow: none; } - -.fc-state-disabled .fc-button-effect { - display: none; - } - + /* Global Event Styles ------------------------------------------------------------------------*/ .fc-event { - border-style: solid; - border-width: 0; + border: 1px solid #3a87ad; /* default BORDER color */ + background-color: #3a87ad; /* default BACKGROUND color */ + color: #fff; /* default TEXT color */ font-size: .85em; cursor: default; } + +a.fc-event { + text-decoration: none; + } a.fc-event, .fc-event-draggable { cursor: pointer; } -a.fc-event { - text-decoration: none; - } - .fc-rtl .fc-event { text-align: right; } - -.fc-event-skin { - border-color: #6b6b6b; /* default BORDER color */ - background-color: #464646; /* default BACKGROUND color */ - color: #fff; /* default TEXT color */ - } - + .fc-event-inner { - position: relative; width: 100%; height: 100%; - border-style: solid; - border-width: 0; overflow: hidden; } @@ -300,7 +283,7 @@ a.fc-event { padding: 0 1px; } -.fc .ui-resizable-handle { /*** TODO: don't use ui-resizable anymore, change class ***/ +.fc .ui-resizable-handle { display: block; position: absolute; z-index: 99999; @@ -318,6 +301,20 @@ a.fc-event { border-width: 1px 0; margin-bottom: 1px; } + +.fc-ltr .fc-event-hori.fc-event-start, +.fc-rtl .fc-event-hori.fc-event-end { + border-left-width: 1px; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + } + +.fc-ltr .fc-event-hori.fc-event-end, +.fc-rtl .fc-event-hori.fc-event-start { + border-right-width: 1px; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + } /* resizable */ @@ -343,66 +340,6 @@ a.fc-event { -/* Fake Rounded Corners (for buttons and events) -------------------------------------------------------------*/ - -.fc-corner-left { - margin-left: 1px; - } - -.fc-corner-left .fc-button-inner, -.fc-corner-left .fc-event-inner { - margin-left: -1px; - } - -.fc-corner-right { - margin-right: 1px; - } - -.fc-corner-right .fc-button-inner, -.fc-corner-right .fc-event-inner { - margin-right: -1px; - } - -.fc-corner-top { - margin-top: 1px; - } - -.fc-corner-top .fc-event-inner { - margin-top: -1px; - } - -.fc-corner-bottom { - margin-bottom: 1px; - } - -.fc-corner-bottom .fc-event-inner { - margin-bottom: -1px; - } - - - -/* Fake Rounded Corners SPECIFICALLY FOR EVENTS ------------------------------------------------------------------*/ - -.fc-corner-left .fc-event-inner { - border-left-width: 1px; - } - -.fc-corner-right .fc-event-inner { - border-right-width: 1px; - } - -.fc-corner-top .fc-event-inner { - border-top-width: 1px; - } - -.fc-corner-bottom .fc-event-inner { - border-bottom-width: 1px; - } - - - /* Reusable Separate-border Table ------------------------------------------------------------*/ @@ -438,6 +375,15 @@ table.fc-border-separate { .fc-grid th { text-align: center; } + +.fc .fc-week-number { + width: 22px; + text-align: center; + } + +.fc .fc-week-number div { + padding: 0 2px; + } .fc-grid .fc-day-number { float: right; @@ -494,6 +440,10 @@ table.fc-border-separate { white-space: nowrap; font-weight: normal; } + +.fc-agenda .fc-week-number { + font-weight: bold; + } .fc-agenda .fc-day-content { padding: 2px 2px 1px; @@ -568,19 +518,28 @@ table.fc-border-separate { .fc-event-vert { border-width: 0 1px; } - -.fc-event-vert .fc-event-head, -.fc-event-vert .fc-event-content { - position: relative; - z-index: 2; - width: 100%; - overflow: hidden; + +.fc-event-vert.fc-event-start { + border-top-width: 1px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + } + +.fc-event-vert.fc-event-end { + border-bottom-width: 1px; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; } .fc-event-vert .fc-event-time { white-space: nowrap; font-size: 10px; } + +.fc-event-vert .fc-event-inner { + position: relative; + z-index: 2; + } .fc-event-vert .fc-event-bg { /* makes the event lighter w/ a semi-transparent overlay */ position: absolute; @@ -590,8 +549,8 @@ table.fc-border-separate { width: 100%; height: 100%; background: #fff; - opacity: .3; - filter: alpha(opacity=30); + opacity: .25; + filter: alpha(opacity=25); } .fc .ui-draggable-dragging .fc-event-bg, /* TODO: something nicer like .fc-opacity */ diff --git a/app/views/paid_time_off/index.html.erb b/app/views/paid_time_off/index.html.erb index 371c116..e024eac 100644 --- a/app/views/paid_time_off/index.html.erb +++ b/app/views/paid_time_off/index.html.erb @@ -2,6 +2,20 @@
+ +
+
+
+
+ Cal +
+
+
+
+
+
+
+
@@ -63,13 +77,22 @@
+ + + +