week number feature

This commit is contained in:
Adam Shaw
2013-03-02 14:00:51 -08:00
parent ebb0b4f5f5
commit b62383d0ad
8 changed files with 235 additions and 9 deletions
+34 -2
View File
@@ -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 =
"<table style='width:100%' class='fc-agenda-days fc-border-separate' cellspacing='0'>" +
"<thead>" +
"<tr>" +
"<th class='fc-agenda-axis " + headerClass + "'>&nbsp;</th>";
"<tr>";
if (showWeekNumbers) {
s += "<th class='fc-agenda-axis fc-week-number " + headerClass + "'/>";
}
else {
s += "<th class='fc-agenda-axis " + headerClass + "'>&nbsp;</th>";
}
for (i=0; i<colCnt; i++) {
s +=
"<th class='fc- fc-col" + i + ' ' + headerClass + "'/>"; // 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<colCnt; i++) {
date = colDate(i);
headCell = dayHeadCells.eq(i);
+4
View File
@@ -18,6 +18,10 @@
white-space: nowrap;
font-weight: normal;
}
.fc-agenda .fc-week-number {
font-weight: bold;
}
.fc-agenda .fc-day-content {
padding: 2px 2px 1px;
+50 -6
View File
@@ -63,6 +63,7 @@ function BasicView(element, calendar, viewName) {
var viewWidth;
var viewHeight;
var colWidth;
var weekNumberWidth;
var rowCnt, colCnt;
var coordinateGrid;
@@ -71,9 +72,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;
@@ -112,6 +116,16 @@ 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";
}
}
@@ -127,6 +141,10 @@ function BasicView(element, calendar, viewName) {
"<table class='fc-border-separate' style='width:100%' cellspacing='0'>" +
"<thead>" +
"<tr>";
if (showWeekNumbers) {
s +=
"<th class='fc-week-number " + headerClass + "'/>";
}
for (i=0; i<colCnt; i++) {
s +=
"<th class='fc- " + headerClass + "'/>"; // need fc- for setDayID
@@ -138,6 +156,10 @@ function BasicView(element, calendar, viewName) {
for (i=0; i<maxRowCnt; i++) {
s +=
"<tr class='fc-week" + i + "'>";
if (showWeekNumbers) {
s +=
"<td class='fc-week-number " + contentClass + "'><div></div></td>";
}
for (j=0; j<colCnt; j++) {
s +=
"<td class='fc- " + contentClass + " fc-day" + (i*colCnt+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
};
}
+9
View File
@@ -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;
+1 -1
View File
@@ -343,7 +343,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;
}
+25
View File
@@ -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;
}
+3
View File
@@ -10,6 +10,9 @@ var defaults = {
right: 'today prev,next'
},
weekends: true,
weekNumbers: false,
weekNumberCalculation: 'iso',
weekNumberTitle: 'W',
// editing
//editable: false,
+109
View File
@@ -0,0 +1,109 @@
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='../build/out/fullcalendar/fullcalendar.css' />
<link rel='stylesheet' href='../build/out/fullcalendar/fullcalendar.print.css' media='print' />
<link rel='stylesheet' href='../demos/cupertino/theme.css' />
<script src='../lib/moment.js'></script>
<script src='../build/deps.js'></script>
<script src='../build/out/fullcalendar/fullcalendar.js'></script>
<script>
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#calendar').fullCalendar({
weekNumbers: true,
weekNumberTitle: 'Wk ',
//weekNumberCalculation: function(date) {
// return date.getMonth(); // inappropriate. but just for testing
//},
firstDay: 1,
selectable: true,
//isRTL: true,
//theme: true,
editable: true,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,basicWeek,agendaDay,basicDay'
},
events: [
{
title: 'All Day Event',
start: new Date(y, m, 1)
},
{
title: 'Long Event',
start: new Date(y, m, d-5),
end: new Date(y, m, d-2)
},
{
id: 999,
title: 'Repeating Event',
start: new Date(y, m, d-3, 16, 0),
allDay: false
},
{
id: 999,
title: 'Repeating Event',
start: new Date(y, m, d+4, 16, 0),
allDay: false
},
{
title: 'Meeting',
start: new Date(y, m, d, 10, 30),
allDay: false
},
{
title: 'Lunch',
start: new Date(y, m, d, 12, 5),
end: new Date(y, m, d, 14, 43),
allDay: false
},
{
title: 'Birthday Party',
start: new Date(y, m, d+1, 19, 0),
end: new Date(y, m, d+1, 22, 30),
allDay: false
},
{
title: 'Click for Google',
start: new Date(y, m, 28),
end: new Date(y, m, 29),
url: 'http://google.com/'
}
]
});
});
</script>
<style>
body {
margin-top: 40px;
text-align: center;
font-size: 13px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
}
#calendar {
width: 900px;
margin: 0 auto;
}
</style>
</head>
<body>
<div id='calendar'></div>
</body>
</html>