cs142/project3/DatePicker.ts

115 lines
3.8 KiB
TypeScript
Raw Normal View History

2020-08-01 22:26:11 +00:00
"use strict";
// The constructor takes an argument consisting of the id attribute for an existing div and a date selection callback function.
// When a date is selected the callback function should be called with the id argument and an object containing the properties month, day,
// year with the number encoding of the date (e.g. {month: 1, day: 30, year: 2016} is the encoding of January 30, 2016).
class DatePicker {
id: string;
callback: Function;
date: Date;
constructor(id: string, callback: Function) {
this.id = id;
this.callback = callback;
}
render(date: Date) {
date.setDate(1);
this.date = date;
// do controls
let controlbox = <HTMLDivElement>document.createElement("DIV");
controlbox.id = this.id + "controlbox";
controlbox.className = "controlbox";
let prev = <HTMLParagraphElement>document.createElement("P");
prev.className = "prev";
prev.innerText = "<";
let prevf = this.prev.bind(this);
prev.onclick = prevf;
let ym = date.getFullYear() + "/" + (date.getMonth() + 1);
let ymElement = <HTMLParagraphElement>document.createElement("P");
ymElement.innerText = ym;
let next = <HTMLParagraphElement>document.createElement("P");
next.innerText = ">";
next.className = "next";
let nextf = this.next.bind(this);
next.onclick = nextf;
controlbox.appendChild(prev);
controlbox.appendChild(ymElement);
controlbox.appendChild(next);
// create table
let offset = date.getDay();
let dayMultiplier = 86400000; // miliseconds in a day
let startDate = date.valueOf() - offset * dayMultiplier;
let daysDisplayed: Array<Date> = [];
for (let i = 0; i < 35; i++) {
daysDisplayed.push(new Date(startDate + i * dayMultiplier));
}
// chicking if last row is needed
if (daysDisplayed[daysDisplayed.length - 1].getDate() === 7) {
for (let i = 0; i < 7; i++) {
daysDisplayed.pop();
}
}
let monthTable: HTMLTableElement = <HTMLTableElement>(
document.createElement("TABLE")
);
monthTable.id = this.id;
// insert days of the month
let weekdays = ["Su", "Mo", "Th", "We", "Th", "Fr", "Sa"];
let head = monthTable.createTHead();
let headrow = head.insertRow();
for (let i = 0; i < 7; i++) {
let temp = headrow.insertCell(i);
temp.innerHTML = weekdays[i];
}
// create actual table filled with cells
let body = monthTable.createTBody();
for (let week = 0; week < daysDisplayed.length / 7; week++) {
let weekrow = body.insertRow();
for (let day = 0; day < 7; day++) {
let dayCell = weekrow.insertCell(day);
dayCell.id = daysDisplayed[day + week * 7].toDateString();
dayCell.innerHTML = String(daysDisplayed[day + week * 7].getDate());
// dirty, dirty hack
let bday = daysDisplayed[day + week * 7];
let bday_args = {day : bday.getDate(), month : bday.getMonth(), year : bday.getFullYear()};
let args = [this.callback, this.id, bday_args];
let anon_cb = function(){
this[0](this[1], this[2]);
}.bind(args);
dayCell.onclick = anon_cb;
}
}
// select the div element
let element = document.getElementById(this.id);
element.replaceWith(monthTable);
let parent = monthTable.parentNode;
parent.insertBefore(controlbox, monthTable);
}
next() {
let newDate = new Date(this.date);
newDate.setMonth(newDate.getMonth() + 1);
let old_control = document.getElementById(this.id + "controlbox");
old_control.parentNode.removeChild(old_control);
this.render(newDate);
}
prev() {
let newDate = new Date(this.date);
let old_control = document.getElementById(this.id + "controlbox");
old_control.parentNode.removeChild(old_control);
newDate.setMonth(newDate.getMonth() - 1);
this.render(newDate);
}
}