BotanJS/botanjs/src/Astro/Blog/Components/Calendar.js
2015-08-14 21:42:25 +08:00

245 lines
5.7 KiB
JavaScript

(function(){
var ns = __namespace( "Astro.Blog.Components" );
/** @type {System.Cycle} */
var Cycle = __import( "System.Cycle" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
/** @type {Dandelion} */
var Dand = __import( "Dandelion" );
/** @type {Dandelion.IDOMElement} */
var IDOMElement = __import( "Dandelion.IDOMElement" );
/** @type {Astro.utils.Date} */
var XDate = __import( "Astro.utils.Date" );
var Calendar = function ()
{
this.stage = null;
this.calDate = null;
this.show = false;
this.caption = null;
this.calDays = false;
this.currentHandler = function( v ) {
debug.Info( "[Astro.Blog.Components.Calendar] " + v );
};
};
var bodyClick = function ( e )
{
var s = e.target.getAttribute("calObj")
if(s)
{
this.stage.style.display = "none";
this.stage.style.position = "";
this.show = false;
}
if( this.show && !this.istg.contains( e.target ) )
{
this.stage.style.display = "none";
this.stage.style.position = "";
this.show = false;
}
};
var addZero = function ( num )
{
return num < 10
? "0" + String(num)
: String(num)
;
};
Calendar.prototype.init = function()
{
this.stage = Dand.wrapc( "astx calendar" );
this.istg = IDOMElement( this.stage );
this.calDate = new Date;
IDOMElement( document.body ).addEventListener( "Click", bodyClick.bind( this ) );
var tr = Dand.wrap(null, "navbar")
, td = Dand.wrap("span")
, btn = Dand.wrap("a", null, "navbtn")
;
tr.setAttribute("style", "position: relative");
btn.onclick = function (e) { this.nextMon(); }.bind(this);
td.style.textAlign = "right";
td.style.width = "100%";
td.style.position = "absolute";
td.style.left = "0";
btn.appendChild(Dand.textNode("\u25ba"));
td.appendChild(btn);
tr.appendChild(td);
td = Dand.wrap("span");
btn = Dand.wrap("a", null, "navbtn");
btn.appendChild(Dand.textNode("\u25c4"));
btn.onclick = function (e) { this.prevMon(); }.bind(this);
td.style["float"] = "left";
td.style.position = "absolute";
td.appendChild(btn);
tr.appendChild(td);
caption = Dand.wrap("span", null, "calDate");
caption.style.width = "100%";
caption.appendChild(
Dand.textNode(
XDate.MONTH[this.calDate.getMonth()] + ", " + this.calDate.getFullYear()
)
);
tr.appendChild(caption);
this.stage.appendChild(tr);
this.stage.onselectstart = function() { return false;};
return this.stage;
};
Calendar.prototype.pop = function ( dateObj, handler )
{
if( typeof( dateObj ) == "string" )
{
var p = dateObj.split(",");
if ( p.length == 3 )
dateObj = new Date( p[2], p[1] - 1, p[0] );
}
this.draw( dateObj, handler );
this.show = false;
this.stage.style.display = "block";
Cycle.next( function (){ this.show = true; }.bind(this) );
};
Calendar.prototype.draw = function (dateObj, handler)
{
if(!dateObj)
dateObj = new Date;
this.calDate = dateObj;
var mon = dateObj.getMonth()
, yr = dateObj.getFullYear()
, j = dateObj.getDay()
, dt = dateObj.getDate()
, thisDate = new Date
, thisYear = thisDate.getFullYear()
, thisMonth = thisDate.getMonth()
, thisDate = thisDate.getDate()
, thisDate = Number(String(thisYear) + addZero(thisMonth) + addZero(thisDate))
, currHead = String(yr) + addZero(mon)
, currDate;
( typeof handler == "function" ) && ( this.currentHandler = handler );
caption.innerHTML = XDate.MONTH[this.calDate.getMonth()] + ", " + this.calDate.getFullYear();
if(this.calDays)
this.calDays.parentElement.removeChild(this.calDays);
this.calDays = Dand.wrap(null, "calDays");
var days = (mon == 1) ? (yr % 4 == 0 ? 29: 28) : XDate.CAP_MONTHS[mon] ? 30 : 31;
for (var i = 0; i < days; i ++)
{
if(j < 0)
j = 6;
if(dt - i == 1)
break;
j --;
}
var tr = Dand.wrap(), td;
for(i = 0; i < 7; i ++)
{
td = Dand.wrap("span");
td.appendChild( Dand.textNode( XDate.DAY_ABBR[i] ) );
tr.appendChild(td);
}
this.calDays.appendChild(tr);
tr = Dand.wrap();
for(i = 0; i < j; i ++)
{
td = Dand.wrap("span");
td.style.background = "none";
tr.appendChild(td);
}
i = 0;
while( i ++ < days )
{
currDate = Number(currHead + addZero(i));
if(j > 6)
{
j = 0;
this.calDays.appendChild(tr);
tr = Dand.wrap();
}
td = Dand.wrap( "span" );
td.setAttribute( "value", i + "," + (mon + 1) + "," + yr );
td.setAttribute( "onmouseover", "className=\"onhover\";" );
td.setAttribute( "onmouseout", "className=\"toNorm\";" );
// Unique identifier for body click
// to test whether choice is chosen
td.setAttribute("calObj", "1");
td.onclick = function ( e )
{
this.currentHandler( e.target.getAttribute("value") );
}.bind(this);
if(thisDate < currDate)
{
td.setAttribute("id", "notyet");
}
else if(thisDate > currDate)
{
td.setAttribute("id", "norec");
/*
if(!( book[yr] && book[yr][mon + 1] && book[yr][mon + 1][i] )) {
td.setAttribute("id", "norec");
} else if(book[yr][mon + 1][i][1]) {
td.setAttribute("id", "notfin");
}
*/
}
else if(currDate == thisDate)
{
td.setAttribute("id", "today");
currlabel = td;
}
td.appendChild(Dand.textNode(i));
tr.appendChild(td);
j ++;
}
if(j) this.calDays.appendChild(tr);
this.stage.appendChild(this.calDays);
};
Calendar.prototype.prevMon = function () {
this.draw( this.calDate = new Date( this.calDate.getFullYear(), this.calDate.getMonth() - 1 ) );
};
Calendar.prototype.nextMon = function () {
this.draw( this.calDate = new Date( this.calDate.getFullYear(), this.calDate.getMonth() + 1 ) );
};
ns[ NS_EXPORT ]( EX_CLASS, "Calendar", Calendar );
})();