| /* |
| Copyright (c) 2004-2005, The Dojo Foundation |
| All Rights Reserved. |
| |
| Licensed under the Academic Free License version 2.1 or above OR the |
| modified BSD license. For more information on Dojo licensing, see: |
| |
| http://dojotoolkit.org/community/licensing.shtml |
| */ |
| |
| dojo.provide("dojo.widget.html.DatePicker"); |
| dojo.require("dojo.widget.*"); |
| dojo.require("dojo.widget.HtmlWidget"); |
| dojo.require("dojo.widget.DatePicker"); |
| dojo.require("dojo.event.*"); |
| dojo.require("dojo.html"); |
| |
| /* |
| Some assumptions: |
| - I'm planning on always showing 42 days at a time, and we can scroll by week, |
| not just by month or year |
| - To get a sense of what month to highlight, I basically initialize on the |
| first Saturday of each month, since that will be either the first of two or |
| the second of three months being partially displayed, and then I work forwards |
| and backwards from that point. |
| Currently, I assume that dates are stored in the RFC 3339 format, |
| because I find it to be most human readable and easy to parse |
| http://www.faqs.org/rfcs/rfc3339.html: 2005-06-30T08:05:00-07:00 |
| FIXME: scroll by week not yet implemented |
| */ |
| |
| |
| dojo.widget.html.DatePicker = function(){ |
| dojo.widget.DatePicker.call(this); |
| dojo.widget.HtmlWidget.call(this); |
| |
| var _this = this; |
| // today's date, JS Date object |
| this.today = ""; |
| // selected date, JS Date object |
| this.date = ""; |
| // rfc 3339 date |
| this.storedDate = ""; |
| // date currently selected in the UI, stored in year, month, date in the format that will be actually displayed |
| this.currentDate = {}; |
| // stored in year, month, date in the format that will be actually displayed |
| this.firstSaturday = {}; |
| this.classNames = { |
| previous: "previousMonth", |
| current: "currentMonth", |
| next: "nextMonth", |
| currentDate: "currentDate", |
| selectedDate: "selectedItem" |
| } |
| |
| this.templatePath = dojo.uri.dojoUri("src/widget/templates/HtmlDatePicker.html"); |
| this.templateCssPath = dojo.uri.dojoUri("src/widget/templates/HtmlDatePicker.css"); |
| |
| this.fillInTemplate = function(){ |
| this.initData(); |
| this.initUI(); |
| } |
| |
| this.initData = function() { |
| this.today = new Date(); |
| if(this.storedDate && (this.storedDate.split("-").length > 2)) { |
| this.date = dojo.widget.DatePicker.util.fromRfcDate(this.storedDate); |
| } else { |
| this.date = this.today; |
| } |
| // calendar math is simplified if time is set to 0 |
| this.today.setHours(0); |
| this.date.setHours(0); |
| var month = this.date.getMonth(); |
| var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(this.date.getMonth().toString(), this.date.getFullYear()); |
| this.firstSaturday.year = tempSaturday.year; |
| this.firstSaturday.month = tempSaturday.month; |
| this.firstSaturday.date = tempSaturday.date; |
| } |
| |
| this.setDate = function(rfcDate) { |
| this.storedDate = rfcDate; |
| } |
| |
| |
| this.initUI = function() { |
| this.selectedIsUsed = false; |
| this.currentIsUsed = false; |
| var currentClassName = ""; |
| var previousDate = new Date(); |
| var calendarNodes = this.calendarDatesContainerNode.getElementsByTagName("td"); |
| var currentCalendarNode; |
| // set hours of date such that there is no chance of rounding error due to |
| // time change in local time zones |
| previousDate.setHours(8); |
| var nextDate = new Date(this.firstSaturday.year, this.firstSaturday.month, this.firstSaturday.date, 8); |
| |
| |
| if(this.firstSaturday.date < 7) { |
| // this means there are days to show from the previous month |
| var dayInWeek = 6; |
| for (var i=this.firstSaturday.date; i>0; i--) { |
| currentCalendarNode = calendarNodes.item(dayInWeek); |
| currentCalendarNode.innerHTML = nextDate.getDate(); |
| dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current")); |
| dayInWeek--; |
| previousDate = nextDate; |
| nextDate = this.incrementDate(nextDate, false); |
| } |
| for(var i=dayInWeek; i>-1; i--) { |
| currentCalendarNode = calendarNodes.item(i); |
| currentCalendarNode.innerHTML = nextDate.getDate(); |
| dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "previous")); |
| previousDate = nextDate; |
| nextDate = this.incrementDate(nextDate, false); |
| } |
| } else { |
| nextDate.setDate(1); |
| for(var i=0; i<7; i++) { |
| currentCalendarNode = calendarNodes.item(i); |
| currentCalendarNode.innerHTML = i + 1; |
| dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current")); |
| previousDate = nextDate; |
| nextDate = this.incrementDate(nextDate, true); |
| } |
| } |
| previousDate.setDate(this.firstSaturday.date); |
| previousDate.setMonth(this.firstSaturday.month); |
| previousDate.setFullYear(this.firstSaturday.year); |
| nextDate = this.incrementDate(previousDate, true); |
| var count = 7; |
| currentCalendarNode = calendarNodes.item(count); |
| while((nextDate.getMonth() == previousDate.getMonth()) && (count<42)) { |
| currentCalendarNode.innerHTML = nextDate.getDate(); |
| dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "current")); |
| currentCalendarNode = calendarNodes.item(++count); |
| previousDate = nextDate; |
| nextDate = this.incrementDate(nextDate, true); |
| } |
| |
| while(count < 42) { |
| currentCalendarNode.innerHTML = nextDate.getDate(); |
| dojo.html.setClass(currentCalendarNode, this.getDateClassName(nextDate, "next")); |
| currentCalendarNode = calendarNodes.item(++count); |
| previousDate = nextDate; |
| nextDate = this.incrementDate(nextDate, true); |
| } |
| this.setMonthLabel(this.firstSaturday.month); |
| this.setYearLabels(this.firstSaturday.year); |
| } |
| |
| this.incrementDate = function(date, bool) { |
| // bool: true to increase, false to decrease |
| var time = date.getTime(); |
| var increment = 1000 * 60 * 60 * 24; |
| time = (bool) ? (time + increment) : (time - increment); |
| var returnDate = new Date(); |
| returnDate.setTime(time); |
| return returnDate; |
| } |
| |
| this.incrementWeek = function(date, bool) { |
| dojo.unimplemented('dojo.widget.html.DatePicker.incrementWeek'); |
| } |
| |
| this.incrementMonth = function(date, bool) { |
| dojo.unimplemented('dojo.widget.html.DatePicker.incrementMonth'); |
| } |
| |
| this.incrementYear = function(date, bool) { |
| dojo.unimplemented('dojo.widget.html.DatePicker.incrementYear'); |
| } |
| |
| this.onIncrementDate = function(evt) { |
| dojo.unimplemented('dojo.widget.html.DatePicker.onIncrementDate'); |
| } |
| |
| this.onIncrementWeek = function(evt) { |
| // FIXME: should make a call to incrementWeek when that is implemented |
| evt.stopPropagation(); |
| dojo.unimplemented('dojo.widget.html.DatePicker.onIncrementWeek'); |
| switch(evt.target) { |
| case this.increaseWeekNode: |
| break; |
| case this.decreaseWeekNode: |
| break; |
| } |
| } |
| |
| this.onIncrementMonth = function(evt) { |
| // FIXME: should make a call to incrementMonth when that is implemented |
| evt.stopPropagation(); |
| var month = this.firstSaturday.month; |
| var year = this.firstSaturday.year; |
| switch(evt.currentTarget) { |
| case this.increaseMonthNode: |
| if(month < 11) { |
| month++; |
| } else { |
| month = 0; |
| year++; |
| |
| this.setYearLabels(year); |
| } |
| break; |
| case this.decreaseMonthNode: |
| if(month > 0) { |
| month--; |
| } else { |
| month = 11; |
| year--; |
| this.setYearLabels(year); |
| } |
| break; |
| case this.increaseMonthNode.getElementsByTagName("img").item(0): |
| if(month < 11) { |
| month++; |
| } else { |
| month = 0; |
| year++; |
| this.setYearLabels(year); |
| } |
| break; |
| case this.decreaseMonthNode.getElementsByTagName("img").item(0): |
| if(month > 0) { |
| month--; |
| } else { |
| month = 11; |
| year--; |
| this.setYearLabels(year); |
| } |
| break; |
| } |
| var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(month.toString(), year); |
| this.firstSaturday.year = tempSaturday.year; |
| this.firstSaturday.month = tempSaturday.month; |
| this.firstSaturday.date = tempSaturday.date; |
| this.initUI(); |
| } |
| |
| this.onIncrementYear = function(evt) { |
| // FIXME: should make a call to incrementYear when that is implemented |
| evt.stopPropagation(); |
| var year = this.firstSaturday.year; |
| switch(evt.target) { |
| case this.nextYearLabelNode: |
| year++; |
| break; |
| case this.previousYearLabelNode: |
| year--; |
| break; |
| } |
| var tempSaturday = dojo.widget.DatePicker.util.initFirstSaturday(this.firstSaturday.month.toString(), year); |
| this.firstSaturday.year = tempSaturday.year; |
| this.firstSaturday.month = tempSaturday.month; |
| this.firstSaturday.date = tempSaturday.date; |
| this.initUI(); |
| } |
| |
| this.setMonthLabel = function(monthIndex) { |
| this.monthLabelNode.innerHTML = this.months[monthIndex]; |
| } |
| |
| this.setYearLabels = function(year) { |
| this.previousYearLabelNode.innerHTML = year - 1; |
| this.currentYearLabelNode.innerHTML = year; |
| this.nextYearLabelNode.innerHTML = year + 1; |
| } |
| |
| this.getDateClassName = function(date, monthState) { |
| var currentClassName = this.classNames[monthState]; |
| if ((!this.selectedIsUsed) && (date.getDate() == this.date.getDate()) && (date.getMonth() == this.date.getMonth()) && (date.getFullYear() == this.date.getFullYear())) { |
| currentClassName = this.classNames.selectedDate + " " + currentClassName; |
| this.selectedIsUsed = 1; |
| } |
| if((!this.currentIsUsed) && (date.getDate() == this.today.getDate()) && (date.getMonth() == this.today.getMonth()) && (date.getFullYear() == this.today.getFullYear())) { |
| currentClassName = currentClassName + " " + this.classNames.currentDate; |
| this.currentIsUsed = 1; |
| } |
| return currentClassName; |
| } |
| |
| this.onClick = function(evt) { |
| dojo.event.browser.stopEvent(evt) |
| } |
| |
| this.onSetDate = function(evt) { |
| dojo.event.browser.stopEvent(evt); |
| this.selectedIsUsed = 0; |
| this.todayIsUsed = 0; |
| var month = this.firstSaturday.month; |
| var year = this.firstSaturday.year; |
| if (dojo.html.hasClass(evt.target, this.classNames["next"])) { |
| month = ++month % 12; |
| // if month is now == 0, add a year |
| year = (month==0) ? ++year : year; |
| } else if (dojo.html.hasClass(evt.target, this.classNames["previous"])) { |
| month = --month % 12; |
| // if month is now == 0, add a year |
| year = (month==11) ? --year : year; |
| } |
| this.date = new Date(year, month, evt.target.innerHTML); |
| this.setDate(dojo.widget.DatePicker.util.toRfcDate(this.date)); |
| this.initUI(); |
| } |
| } |
| dojo.inherits(dojo.widget.html.DatePicker, dojo.widget.HtmlWidget); |