273 lines
5.3 KiB
JavaScript
273 lines
5.3 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.setTime (cellDate.getTime () + 86400000);
|
|
}
|
|
}
|
|
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 (value)
|
|
{
|
|
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);
|
|
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 ();
|
|
}
|
|
});
|