259 lines
5.5 KiB
JavaScript
259 lines
5.5 KiB
JavaScript
|
|
module.exports = new Class({
|
|
Extends: Htk.Field
|
|
,Tag: 'htk-calendar'
|
|
,Properties:
|
|
{
|
|
restrictFunc:
|
|
{
|
|
type: Function
|
|
,set: function(x) {
|
|
this._restrictFunc = x;
|
|
}
|
|
,get: function(x) {
|
|
return this._restrictFunc;
|
|
}
|
|
}
|
|
}
|
|
|
|
,cells: []
|
|
,selectedCell: -1
|
|
,year: null
|
|
,month: null
|
|
|
|
,render: function() {
|
|
var len = Vn.Date.WDays.length;
|
|
|
|
var node = this.createRoot('div');
|
|
node.className = 'htk-calendar';
|
|
|
|
var table = this.createElement('table');
|
|
this.node.appendChild(table);
|
|
|
|
var colgroup = this.createElement('colgroup');
|
|
table.appendChild(colgroup);
|
|
|
|
for (var i = 0; i < len; i++)
|
|
colgroup.appendChild(this.createElement('col'));
|
|
|
|
var thead = this.createElement('thead');
|
|
table.appendChild(thead);
|
|
|
|
var tr = this.createElement('tr');
|
|
thead.appendChild(tr);
|
|
|
|
var th = this.createElement('th');
|
|
th.appendChild(this.createTextNode('<'));
|
|
th.className = 'button';
|
|
th.addEventListener('click', this.prevMonthClicked.bind(this));
|
|
tr.appendChild(th);
|
|
|
|
var th = this.createElement('th');
|
|
th.colSpan = 5;
|
|
tr.appendChild(th);
|
|
|
|
var monthNode = this.createElement('span');
|
|
th.appendChild(monthNode);
|
|
|
|
var space = this.createTextNode(' ');
|
|
th.appendChild(space);
|
|
|
|
var yearNode = this.createElement('span');
|
|
th.appendChild(yearNode);
|
|
|
|
var th = this.createElement('th');
|
|
th.appendChild(this.createTextNode('>'));
|
|
th.className = 'button';
|
|
th.addEventListener('click', this.nextMonthClicked.bind(this));
|
|
tr.appendChild(th);
|
|
|
|
var tr = this.createElement('tr');
|
|
thead.appendChild(tr);
|
|
|
|
for (var i = 1; i <= len; i++) {
|
|
var th = this.createElement('th');
|
|
tr.appendChild(th);
|
|
|
|
var weekday = _(Vn.Date.AbrWDays [i%len]);
|
|
th.appendChild(this.createTextNode(weekday));
|
|
}
|
|
|
|
var tbody = this.createElement('tbody');
|
|
table.appendChild(tbody);
|
|
|
|
for (var i = 0; i < 6; i++) {
|
|
var tr = this.createElement('tr');
|
|
tbody.appendChild(tr);
|
|
|
|
for (var j = 0; j < len; j++) {
|
|
var td = this.createElement('td');
|
|
td.addEventListener('click', this.dayClicked.bind(this, td, i*len+j));
|
|
tr.appendChild(td);
|
|
|
|
var div = this.createElement('div');
|
|
td.appendChild(div);
|
|
|
|
this.cells.push({
|
|
node: div,
|
|
enabled: false,
|
|
day: -1
|
|
});
|
|
}
|
|
}
|
|
|
|
this.monthNode = monthNode;
|
|
this.yearNode = yearNode;
|
|
this.goToCurrentMonth();
|
|
}
|
|
|
|
,getMonthDays: function() {
|
|
if (this.month > 6)
|
|
return (this.month % 2 != 0) ? 31 : 30;
|
|
else if (this.month != 1)
|
|
return (this.month % 2 != 1) ? 31 : 30;
|
|
else
|
|
return (this.year % 4 != 0) ? 28 : 29;
|
|
}
|
|
|
|
,goToMonth: function(year, month) {
|
|
if (year)
|
|
this.year = year;
|
|
if (!isNaN(month))
|
|
this.month = month;
|
|
|
|
this.refresh();
|
|
}
|
|
|
|
,goToSelectedMonth: function() {
|
|
var date = this._value;
|
|
|
|
if (date instanceof Date)
|
|
this.goToMonth(date.getFullYear(), date.getMonth());
|
|
else
|
|
this.goToCurrentMonth();
|
|
}
|
|
|
|
,goToCurrentMonth: function() {
|
|
var date = new Date();
|
|
this.goToMonth(date.getFullYear(), date.getMonth());
|
|
}
|
|
|
|
,refresh: function() {
|
|
Vn.Node.setText(this.yearNode, this.year);
|
|
Vn.Node.setText(this.monthNode, _(Vn.Date.Months[this.month]));
|
|
|
|
var day = 1;
|
|
var cellDate = new Date(this.year, this.month, 1);
|
|
|
|
var weekDay = cellDate.getDay();
|
|
var firstWeekDay = (weekDay != 0) ? weekDay - 1 : 6;
|
|
var monthDays = this.getMonthDays();
|
|
|
|
for (var i = 0; i < this.cells.length; i++) {
|
|
var cell = this.cells[i];
|
|
|
|
if (firstWeekDay <= i && day <= monthDays) {
|
|
Vn.Node.setText(cell.node, day);
|
|
cell.enabled = true;
|
|
cell.day = day++;
|
|
|
|
if (this._restrictFunc) {
|
|
cell.enabled = this._restrictFunc(cellDate);
|
|
cellDate.setDate(cellDate.getDate() + 1);
|
|
}
|
|
} else {
|
|
Vn.Node.removeChilds(cell.node);
|
|
cell.enabled = false;
|
|
cell.day = -1;
|
|
}
|
|
|
|
cell.node.className = cell.enabled ? 'enabled' : 'disabled';
|
|
}
|
|
|
|
// Marks the current day
|
|
|
|
var today = new Date();
|
|
|
|
if (this.year == today.getFullYear()
|
|
&& this.month == today.getMonth()) {
|
|
var cellIndex = (firstWeekDay + today.getDate()) - 1;
|
|
Vn.Node.addClass(this.cells[cellIndex].node, 'today');
|
|
}
|
|
|
|
// Marks the selected day
|
|
|
|
var date = this._value;
|
|
|
|
if (date instanceof Date
|
|
&& this.year == date.getFullYear()
|
|
&& this.month == date.getMonth())
|
|
this.selectCell((firstWeekDay + date.getDate()) - 1);
|
|
else
|
|
this.selectCell(-1);
|
|
}
|
|
|
|
,selectCell: function(cellIndex) {
|
|
if (this.selectedCell != -1) {
|
|
var node = this.cells[this.selectedCell].node;
|
|
Vn.Node.removeClass(node, 'selected');
|
|
}
|
|
if (cellIndex != -1) {
|
|
var node = this.cells[cellIndex].node;
|
|
Vn.Node.addClass(node, 'selected');
|
|
}
|
|
|
|
this.selectedCell = cellIndex;
|
|
}
|
|
|
|
,putValue: function() {
|
|
this.goToSelectedMonth();
|
|
}
|
|
|
|
,dayClicked: function(td, cellIndex) {
|
|
var cell = this.cells[cellIndex];
|
|
|
|
if (cell.enabled) {
|
|
this.selectCell(cellIndex);
|
|
var newDate = new Date(this.year, this.month, cell.day);
|
|
|
|
if (this.value) {
|
|
var orgDate = this.value instanceof Date
|
|
? this.value
|
|
: new Date(this.value);
|
|
|
|
if (!isNaN(orgDate.getTime()))
|
|
newDate.setHours(
|
|
orgDate.getHours(),
|
|
orgDate.getMinutes(),
|
|
orgDate.getSeconds(),
|
|
orgDate.getMilliseconds()
|
|
);
|
|
}
|
|
|
|
this.valueChanged(newDate);
|
|
}
|
|
}
|
|
|
|
,prevMonthClicked: function() {
|
|
if (this.month > 0)
|
|
this.month--;
|
|
else {
|
|
this.month = 11;
|
|
this.year--;
|
|
}
|
|
|
|
this.refresh();
|
|
}
|
|
|
|
,nextMonthClicked: function() {
|
|
if (this.month < 11)
|
|
this.month++;
|
|
else {
|
|
this.month = 0;
|
|
this.year++;
|
|
}
|
|
|
|
this.refresh();
|
|
}
|
|
});
|