I am building a multi view calendar from scratch. I have an implementation working that sets the date to the correct date, and lets you toggle through the months. My html for that implementation looks like this:
<div id="cal">
<div class="header">
<span class="left button" id="prev"> ⟨ </span>
<span class="month-year" id="label"> June 2017 </span>
<span class="right button" id="next"> ⟩ </span>
</div>
<table id="days">
<td>sun</td>
<td>mon</td>
<td>tue</td>
<td>wed</td>
<td>thu</td>
<td>fri</td>
<td>sat</td>
</table>
<div id="cal-frame">
<table class="curr">
<tbody>
<tr><td class="nil"></td><td class="nil"></td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td class="today">11</td><td>12</td></tr>
<tr><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td></tr>
<tr><td>20</td><td>21</td><td>22</td><td>23</td><td>24</td><td>25</td><td>26</td></tr>
<tr><td>27</td><td>28</td><td>29</td><td>30</td><td class="nil"></td><td class="nil"></td><td class="nil"></td></tr>
</tbody>
</table>
</div>
and the javascript that accompanies it is this:
$(document).ready(function(){
var CALENDAR = function () {
var wrap, label,
months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
function init(newWrap) {
wrap = $(newWrap || "#cal");
label = wrap.find("#label");
wrap.find("#prev").bind("click.calendar", function () { switchMonth(false); });
wrap.find("#next").bind("click.calendar", function () { switchMonth(true); });
label.bind("click", function () { switchMonth(null, new Date().getMonth(), new Date().getFullYear()); });
label.click();
}
function switchMonth(next, month, year) {
var curr = label.text().trim().split(" "), calendar, tempYear = parseInt(curr[1], 10);
if (!month) {
if (next) {
if (curr[0] === "December") {
month = 0;
} else {
month = months.indexOf(curr[0]) + 1;
}
} else {
if (curr[0] === "January") {
month = 11;
} else {
month = months.indexOf(curr[0]) - 1;
}
}
}
if (!year) {
if (next && month === 0) {
year = tempYear + 1;
} else if (!next && month === 11) {
year = tempYear - 1;
} else {
year = tempYear;
}
}
calendar = createCal(year, month);
$("#cal-frame", wrap)
.find(".curr")
.removeClass("curr")
.addClass("temp")
.end()
.prepend(calendar.calendar())
.find(".temp")
.fadeOut("slow", function () { $(this).remove(); });
$('#label').text(calendar.label);
}
function createCal(year, month) {
var day = 1, i, j, haveDays = true,
startDay = new Date(year, month, day).getDay(),
daysInMonths = [31, (((year%4==0)&&(year%100!=0))||(year%400==0)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
calendar = [];
if (createCal.cache[year]) {
if (createCal.cache[year][month]) {
return createCal.cache[year][month];
}
}
else {
createCal.cache[year] = {};
}
i = 0;
while (haveDays) {
calendar[i] = [];
for (j = 0; j < 7; j++) {
if (i === 0) {
if (j === startDay) {
calendar[i][j] = day++;
startDay++;
}
} else if (day <= daysInMonths[month]) {
calendar[i][j] = day++;
} else {
calendar[i][j] = "";
haveDays = false;
}
if (day > daysInMonths[month]) {
haveDays = false;
}
}
i++;
}
if (calendar[5]) {
for (i = 0; i < calendar[5].length; i++) {
if (calendar[5][i] !== "") {
calendar[4][i] = "<span>" + calendar[4][i] + "</span><span>" + calendar[5][i] + "</span>";
}
}
calendar = calendar.slice(0, 5);
}
for (i = 0; i < calendar.length; i++) {
calendar[i] = "<tr><td>" + calendar[i].join("</td><td>") + "</td></tr>";
}
calendar = $("<table>" + calendar.join("") + "</table>").addClass("curr");
$("td:empty", calendar).addClass("nil");
if (month === new Date().getMonth()) {
$('td', calendar).filter(function () { return $(this).text() === new Date().getDate().toString(); }).addClass("today");
}
createCal.cache[year][month] = { calendar : function () { return calendar.clone() }, label : months[month] + " " + year };
return createCal.cache[year][month];
}
createCal.cache = {};
return {
init : init,
switchMonth : switchMonth,
createCal : createCal
};
};
var cal = CALENDAR();
cal.init();
});
This all works perfectly and is just provided for context. My issue is thar I am trying to implement the same feature for a weekly view (i.e. defaults to the current week, has the correct dates for that week, lists the month and year on the header, and lets you toggle through weeks. I tried using the month code as a guideline to implement the same idea for the weekly feature, but unforetunately it isn't working. I'm not sure if I need to find some new algorithm altogether, or whether the code can be modified, but I'm hoping for the latter. Let me know if you have any insight. The html for week view looks like this:
<html>
<head>
</head>
<body>
<div id="weekCal">
<div class="header">
<span class="left button" id="prev"> ⟨ </span>
<span class="month-year" id="label"> April 2017 </span>
<span class="right button" id="next"> ⟩ </span>
</div>
<table id="days">
<td>sun</td>
<td>mon</td>
<td>tue</td>
<td>wed</td>
<td>thu</td>
<td>fri</td>
<td>sat</td>
</table>
<div id="cal-frame">
<table class="curr">
<tbody>
<tr><td class="nil"></td><td class="nil"></td><td>1</td><td class="today">2</td><td>3</td><td>4</td><td>5</td></tr>
</tbody>
</table>
</div>
</div>
The Javascript I tried to derive for the week view looks like this:
$(document).ready(function(){
var WEEKLY_CALENDAR = function () {
var weekWrap, weekLlabel,
weeks = ["Week1", "Week2", "Week3", "Week4", "Week 5", "Week 6", "Week 7", "Week 8", "Week 9", "Week 10", "Week 11", "Week 12"];
In the final implementation I am assuming I will need 52 weeks, but I started with 12 as an example kind of, just to see if it worked months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
Date.prototype.getWeek = function() {
var onejan = new Date(this.getFullYear(),0,1);
var today = new Date(this.getFullYear(),this.getMonth(),this.getDate());
var dayOfYear = ((today - onejan + 86400000)/86400000);
return Math.ceil(dayOfYear/7)
};
found this getWeek function at at JavaScript Date.getWeek()?
function init(newWrap) {
weekWrap = $(newWrap || "#weekCal");
label = wrap.find("#label");
wrap.find("#prev").bind("click.calendar", function () { switchWeek(false); });
wrap.find("#next").bind("click.calendar", function () { switchWeek(true); });
label.bind("click", function () { switchWeek(null, new Date().getWeek(), new Date().getMonth(), new Date().getFullYear()); });
label.click();
}
function switchWeek(next, week, month, year) {
var curr = label.text().trim().split(" "), calendar, tempYear = parseInt(curr[1], 10);
if (!week) {
if (next) {
if (curr[0] === "week 52") {
week = 0;
} else {
week = week.indexOf(curr[0]) + 1;
}
} else {
if (curr[0] === "week 1") {
week = 11;
} else {
week = weeks.indexOf(curr[0]) - 1;
}
}
}
if (!month) {
if (next) {
if (curr[0] === "December") {
month = 0;
} else {
month = months.indexOf(curr[0]) + 1;
}
} else {
if (curr[0] === "January") {
month = 11;
} else {
month = months.indexOf(curr[0]) - 1;
}
}
}
if (!year) {
if (next && month === 0) {
year = tempYear + 1;
} else if (!next && month === 11) {
year = tempYear - 1;
} else {
year = tempYear;
}
}
calendar = createCal(year, month, week);
$("#cal-frame", weekWrap)
.find(".curr")
.removeClass("curr")
.addClass("temp")
.end()
.prepend(calendar.calendar())
.find(".temp")
.fadeOut("slow", function () { $(this).remove(); });
$('#label').text(calendar.label);
}
function createCal(year, month, week) {
var day = 1, i, j, haveDays = true,
startDay = new Date(year, month, day).getDay(),
daysInMonths = [31, (((year%4==0)&&(year%100!=0))||(year%400==0)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
calendar = [];
if (createCal.cache[year]) {
if (createCal.cache[year][week]) {
return createCal.cache[year][week];
}
}
else {
createCal.cache[year] = {};
}
i = 0;
while (haveDays) {
calendar[i] = [];
for (j = 0; j < 7; j++) {
if (i === 0) {
if (j === startDay) {
calendar[i][j] = day++;
startDay++;
}
} else if (day <= daysInMonths[month]) {
calendar[i][j] = day++;
} else {
calendar[i][j] = "";
haveDays = false;
}
if (day > daysInMonths[month]) {
haveDays = false;
}
}
i++;
}
if (calendar[5]) {
for (i = 0; i < calendar[5].length; i++) {
if (calendar[5][i] !== "") {
calendar[4][i] = "<span>" + calendar[4][i] + "</span><span>" + calendar[5][i] + "</span>";
}
}
calendar = calendar.slice(0, 5);
}
for (i = 0; i < calendar.length; i++) {
calendar[i] = "<tr><td>" + calendar[i].join("</td><td>") + "</td></tr>";
}
calendar = $("<table>" + calendar.join("") + "</table>").addClass("curr");
$("td:empty", calendar).addClass("nil");
if (month === new Date().getMonth()) {
$('td', calendar).filter(function () { return $(this).text() === new Date().getDate().toString(); }).addClass("today");
}
createCal.cache[year][week] = { calendar : function () { return calendar.clone() }, label : weeks[week] + " " + year };
return createCal.cache[year][week];
}
createCal.cache = {};
return {
init : init,
switchWeek : switchWeek,
createCal : createCal
};
};
var cal = CALENDAR();
cal.init();
});
I am fairly new to javascript and algorithms, so I'm a little lost on how to fix this. If you have any insight I'd love to hear it.