diff --git a/src/agenda/AgendaView.js b/src/agenda/AgendaView.js index 2a4373c..484088c 100644 --- a/src/agenda/AgendaView.js +++ b/src/agenda/AgendaView.js @@ -121,6 +121,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; @@ -158,6 +161,16 @@ 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"; + } } @@ -175,8 +188,15 @@ function AgendaView(element, calendar, viewName) { s = "" + "" + - "" + - ""; + ""; + + if (showWeekNumbers) { + s += ""; + } + for (i=0; i"; // fc- needed for setDayID @@ -310,6 +330,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" + "" + ""; + if (showWeekNumbers) { + s += + ""; + } for (j=0; j" + // need fc- for setDayID @@ -161,11 +183,11 @@ function BasicView(element, calendar, viewName) { table = $(s).appendTo(element); head = table.find('thead'); - headCells = head.find('th'); + headCells = head.find('th:not(.fc-week-number)'); body = table.find('tbody'); bodyRows = body.find('tr'); - bodyCells = body.find('td'); - bodyFirstCells = bodyCells.filter(':first-child'); + bodyCells = body.find('td').filter(':not(.fc-week-number)'); + bodyFirstCells = bodyCells.filter(':first-child, td.fc-week-number + *'); // either first cell in each row, or immediately following week # bodyCellTopInners = bodyRows.eq(0).find('div.fc-day-content div'); markFirstLast(head.add(head.find('tr'))); // marks first+last tr/th's @@ -189,6 +211,10 @@ function BasicView(element, calendar, viewName) { var date; var row; + if (showWeekNumbers) { + head.find('.fc-week-number').text(weekNumberTitle); + } + if (dowDirty) { headCells.each(function(i, _cell) { cell = $(_cell); @@ -220,6 +246,14 @@ function BasicView(element, calendar, viewName) { bodyRows.each(function(i, _row) { row = $(_row); if (i < rowCnt) { + + if (showWeekNumbers) { + var weekStartDate = indexDate(i*7); + row.find('.fc-week-number > div').text( + formatDate(weekStartDate, weekNumberFormat) + ); + } + row.show(); if (i == rowCnt-1) { row.addClass('fc-last'); @@ -265,7 +299,13 @@ function BasicView(element, calendar, viewName) { 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); } @@ -475,8 +515,12 @@ function BasicView(element, calendar, viewName) { function allDayBounds(i) { + var left = 0; + if (showWeekNumbers) { + left += weekNumberWidth; + } return { - left: 0, + left: left, right: viewWidth }; } diff --git a/src/basic/basic.css b/src/basic/basic.css index cd4eb4f..d006a99 100644 --- a/src/basic/basic.css +++ b/src/basic/basic.css @@ -5,6 +5,15 @@ .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; diff --git a/src/common/DayEventRenderer.js b/src/common/DayEventRenderer.js index 1575a4e..0430c69 100644 --- a/src/common/DayEventRenderer.js +++ b/src/common/DayEventRenderer.js @@ -343,7 +343,7 @@ function DayEventRenderer() { var rowDivs = []; for (i=0; i div'); // optimal selector? + .find('div.fc-day-content > div'); // optimal selector? } return rowDivs; } diff --git a/src/date_util.js b/src/date_util.js index 068679d..cc74799 100644 --- a/src/date_util.js +++ b/src/date_util.js @@ -353,7 +353,32 @@ 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); } }; +/* 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; +} + diff --git a/src/defaults.js b/src/defaults.js index 9cb9982..6ac058c 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -10,6 +10,9 @@ var defaults = { right: 'today prev,next' }, weekends: true, + weekNumbers: false, + weekNumberCalculation: 'iso', + weekNumberTitle: 'W', // editing //editable: false, diff --git a/tests/week_numbers.html b/tests/week_numbers.html new file mode 100644 index 0000000..973b3c4 --- /dev/null +++ b/tests/week_numbers.html @@ -0,0 +1,109 @@ + + + + + + + + + + + + + +
+ +
 
"; + } + else { + s += " 
"; + } for (i=0; i"; // need fc- for setDayID @@ -138,6 +156,10 @@ function BasicView(element, calendar, viewName) { for (i=0; i"; + if (showWeekNumbers) { + s += + "