hedera-web/js/htk/field/calendar.js

288 lines
5.7 KiB
JavaScript

var transitions = require ('vn/transitions');
module.exports = new Class
({
Extends: Htk.Field
,Tag: 'htk-calendar'
,Properties:
{
restrictFunc:
{
type: Function
,set: function (x)
{
this._restrictFunc = x;
}
,get: function ()
{
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 div = this.createElement ('div');
div.className = 'month';
node.appendChild (div);
var button = this.createElement ('button');
button.className = 'previous';
button.addEventListener ('click', this.prevMonthClicked.bind (this));
div.appendChild (button);
var icon = this.createElement ('htk-icon');
icon.icon = 'go-previous',
icon.theme = 'dark';
button.appendChild (icon.node);
var monthNode = this.createElement ('span');
div.appendChild (monthNode);
var space = this.createTextNode (' ');
div.appendChild (space);
var yearNode = this.createElement ('span');
div.appendChild (yearNode);
var button = this.createElement ('button');
button.className = 'next';
button.addEventListener ('click', this.nextMonthClicked.bind (this));
div.appendChild (button);
var icon = this.createElement ('htk-icon');
icon.icon = 'go-next',
icon.theme = 'dark';
button.appendChild (icon.node);
var wrapper = this.createElement ('div');
wrapper.className = 'wrapper';
node.appendChild (wrapper);
var table = this.createElement ('table');
wrapper.appendChild (table);
this.table = table;
var thead = this.createElement ('thead');
table.appendChild (thead);
var tr = this.createElement ('tr');
tr.className = 'wdays';
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;
}
,_putFieldValue: 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);
this.emit ('pick', newDate);
this._notifyFieldChange (newDate);
}
}
,prevMonthClicked: function ()
{
if (this.month > 0)
this.month--;
else
{
this.month = 11;
this.year--;
}
this.refreshSlide ('right');
}
,nextMonthClicked: function ()
{
if (this.month < 11)
this.month++;
else
{
this.month = 0;
this.year++;
}
this.refreshSlide ('left');
}
,refreshSlide: function (way)
{
var cb = this.refresh.bind (this);
transitions.slide (this.table, way, cb);
}
});