Created
March 8, 2011 18:09
-
-
Save botic/860675 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Jala Project [http://opensvn.csie.org/traccgi/jala] | |
// | |
// Copyright 2004 ORF Online und Teletext GmbH | |
// | |
// Licensed under the Apache License, Version 2.0 (the ``License''); | |
// you may not use this file except in compliance with the License. | |
// You may obtain a copy of the License at | |
// | |
// http://www.apache.org/licenses/LICENSE-2.0 | |
// | |
// Unless required by applicable law or agreed to in writing, software | |
// distributed under the License is distributed on an ``AS IS'' BASIS, | |
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
// See the License for the specific language governing permissions and | |
// limitations under the License. | |
// | |
// $Revision: 132 $ | |
// $LastChangedBy: robert $ | |
// $LastChangedDate: 2007-02-27 13:29:59 +0100 (Die, 27. Feb 2007) $ | |
// $HeadURL: http://dev.orf.at/source/jala/trunk/code/Date.js $ | |
// | |
/** | |
* @fileoverview Fields and methods of the jala.Date class. | |
*/ | |
// Define the global namespace for Jala modules | |
if (!global.jala) { | |
global.jala = {}; | |
} | |
/** | |
* HelmaLib dependencies | |
*/ | |
app.addRepository("modules/core/Date.js"); | |
app.addRepository("modules/helma/Html.js"); | |
/** | |
* Constructs a new Renderings object. | |
* @class This class provides various convenience | |
* methods for rendering purposes. | |
* @constructor | |
*/ | |
jala.Date = function() { | |
return this; | |
}; | |
/** | |
* Renders a timestamp as set of DropDown boxes, following the | |
* format passed as argument. Every <select> | |
* item is prefixed with a string so that it can be retrieved | |
* easily from the values of a submitted POST request. | |
* @param {String} prefix The prefix to use for all dropdown boxes, eg. "postdate" | |
* @param {Date} date A Date object to use as preselection (optional) | |
* @param {Object} fmt Array containing one parameter object for every single | |
* select box that should be rendered, with the following properties set: | |
* <ul> | |
* <li>pattern - The date format pattern that should be rendered. Valid | |
* patterns are: "dd", "MM", "yyyy", "HH", "ss".</li> | |
* <li>firstOption - The string to use as first option, eg.: "choose a day"</li> | |
* </ul> | |
*/ | |
jala.Date.prototype.renderEditor = function(prefix, date, fmt) { | |
/** | |
* rendering method | |
* @private | |
*/ | |
var render = function(param, date) { | |
switch (param.pattern) { | |
case "dd": | |
param.offset = 1; | |
param.max = 31; | |
param.selected = (date ? date.getDate() : null); | |
break; | |
case "MM": | |
param.offset = 1; | |
param.max = 12; | |
param.selected = (date ? date.getMonth() +1 : null); | |
break; | |
case "yyyy": | |
param.offset = 2002; | |
param.max = 20; | |
param.selected = (date ? date.getFullYear() : null); | |
break; | |
case "HH": | |
param.offset = 0; | |
param.max = 24; | |
param.selected = (date ? date.getHours() : null); | |
break; | |
case "mm": | |
param.offset = 0; | |
param.max = 60; | |
param.selected = (date ? date.getMinutes() : null); | |
break; | |
case "ss": | |
param.offset = 0; | |
param.max = 60; | |
param.selected = (date ? date.getSeconds() : null); | |
break; | |
} | |
var key = prefix + ":" + param.pattern; | |
if (req.data[key]) | |
param.selected = req.data[key]; | |
var options = []; | |
var opt; | |
for (var i=0;i<param.max;i++) { | |
opt = (param.offset + i).format("00"); | |
options[i] = [opt, opt]; | |
} | |
var html = new helma.Html(); | |
html.dropDown({name: key}, options, param.selected, param.firstOption); | |
} | |
if (!fmt) | |
var fmt = [{pattern: "dd", firstOption: "day"}, | |
{pattern: "MM", firstOption: "month"}, | |
{pattern: "yyyy", firstOption: "year"}, | |
{pattern: "HH", firstOption: "hour"}, | |
{pattern: "mm", firstOption: "minute"}]; | |
for (var i in fmt) { | |
render(fmt[i], date); | |
} | |
return; | |
}; | |
/** | |
* Returns a timestamp as set of dropdown-boxes | |
* @see #renderEditor | |
* @type String | |
*/ | |
jala.Date.prototype.renderEditorAsString = function(prefix, date, pattern) { | |
res.push(); | |
this.renderEditor(prefix, date, pattern); | |
return res.pop(); | |
}; | |
/** | |
* Creates a new instance of jala.Data.Calendar | |
* @class This class represents a calendar based based on a grouped | |
* collection of HopObjects. It provides several methods for rendering | |
* the calendar plus defining locale and timezone settings. | |
* @param {HopObject} collection A grouped HopObject collection to work on | |
* @returns A newly created jala.Date.Calendar instance | |
* @constructor | |
*/ | |
jala.Date.Calendar = function(collection) { | |
var renderer = null; | |
var locale = java.util.Locale.getDefault(); | |
var timezone = java.util.TimeZone.getDefault(); | |
var hrefFormat = "yyyyMMdd"; | |
var accessNameFormat = "yyyyMMdd"; | |
/** | |
* Returns the collection this calendar object works on | |
* @returns The HopObject collection of this calendar | |
* @type HopObject | |
*/ | |
this.getCollection = function() { | |
return collection; | |
}; | |
/** | |
* Sets the renderer to use. | |
* @param {Object} r The renderer to use | |
* @see #getRenderer | |
*/ | |
this.setRenderer = function(r) { | |
renderer = r; | |
return; | |
}; | |
/** | |
* Returns the renderer used by this calendar. | |
* @returns The calendar renderer | |
* @type Object | |
* @see #setRenderer | |
*/ | |
this.getRenderer = function() { | |
if (!renderer) { | |
renderer = new jala.Date.Calendar.Renderer(this); | |
} | |
return renderer; | |
}; | |
/** | |
* Sets the locale to use within this calendar object | |
* @param {java.util.Locale} loc The locale to use | |
* @see #getLocale | |
*/ | |
this.setLocale = function(loc) { | |
locale = loc; | |
return; | |
}; | |
/** | |
* Returns the locale used within this calendar instance. By default | |
* the locale used by this calendar is the default locale of the | |
* Java Virtual Machine running Helma. | |
* @returns The locale of this calendar | |
* @type java.util.Locale | |
* @see #setLocale | |
*/ | |
this.getLocale = function() { | |
return locale; | |
}; | |
/** | |
* Sets the locale to use within this calendar object | |
* @param {java.util.Locale} loc The locale to use | |
* @see #getTimeZone | |
*/ | |
this.setTimeZone = function(tz) { | |
timezone = tz; | |
return; | |
}; | |
/** | |
* Returns the locale used within this calendar instance. By default | |
* the timezone used by this calendar is the default timezone | |
* of the Java Virtual Machine running Helma. | |
* @returns The locale of this calendar | |
* @type java.util.Locale | |
* @see #setTimeZone | |
*/ | |
this.getTimeZone = function() { | |
return timezone; | |
}; | |
/** | |
* Sets the format of the hrefs to render by this calendar | |
* to the format pattern passed as argument. | |
* @param {String} fmt The date format pattern to use for | |
* rendering the href | |
* @see #getHrefFormat | |
*/ | |
this.setHrefFormat = function(fmt) { | |
hrefFormat = fmt; | |
return; | |
}; | |
/** | |
* Returns the date formatting pattern used to render hrefs. The default | |
* format is "yyyyMMdd". | |
* @returns The date formatting pattern | |
* @type String | |
* @see #setHrefFormat | |
*/ | |
this.getHrefFormat = function() { | |
return hrefFormat; | |
}; | |
/** | |
* Sets the format of the group name to use when trying to access | |
* child objects of the collection this calendar is operating on. | |
* @param {String} fmt The date format pattern to use for | |
* accessing child objects | |
* @see #getAccessNameFormat | |
*/ | |
this.setAccessNameFormat = function(fmt) { | |
accessNameFormat = fmt; | |
return; | |
}; | |
/** | |
* Returns the format of the access name used by this calendar to access | |
* child group objects of the collection this calendar is operating on. | |
* The default format is "yyyyMMdd". | |
* @returns The date formatting pattern used to access child objects | |
* @type String | |
* @see #setAccessNameFormat | |
*/ | |
this.getAccessNameFormat = function() { | |
return accessNameFormat; | |
}; | |
return this; | |
}; | |
/** @ignore */ | |
jala.Date.Calendar.prototype.toString = function() { | |
return "[Jala Calendar]"; | |
}; | |
/** | |
* Renders the calendar using either a custom renderer defined | |
* using {@link #setRenderer} or the default one. | |
* @see #setRenderer | |
* @see jala.Date.Calendar.Renderer | |
*/ | |
jala.Date.Calendar.prototype.render = function(today) { | |
var renderer = this.getRenderer(); | |
var collection = this.getCollection(); | |
var hrefFormat = this.getHrefFormat(); | |
var accessNameFormat = this.getAccessNameFormat(); | |
var locale = this.getLocale(); | |
var timezone = this.getTimeZone(); | |
var size = collection.size(); | |
if (size == null) | |
return; | |
/** | |
* private method that creates a date object set | |
* to the last date of the previous month or the | |
* first date of the next month (if available) | |
*/ | |
var prevNextMonth = function(which, dayIndex) { | |
var obj; | |
if (which == "prev") { | |
if (size <= dayIndex || !(obj = collection.get(dayIndex +1))) | |
return; | |
} else if (which == "next") { | |
if (dayIndex == 0 || !(obj = collection.get(dayIndex - 1))) | |
return; | |
} else { | |
return; | |
} | |
return new Date(obj.groupname.substring(0, 4), | |
obj.groupname.substring(4, 6) -1, | |
obj.groupname.substring(6)); | |
}; | |
// create the calendar object used for date calculations | |
var cal = java.util.Calendar.getInstance(timezone, locale); | |
var firstDayOfWeek = cal.getFirstDayOfWeek(); | |
var symbols = new java.text.DateFormatSymbols(locale); | |
res.push(); | |
// render the header-row | |
res.push(); | |
var weekdays = symbols.getShortWeekdays(); | |
for (var i=0;i<7;i++) { | |
renderer.renderDayHeader(weekdays[(i+firstDayOfWeek-1)%7+1]); | |
} | |
renderer.renderRow(res.pop()); | |
// check whether there's a day in path | |
// if so, use it to determine the month to render | |
if (today) { | |
cal.set(java.util.Calendar.YEAR, today.getFullYear()); | |
cal.set(java.util.Calendar.MONTH, today.getMonth()); | |
} | |
// nr. of empty days in rendered calendar before the first day of month appears | |
var pre = (7-firstDayOfWeek+cal.get(java.util.Calendar.DAY_OF_WEEK)) % 7; | |
var days = cal.getActualMaximum(java.util.Calendar.DATE); | |
var weeks = Math.ceil((pre + days) / 7); | |
var daycnt = 1; | |
var date = new Date(cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH), 1); | |
// remember the index of the first and last days within this month. | |
// this is needed to optimize previous and next month links. | |
var lastDayIndex = Number.MAX_VALUE; | |
var firstDayIndex = -1; | |
var dayObj, idx, selected; | |
for (var i=0;i<weeks;i++) { | |
res.push(); | |
for (var j=0;j<7;j++) { | |
if ((i == 0 && j < pre) || daycnt > days) { | |
renderer.renderDay(null); | |
} else { | |
date.setDate(daycnt); | |
if ((dayObj = collection.get(date.format(accessNameFormat))) != null) { | |
idx = collection.contains(dayObj); | |
if (idx > -1) { | |
if (idx > firstDayIndex) { | |
firstDayIndex = idx; | |
} | |
if (idx < lastDayIndex) { | |
lastDayIndex = idx; | |
} | |
} | |
} | |
selected = (today != null) ? date.equals(today) : false; | |
renderer.renderDay(date, dayObj != null, selected); | |
daycnt++; | |
} | |
} | |
renderer.renderRow(res.pop()); | |
} | |
var prevMonth = prevNextMonth("prev", firstDayIndex) || null; | |
var nextMonth = prevNextMonth("next", lastDayIndex) || null; | |
renderer.renderCalendar(date, res.pop(), prevMonth, nextMonth); | |
return; | |
}; | |
/** | |
* Returns a rendered calendar | |
* @see #renderCalendar | |
* @type String | |
*/ | |
jala.Date.Calendar.prototype.getCalendar = function(today) { | |
res.push(); | |
this.render(today); | |
return res.pop(); | |
}; | |
/** | |
* Returns a new instance of the default calendar renderer. | |
* @class A default renderer to use in conjunction with jala.Date.Calendar | |
* @param {jala.Date.Calendar} calendar The calendar utilizing this renderer | |
* @returns A newly created instance of jala.Date.Calendar.Renderer | |
* @constructor | |
*/ | |
jala.Date.Calendar.Renderer = function(calendar) { | |
/** | |
* An instance of helma.Html used for rendering the calendar | |
* @type helma.Html | |
*/ | |
this.html = new helma.Html(); | |
/** | |
* The calendar utilizing this renderer instance | |
* @type jala.Date.Calendar | |
*/ | |
this.calendar = calendar; | |
return this; | |
}; | |
/** @ignore */ | |
jala.Date.Calendar.Renderer.prototype.toString = function() { | |
return "[Jala Calendar Default Renderer]"; | |
}; | |
/** | |
* Renders a single cell in the calendar day header row directly to response. | |
* @param {String} text The text to display in the header field. | |
*/ | |
jala.Date.Calendar.Renderer.prototype.renderDayHeader = function(text) { | |
this.html.element("th", text); | |
return; | |
}; | |
/** | |
* Renders a single calendar row directly to response. | |
* @param {String} row The body of the calendar row. | |
*/ | |
jala.Date.Calendar.Renderer.prototype.renderRow = function(row) { | |
this.html.element("tr", row); | |
return; | |
}; | |
/** | |
* Renders a single day within the calendar directly to response. | |
* @param {Date} date A date instance representing the day within the calendar. | |
* @param {Boolean} isExisting True if there is a child object in the calendar's | |
* collection to which the date cell should link to | |
* @param {Boolean} isSelected True if this calendar day should be rendered | |
* as selected day. | |
*/ | |
jala.Date.Calendar.Renderer.prototype.renderDay = function(date, isExisting, isSelected) { | |
var attr = {"class": "day"}; | |
if (isSelected === true) { | |
attr["class"] += " selected"; | |
} | |
this.html.openTag("td", attr); | |
if (date != null) { | |
var text = date.getDate(); | |
if (isExisting === true) { | |
attr = {"href": this.calendar.getCollection().href() + | |
date.format(this.calendar.getHrefFormat())}; | |
this.html.link(attr, text); | |
} else { | |
res.write(text); | |
} | |
} | |
this.html.closeTag("td"); | |
return; | |
}; | |
/** | |
* Renders a link to the previous or next month's calendar directly to response. | |
* @param {Date} date A date object set to the previous or next available | |
* month. This can be null in case there is no previous or next month. | |
*/ | |
jala.Date.Calendar.Renderer.prototype.renderPrevNextLink = function(date) { | |
if (date != null) { | |
var attr = {"href": this.calendar.getCollection().href() + | |
date.format(this.calendar.getHrefFormat())}; | |
this.html.link(attr, date.format("MMMM", this.calendar.getLocale())); | |
} | |
return; | |
}; | |
/** | |
* Renders the calendar directly to response. | |
* @param {Date} date A date object representing this calendar's month and year. | |
* Please mind that the day will be set to the <em>last</em> date in this | |
* month. | |
* @param {String} body The rendered calendar weeks including the day header | |
* (basically the whole kernel of the table). | |
* @param {Date} prevMonth A date object set to the last available date of | |
* the previous month. This can be used to render a navigation link to | |
* the previous month. | |
* @param {Date} nextMonth A date object set to the first available date | |
* of the next month. This can be used to render a navigation link to | |
* the next month. | |
*/ | |
jala.Date.Calendar.Renderer.prototype.renderCalendar = function(date, body, prevMonth, nextMonth) { | |
var locale = this.calendar.getLocale(); | |
this.html.openTag("table", {"class": "calendar"}); | |
this.html.openTag("thead"); | |
this.html.openTag("tr"); | |
this.html.openTag("th", {"colspan": 7}); | |
res.write(date.format("MMMM", locale)); | |
res.write(' '); | |
res.write(date.format("yyyy", locale)); | |
this.html.closeTag("th"); | |
this.html.closeTag("tr"); | |
this.html.closeTag("thead"); | |
this.html.element("tbody", body); | |
this.html.openTag("tfoot"); | |
this.html.openTag("tr"); | |
this.html.openTag("td", {"class": "left", "colspan": 3}); | |
this.renderPrevNextLink(prevMonth); | |
this.html.closeTag("td"); | |
this.html.openTag("td"); | |
this.html.closeTag("td"); | |
this.html.openTag("td", {"class": "right", "colspan": 3}); | |
this.renderPrevNextLink(nextMonth); | |
this.html.closeTag("td"); | |
this.html.closeTag("tr"); | |
this.html.closeTag("tfoot"); | |
this.html.closeTag("table"); | |
return; | |
}; | |
/** | |
* Default date class instance. | |
* @type jala.Date | |
* @final | |
*/ | |
jala.date = new jala.Date(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment