summaryrefslogtreecommitdiff
path: root/framework/Web/Javascripts/base/datepicker.js
diff options
context:
space:
mode:
Diffstat (limited to 'framework/Web/Javascripts/base/datepicker.js')
-rw-r--r--framework/Web/Javascripts/base/datepicker.js928
1 files changed, 928 insertions, 0 deletions
diff --git a/framework/Web/Javascripts/base/datepicker.js b/framework/Web/Javascripts/base/datepicker.js
new file mode 100644
index 00000000..046a0a4b
--- /dev/null
+++ b/framework/Web/Javascripts/base/datepicker.js
@@ -0,0 +1,928 @@
+Prado.Calendar = Class.create();
+
+Prado.Calendar.Util = Class.create();
+
+Object.extend(Prado.Calendar.Util,
+{
+ // utility function to pad a number to a given width
+ pad : function(number, X)
+ {
+ X = (!X ? 2 : X);
+ number = ""+number;
+ while (number.length < X)
+ number = "0" + number;
+ return number;
+ },
+
+ //allow for deprecated formats
+ FormatDate : function(date, format)
+ {
+ if(!isObject(date)) return "";
+ if(format.indexOf("%") > -1)
+ {
+ alert('Please use the new SimpleDateFormat pattern, e.g. yyyy-MM-dd');
+ return this.FormatDateDepr(date,format);
+ }
+ else
+ {
+ return this.SimpleFormatDate(date, format);
+ }
+ },
+
+ //allow for deprecated format
+ ParseDate : function(value, format)
+ {
+ val=String(value);
+ format=String(format);
+
+ if(val.length <= 0) return null;
+
+ if(format.length <= 0) return new Date(value);
+
+ if(format.indexOf("%") > -1)
+ return this.ParseDateDepr(value, format);
+ else
+ return this.SimpleParseDate(value, format);
+ },
+
+ //deprecated format
+ FormatDateDepr : function(date, str)
+ {
+ var m = date.getMonth();
+ var d = date.getDate();
+ var y = date.getFullYear();
+
+ var s = {};
+
+ s["%d"] = this.pad(d); // the day of the month (range 01 to 31)
+ s["%e"] = d; // the day of the month (range 1 to 31)
+ s["%m"] = this.pad(m+1);
+ s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
+ s["%Y"] = y; // year with the century
+
+ var re = /%./g;
+
+ var a = str.match(re);
+ for (var i = 0; i < a.length; i++)
+ {
+ var tmp = s[a[i]];
+ if (tmp)
+ {
+ re = new RegExp(a[i], 'g');
+ str = str.replace(re, tmp);
+ }
+ }
+
+ return str;
+ },
+
+ //deprecated format parser
+ ParseDateDepr : function(value, format)
+ {
+ var y = 0;
+ var m = -1;
+ var d = 0;
+ var a = value.split(/\W+/);
+ var b = format.match(/%./g);
+ var i = 0, j = 0;
+ var hr = 0;
+ var min = 0;
+ for (i = 0; i < a.length; ++i) {
+ if (!a[i])
+ continue;
+ switch (b[i]) {
+ case "%d":
+ case "%e":
+ d = parseInt(a[i], 10);
+ break;
+
+ case "%m":
+ m = parseInt(a[i], 10) - 1;
+ break;
+
+ case "%Y":
+ case "%y":
+ y = parseInt(a[i], 10);
+ (y < 100) && (y += (y > 29) ? 1900 : 2000);
+ break;
+
+ case "%H":
+ case "%I":
+ case "%k":
+ case "%l":
+ hr = parseInt(a[i], 10);
+ break;
+
+ case "%P":
+ case "%p":
+ if (/pm/i.test(a[i]) && hr < 12)
+ hr += 12;
+ break;
+
+ case "%M":
+ min = parseInt(a[i], 10);
+ break;
+ }
+ }
+ if (y != 0 && m != -1 && d != 0)
+ {
+ var date = new Date(y, m, d, hr, min, 0);
+ return (isObject(date)
+ && y == date.getFullYear()
+ && m == date.getMonth()
+ && d == date.getDate()) ? date : null;
+ }
+ return null;
+ },
+
+ SimpleFormatDate : function(date, format)
+ {
+ if(!isObject(date)) return "";
+ var bits = new Array();
+ bits['d'] = date.getDate();
+ bits['dd'] = this.pad(date.getDate(),2);
+
+ bits['M'] = date.getMonth()+1;
+ bits['MM'] = this.pad(date.getMonth()+1,2);
+
+ var yearStr = "" + date.getFullYear();
+ yearStr = (yearStr.length == 2) ? '19' + yearStr: yearStr;
+ bits['yyyy'] = yearStr;
+ bits['yy'] = bits['yyyy'].toString().substr(2,2);
+
+ // do some funky regexs to replace the format string
+ // with the real values
+ var frm = new String(format);
+ for (var sect in bits)
+ {
+ var reg = new RegExp("\\b"+sect+"\\b" ,"g");
+ frm = frm.replace(reg, bits[sect]);
+ }
+ return frm;
+ },
+
+ SimpleParseDate : function(value, format)
+ {
+ val=String(value);
+ format=String(format);
+
+ if(val.length <= 0) return null;
+
+ if(format.length <= 0) return new Date(value);
+
+ var isInteger = function (val)
+ {
+ var digits="1234567890";
+ for (var i=0; i < val.length; i++)
+ {
+ if (digits.indexOf(val.charAt(i))==-1) { return false; }
+ }
+ return true;
+ };
+
+ var getInt = function(str,i,minlength,maxlength)
+ {
+ for (var x=maxlength; x>=minlength; x--)
+ {
+ var token=str.substring(i,i+x);
+ if (token.length < minlength) { return null; }
+ if (isInteger(token)) { return token; }
+ }
+ return null;
+ };
+
+ var i_val=0;
+ var i_format=0;
+ var c="";
+ var token="";
+ var token2="";
+ var x,y;
+ var now=new Date();
+ var year=now.getFullYear();
+ var month=now.getMonth()+1;
+ var date=1;
+
+ while (i_format < format.length)
+ {
+ // Get next token from format string
+ c=format.charAt(i_format);
+ token="";
+ while ((format.charAt(i_format)==c) && (i_format < format.length))
+ {
+ token += format.charAt(i_format++);
+ }
+
+ // Extract contents of value based on format token
+ if (token=="yyyy" || token=="yy" || token=="y")
+ {
+ if (token=="yyyy") { x=4;y=4; }
+ if (token=="yy") { x=2;y=2; }
+ if (token=="y") { x=2;y=4; }
+ year=getInt(val,i_val,x,y);
+ if (year==null) { return null; }
+ i_val += year.length;
+ if (year.length==2)
+ {
+ if (year > 70) { year=1900+(year-0); }
+ else { year=2000+(year-0); }
+ }
+ }
+
+ else if (token=="MM"||token=="M")
+ {
+ month=getInt(val,i_val,token.length,2);
+ if(month==null||(month<1)||(month>12)){return null;}
+ i_val+=month.length;
+ }
+ else if (token=="dd"||token=="d")
+ {
+ date=getInt(val,i_val,token.length,2);
+ if(date==null||(date<1)||(date>31)){return null;}
+ i_val+=date.length;
+ }
+ else
+ {
+ if (val.substring(i_val,i_val+token.length)!=token) {return null;}
+ else {i_val+=token.length;}
+ }
+ }
+
+ // If there are any trailing characters left in the value, it doesn't match
+ if (i_val != val.length) { return null; }
+
+ // Is date valid for month?
+ if (month==2)
+ {
+ // Check for leap year
+ if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
+ if (date > 29){ return null; }
+ }
+ else { if (date > 28) { return null; } }
+ }
+
+ if ((month==4)||(month==6)||(month==9)||(month==11))
+ {
+ if (date > 30) { return null; }
+ }
+
+ var newdate=new Date(year,month-1,date, 0, 0, 0);
+ return newdate;
+ },
+
+ IsLeapYear : function (year)
+ {
+ return ((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));
+ },
+
+ yearLength : function(year)
+ {
+ if (this.isLeapYear(year))
+ return 366;
+ else
+ return 365;
+ },
+
+ dayOfYear : function(date)
+ {
+ var a = this.isLeapYear(date.getFullYear()) ?
+ Calendar.LEAP_NUM_DAYS : Calendar.NUM_DAYS;
+ return a[date.getMonth()] + date.getDate();
+ },
+ ISODate : function(date)
+ {
+ var y = date.getFullYear();
+ var m = this.pad(date.getMonth() + 1);
+ var d = this.pad(date.getDate());
+ return String(y) + String(m) + String(d);
+ },
+
+ browser : function()
+ {
+ var info = { Version : "1.0" };
+ var is_major = parseInt( navigator.appVersion );
+ info.nver = is_major;
+ info.ver = navigator.appVersion;
+ info.agent = navigator.userAgent;
+ info.dom = document.getElementById ? 1 : 0;
+ info.opera = window.opera ? 1 : 0;
+ info.ie5 = ( info.ver.indexOf( "MSIE 5" ) > -1 && info.dom && !info.opera ) ? 1 : 0;
+ info.ie6 = ( info.ver.indexOf( "MSIE 6" ) > -1 && info.dom && !info.opera ) ? 1 : 0;
+ info.ie4 = ( document.all && !info.dom && !info.opera ) ? 1 : 0;
+ info.ie = info.ie4 || info.ie5 || info.ie6;
+ info.mac = info.agent.indexOf( "Mac" ) > -1;
+ info.ns6 = ( info.dom && parseInt( info.ver ) >= 5 ) ? 1 : 0;
+ info.ie3 = ( info.ver.indexOf( "MSIE" ) && ( is_major < 4 ) );
+ info.hotjava = ( info.agent.toLowerCase().indexOf( 'hotjava' ) != -1 ) ? 1 : 0;
+ info.ns4 = ( document.layers && !info.dom && !info.hotjava ) ? 1 : 0;
+ info.bw = ( info.ie6 || info.ie5 || info.ie4 || info.ns4 || info.ns6 || info.opera );
+ info.ver3 = ( info.hotjava || info.ie3 );
+ info.opera7 = ( ( info.agent.toLowerCase().indexOf( 'opera 7' ) > -1 ) || ( info.agent.toLowerCase().indexOf( 'opera/7' ) > -1 ) );
+ info.operaOld = info.opera && !info.opera7;
+ return info;
+ },
+
+ ImportCss : function(doc, css_file)
+ {
+ if (this.browser().ie)
+ var styleSheet = doc.createStyleSheet(css_file);
+ else
+ {
+ var elm = doc.createElement("link");
+
+ elm.rel = "stylesheet";
+ elm.href = css_file;
+
+ if (headArr = doc.getElementsByTagName("head"))
+ headArr[0].appendChild(elm);
+ }
+ }
+});
+
+Object.extend(Prado.Calendar,
+{
+ // Accumulated days per month, for normal and for leap years.
+ // Used in week number calculations.
+ NUM_DAYS : [0,31,59,90,120,151,181,212,243,273,304,334],
+ LEAP_NUM_DAYS : [0,31,60,91,121,152,182,213,244,274,305,335]
+});
+
+Prado.Calendar.prototype =
+{
+ monthNames : [ "January", "February", "March", "April",
+ "May", "June", "July", "August",
+ "September", "October", "November", "December"
+ ],
+
+ shortWeekDayNames : ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
+
+ format : "yyyy-MM-dd",
+
+ css : "calendar_system.css",
+
+ initialize : function(control, attr)
+ {
+ this.attr = attr || [];
+ this.control = $(control);
+ this.dateSlot = new Array(42);
+ this.weekSlot = new Array(6);
+ this.firstDayOfWeek = 1;
+ this.minimalDaysInFirstWeek = 4;
+ this.currentDate = new Date();
+ this.selectedDate = null;
+ this.className = "Prado_Calendar";
+
+ //which element to trigger to show the calendar
+ this.trigger = this.attr.trigger ? $(this.attr.trigger) : this.control;
+ Event.observe(this.trigger, "click", this.show.bind(this));
+
+ Prado.Calendar.Util.ImportCss(document, this.css);
+
+ if(this.attr.format) this.format = this.attr.format;
+
+ //create it
+ this.create();
+ this.hookEvents();
+ },
+
+ create : function()
+ {
+ var div;
+ var table;
+ var tbody;
+ var tr;
+ var td;
+
+ // Create the top-level div element
+ this._calDiv = document.createElement("div");
+ this._calDiv.className = this.className;
+ this._calDiv.style.display = "none";
+
+ // header div
+ div = document.createElement("div");
+ div.className = "calendarHeader";
+ this._calDiv.appendChild(div);
+
+ table = document.createElement("table");
+ table.style.cellSpacing = 0;
+ div.appendChild(table);
+
+ tbody = document.createElement("tbody");
+ table.appendChild(tbody);
+
+ tr = document.createElement("tr");
+ tbody.appendChild(tr);
+
+ // Previous Month Button
+ td = document.createElement("td");
+ td.className = "prevMonthButton";
+ this._previousMonth = document.createElement("button");
+ this._previousMonth.appendChild(document.createTextNode("<<"));
+ td.appendChild(this._previousMonth);
+ tr.appendChild(td);
+
+
+
+ //
+ // Create the month drop down
+ //
+ td = document.createElement("td");
+ td.className = "labelContainer";
+ tr.appendChild(td);
+ this._monthSelect = document.createElement("select");
+ for (var i = 0 ; i < this.monthNames.length ; i++) {
+ var opt = document.createElement("option");
+ opt.innerHTML = this.monthNames[i];
+ opt.value = i;
+ if (i == this.currentDate.getMonth()) {
+ opt.selected = true;
+ }
+ this._monthSelect.appendChild(opt);
+ }
+ td.appendChild(this._monthSelect);
+
+
+ //
+ // Create the year drop down
+ //
+ td = document.createElement("td");
+ td.className = "labelContainer";
+ tr.appendChild(td);
+ this._yearSelect = document.createElement("select");
+ for(var i=1920; i < 2050; ++i) {
+ var opt = document.createElement("option");
+ opt.innerHTML = i;
+ opt.value = i;
+ if (i == this.currentDate.getFullYear()) {
+ opt.selected = false;
+ }
+ this._yearSelect.appendChild(opt);
+ }
+ td.appendChild(this._yearSelect);
+
+
+ td = document.createElement("td");
+ td.className = "nextMonthButton";
+ this._nextMonth = document.createElement("button");
+ this._nextMonth.appendChild(document.createTextNode(">>"));
+ td.appendChild(this._nextMonth);
+ tr.appendChild(td);
+
+ // Calendar body
+ div = document.createElement("div");
+ div.className = "calendarBody";
+ this._calDiv.appendChild(div);
+ this._table = div;
+
+ // Create the inside of calendar body
+
+ var text;
+ table = document.createElement("table");
+ //table.style.width="100%";
+ table.className = "grid";
+
+ div.appendChild(table);
+ var thead = document.createElement("thead");
+ table.appendChild(thead);
+ tr = document.createElement("tr");
+ thead.appendChild(tr);
+
+ for(i=0; i < 7; ++i) {
+ td = document.createElement("th");
+ text = document.createTextNode(this.shortWeekDayNames[(i+this.firstDayOfWeek)%7]);
+ td.appendChild(text);
+ td.className = "weekDayHead";
+ tr.appendChild(td);
+ }
+
+ // Date grid
+ tbody = document.createElement("tbody");
+ table.appendChild(tbody);
+
+ for(week=0; week<6; ++week) {
+ tr = document.createElement("tr");
+ tbody.appendChild(tr);
+
+ for(day=0; day<7; ++day) {
+ td = document.createElement("td");
+ td.className = "calendarDate";
+ text = document.createTextNode(String.fromCharCode(160));
+ td.appendChild(text);
+
+ tr.appendChild(td);
+ var tmp = new Object();
+ tmp.tag = "DATE";
+ tmp.value = -1;
+ tmp.data = text;
+ this.dateSlot[(week*7)+day] = tmp;
+
+ Event.observe(td, "mouseover", this.hover.bind(this));
+ Event.observe(td, "mouseout", this.hover.bind(this));
+
+ }
+ }
+
+ // Calendar Footer
+ div = document.createElement("div");
+ div.className = "calendarFooter";
+ this._calDiv.appendChild(div);
+
+ table = document.createElement("table");
+ //table.style.width="100%";
+ table.className = "footerTable";
+ //table.cellSpacing = 0;
+ div.appendChild(table);
+
+ tbody = document.createElement("tbody");
+ table.appendChild(tbody);
+
+ tr = document.createElement("tr");
+ tbody.appendChild(tr);
+
+ //
+ // The TODAY button
+ //
+ td = document.createElement("td");
+ td.className = "todayButton";
+ this._todayButton = document.createElement("button");
+ var today = new Date();
+ var buttonText = today.getDate() + " " + this.monthNames[today.getMonth()] + ", " + today.getFullYear();
+ this._todayButton.appendChild(document.createTextNode(buttonText));
+ td.appendChild(this._todayButton);
+ tr.appendChild(td);
+
+ //
+ // The CLEAR button
+ //
+ td = document.createElement("td");
+ td.className = "clearButton";
+ this._clearButton = document.createElement("button");
+ var today = new Date();
+ buttonText = "Clear";
+ this._clearButton.appendChild(document.createTextNode(buttonText));
+ td.appendChild(this._clearButton);
+ tr.appendChild(td);
+
+ document.body.appendChild(this._calDiv);
+
+ this.update();
+ this.updateHeader();
+
+ return this._calDiv;
+ },
+
+ hookEvents : function()
+ {
+ // IE55+ extension
+ this._previousMonth.hideFocus = true;
+ this._nextMonth.hideFocus = true;
+ this._todayButton.hideFocus = true;
+ // end IE55+ extension
+
+ // hook up events
+ Event.observe(this._previousMonth, "click", this.prevMonth.bind(this));
+ Event.observe(this._nextMonth, "click", this.nextMonth.bind(this));
+ Event.observe(this._todayButton, "click", this.selectToday.bind(this));
+ Event.observe(this._clearButton, "click", this.clearSelection.bind(this));
+
+ Event.observe(this._monthSelect, "change", this.monthSelect.bind(this));
+ Event.observe(this._yearSelect, "change", this.yearSelect.bind(this));
+
+ // ie6 extension
+ Event.observe(this._calDiv, "mousewheel", this.mouseWheelChange.bind(this));
+
+ Event.observe(this._table, "click", this.selectDate.bind(this));
+
+ Event.observe(this._calDiv,"keydown", this.keyPressed.bind(this));
+
+ /*
+ this._calDiv.onkeydown = function (e) {
+ if (e == null) e = document.parentWindow.event;
+ var kc = e.keyCode != null ? e.keyCode : e.charCode;
+
+ if(kc == 13) {
+ var d = new Date(dp._currentDate).valueOf();
+ dp.setSelectedDate(d);
+
+ if (!dp._alwaysVisible && dp._hideOnSelect) {
+ dp.hide();
+ }
+ return false;
+ }
+
+
+ if (kc < 37 || kc > 40) return true;
+
+ var d = new Date(dp._currentDate).valueOf();
+ if (kc == 37) // left
+ d -= 24 * 60 * 60 * 1000;
+ else if (kc == 39) // right
+ d += 24 * 60 * 60 * 1000;
+ else if (kc == 38) // up
+ d -= 7 * 24 * 60 * 60 * 1000;
+ else if (kc == 40) // down
+ d += 7 * 24 * 60 * 60 * 1000;
+
+ dp.setCurrentDate(new Date(d));
+ return false;
+ }*/
+
+
+ },
+
+ keyPressed : function(ev)
+ {
+ if (!ev) ev = document.parentWindow.event;
+ var kc = ev.keyCode != null ? ev.keyCode : ev.charCode;
+
+ if(kc = Event.KEY_RETURN)
+ {
+ //var d = new Date(this.currentDate);
+ this.setSelectedDate(this.currentDate);
+ this.hide();
+ return false;
+ }
+
+ if(kc < 37 || kc > 40) return true;
+
+ var d = new Date(this.currentDate).valueOf();
+ if(kc == Event.KEY_LEFT)
+ d -= 86400000; //-1 day
+ else if (kc == Event.KEY_RIGHT)
+ d += 86400000; //+1 day
+ else if (kc == Event.KEY_UP)
+ d -= 604800000; // -7 days
+ else if (kc == Event.KEY_DOWN)
+ d += 604800000; // +7 days
+ this.setCurrentDate(new Date(d));
+ return false;
+ },
+
+ selectDate : function(ev)
+ {
+ var el = Event.element(ev);
+ while (el.nodeType != 1)
+ el = el.parentNode;
+
+ while (el != null && el.tagName && el.tagName.toLowerCase() != "td")
+ el = el.parentNode;
+
+ // if no td found, return
+ if (el == null || el.tagName == null || el.tagName.toLowerCase() != "td")
+ return;
+
+ var d = new Date(this.currentDate);
+ var n = Number(el.firstChild.data);
+ if (isNaN(n) || n <= 0 || n == null)
+ return;
+
+ d.setDate(n);
+ this.setSelectedDate(d);
+ this.hide();
+ },
+
+ selectToday : function()
+ {
+ this.setSelectedDate(new Date());
+ this.hide();
+ },
+
+ clearSelection : function()
+ {
+ this.selectedDate = null;
+ if (isFunction(this.onchange))
+ this.onchange();
+ this.hide();
+ },
+
+ monthSelect : function(ev)
+ {
+ this.setMonth(Form.Element.getValue(Event.element(ev)));
+ },
+
+ yearSelect : function(ev)
+ {
+ this.setYear(Form.Element.getValue(Event.element(ev)));
+ },
+
+ // ie6 extension
+ mouseWheelChange : function (e)
+ {
+ if (e == null) e = document.parentWindow.event;
+ var n = - e.wheelDelta / 120;
+ var d = new Date(this.currentDate);
+ var m = this.getMonth() + n;
+ this.setMonth(m);
+ this.setCurrentDate(d);
+
+ return false;
+ },
+
+ onchange : function()
+ {
+ this.control.value = this.formatDate();
+ },
+
+ formatDate : function()
+ {
+ return Prado.Calendar.Util.FormatDate(this.selectedDate, this.format);
+ },
+
+ setCurrentDate : function(date)
+ {
+ if (date == null)
+ return;
+
+ // if string or number create a Date object
+ if (isString(date) || isNumber(date))
+ date = new Date(date);
+
+ // do not update if not really changed
+ if (this.currentDate.getDate() != date.getDate() ||
+ this.currentDate.getMonth() != date.getMonth() ||
+ this.currentDate.getFullYear() != date.getFullYear())
+ {
+
+ this.currentDate = new Date(date);
+
+ this.updateHeader();
+ this.update();
+ }
+
+ },
+
+ setSelectedDate : function(date)
+ {
+ this.selectedDate = new Date(date);
+ this.setCurrentDate(this.selectedDate);
+ if (isFunction(this.onchange))
+ this.onchange();
+ },
+
+ getElement : function()
+ {
+ return this._calDiv;
+ },
+
+ getSelectedDate : function ()
+ {
+ return isNull(this.selectedDate) ? null : new Date(this.selectedDate);
+ },
+
+ setYear : function(year)
+ {
+ var d = new Date(this.currentDate);
+ d.setFullYear(year);
+ this.setCurrentDate(d);
+ },
+
+ setMonth : function (month)
+ {
+ var d = new Date(this.currentDate);
+ d.setMonth(month);
+ this.setCurrentDate(d);
+ },
+
+ nextMonth : function ()
+ {
+ this.setMonth(this.currentDate.getMonth()+1);
+ },
+
+ prevMonth : function ()
+ {
+ this.setMonth(this.currentDate.getMonth()-1);
+ },
+
+ show : function()
+ {
+ if(!this.showing)
+ {
+ var pos = Position.cumulativeOffset(this.control);
+ pos[1] += this.control.offsetHeight;
+ this._calDiv.style.display = "block";
+ this._calDiv.style.top = pos[1] + "px";
+ this._calDiv.style.left = pos[0] + "px";
+ Event.observe(document.body, "click", this.hideOnClick.bind(this));
+ var date = Prado.Calendar.Util.ParseDate(Form.Element.getValue(this.control), this.format);
+ if(!isNull(date))
+ {
+ this.selectedDate = date;
+ this.setCurrentDate(date);
+ }
+ this.showing = true;
+ }
+ },
+
+ //hide the calendar when clicked outside any calendar
+ hideOnClick : function(ev)
+ {
+ if(!this.showing) return;
+ var el = Event.element(ev);
+ var within = false;
+ do
+ {
+ within = within || el.className == this.className;
+ within = within || el == this.trigger;
+ within = within || el == this.control;
+ if(within) break;
+ el = el.parentNode;
+ }
+ while(el);
+ if(!within) this.hide();
+ },
+
+ hide : function()
+ {
+ if(this.showing)
+ {
+ this._calDiv.style.display = "none";
+ this.showing = false;
+ Event.stopObserving(document.body, "click", this.hideOnClick.bind(this));
+ }
+ },
+
+ update : function()
+ {
+ var Util = Prado.Calendar.Util;
+
+ // Calculate the number of days in the month for the selected date
+ var date = this.currentDate;
+ var today = Util.ISODate(new Date());
+
+ var selected = isNull(this.selectedDate) ? "" : Util.ISODate(this.selectedDate);
+ var current = Util.ISODate(date);
+ var d1 = new Date(date.getFullYear(), date.getMonth(), 1);
+ var d2 = new Date(date.getFullYear(), date.getMonth()+1, 1);
+ var monthLength = Math.round((d2 - d1) / (24 * 60 * 60 * 1000));
+
+ // Find out the weekDay index for the first of this month
+ var firstIndex = (d1.getDay() - this.firstDayOfWeek) % 7 ;
+ if (firstIndex < 0)
+ firstIndex += 7;
+
+ var index = 0;
+ while (index < firstIndex) {
+ this.dateSlot[index].value = -1;
+ this.dateSlot[index].data.data = String.fromCharCode(160);
+ this.dateSlot[index].data.parentNode.className = "empty";
+ index++;
+ }
+
+ for (i = 1; i <= monthLength; i++, index++) {
+ var slot = this.dateSlot[index];
+ var slotNode = slot.data.parentNode;
+ slot.value = i;
+ slot.data.data = i;
+ slotNode.className = "date";
+ if (Util.ISODate(d1) == today) {
+ slotNode.className += " today";
+ }
+ if (Util.ISODate(d1) == current) {
+ slotNode.className += " current";
+ }
+ if (Util.ISODate(d1) == selected) {
+ slotNode.className += " selected";
+ }
+ d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()+1);
+ }
+
+ var lastDateIndex = index;
+
+ while(index < 42) {
+ this.dateSlot[index].value = -1;
+ this.dateSlot[index].data.data = String.fromCharCode(160);
+ this.dateSlot[index].data.parentNode.className = "empty";
+ ++index;
+ }
+
+ },
+
+ hover : function(ev)
+ {
+ //conditionally add the hover class to the event target element.
+ Element.condClassName(Event.element(ev), "hover", ev.type=="mouseover");
+ },
+
+ updateHeader : function () {
+
+ var options = this._monthSelect.options;
+ var m = this.currentDate.getMonth();
+ for(var i=0; i < options.length; ++i) {
+ options[i].selected = false;
+ if (options[i].value == m) {
+ options[i].selected = true;
+ }
+ }
+
+ options = this._yearSelect.options;
+ var year = this.currentDate.getFullYear();
+ for(var i=0; i < options.length; ++i) {
+ options[i].selected = false;
+ if (options[i].value == year) {
+ options[i].selected = true;
+ }
+ }
+
+ }
+
+
+}; \ No newline at end of file