You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/03/11 21:55:35 UTC
svn commit: r385164 [15/32] - in /jakarta/tapestry/trunk: ./ .settings/
annotations/src/java/org/apache/tapestry/annotations/
annotations/src/test/org/apache/tapestry/annotations/ config/
contrib/src/documentation/content/xdocs/tapestry-contrib/Compone...
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/DatePicker.js.merge-left.r384672
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/DatePicker.js.merge-left.r384672?rev=385164&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/DatePicker.js.merge-left.r384672 (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/DatePicker.js.merge-left.r384672 Sat Mar 11 12:54:27 2006
@@ -0,0 +1,1024 @@
+//
+// calendar -- a javascript date picker designed for easy localization.
+//
+//
+//
+// Author: Per Norrman (pernorrman@telia.com)
+//
+// Based on Tapestry 2.3-beta1 Datepicker by Paul Geerts
+//
+// Thanks to:
+// Vladimir [vyc@quorus-ms.ru] for fixing the IE6 zIndex problem.
+//
+// The normal setup would be to have one text field for displaying the
+// selected date, and one button to show/hide the date picker control.
+// This is the recommended javascript code:
+//
+// <script language="javascript">
+// var cal;
+//
+// function init() {
+// cal = new Calendar();
+// cal.setIncludeWeek(true);
+// cal.setFormat("yyyy-MM-dd");
+// cal.setMonthNames(.....);
+// cal.setShortMonthNames(....);
+// cal.create();
+//
+// document.form.button1.onclick = function() {
+// cal.toggle(document.form.button1);
+// }
+// cal.onchange = function() {
+// document.form.textfield1.value = cal.formatDate();
+// }
+// }
+// </script>
+//
+// The init function is invoked when the body is loaded.
+//
+//
+
+function Calendar(date) {
+ if (arguments.length == 0) {
+ this._currentDate = new Date();
+ this._selectedDate = null;
+ }
+ else {
+ this._currentDate = new Date(date);
+ this._selectedDate = new Date(date);
+ }
+
+ // Accumulated days per month, for normal and for leap years.
+ // Used in week number calculations.
+ Calendar.NUM_DAYS = [0,31,59,90,120,151,181,212,243,273,304,334];
+
+ Calendar.LEAP_NUM_DAYS = [0,31,60,91,121,152,182,213,244,274,305,335];
+
+
+ this._bw = new bw_check();
+ this._showing = false;
+ this._includeWeek = false;
+ this._hideOnSelect = true;
+ this._alwaysVisible = false;
+
+ this._dateSlot = new Array(42);
+ this._weekSlot = new Array(6);
+
+ this._firstDayOfWeek = 1;
+ this._minimalDaysInFirstWeek = 4;
+
+ this._monthNames = [
+ "January", "February", "March", "April",
+ "May", "June", "July", "August",
+ "September", "October", "November", "December"
+ ];
+
+ this._shortMonthNames = [
+ "jan", "feb", "mar", "apr", "may", "jun",
+ "jul", "aug", "sep", "oct", "nov", "dec"
+ ];
+
+ // Week days start with Sunday=0, ... Saturday=6
+ this._weekDayNames = [
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+ ];
+
+ this._shortWeekDayNames =
+ ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ];
+
+ this._defaultFormat = "yyyy-MM-dd";
+
+ this._format = this._defaultFormat;
+
+ this._calDiv = null;
+
+ this._clearButtonLabel = "Clear";
+
+}
+
+/**
+ * CREATE the Calendar DOM element
+ */
+Calendar.prototype.create = function() {
+ var div;
+ var table;
+ var tbody;
+ var tr;
+ var td;
+ var dp = this;
+
+ // Create the top-level div element
+ this._calDiv = document.createElement("div");
+ this._calDiv.className = "calendar";
+ this._calDiv.style.position = "absolute";
+ this._calDiv.style.display = "none";
+ this._calDiv.style.border = "1px solid WindowText";
+ this._calDiv.style.textAlign = "center";
+ this._calDiv.style.background = "Window";
+ this._calDiv.style.zIndex = "400";
+
+
+ // header div
+ div = document.createElement("div");
+ div.className = "calendarHeader";
+ div.style.background = "ActiveCaption";
+ div.style.padding = "3px";
+ div.style.borderBottom = "1px solid WindowText";
+ 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");
+ this._previousMonth = document.createElement("button");
+ this._previousMonth.className = "prevMonthButton"
+ this._previousMonth.appendChild(document.createTextNode("<<"));
+ //this._previousMonth.appendChild(document.createTextNode(String.fromCharCode(9668)));
+ 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");
+ this._nextMonth = document.createElement("button");
+ this._nextMonth.appendChild(document.createTextNode(">>"));
+ //this._nextMonth.appendChild(document.createTextNode(String.fromCharCode(9654)));
+ this._nextMonth.className = "nextMonthButton";
+ 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";
+ table.style.font = "small-caption";
+ table.style.fontWeight = "normal";
+ table.style.textAalign = "center";
+ table.style.color = "WindowText";
+ table.style.cursor = "default";
+ table.cellPadding = "3";
+ table.cellSpacing = "0";
+
+ div.appendChild(table);
+ var thead = document.createElement("thead");
+ table.appendChild(thead);
+ tr = document.createElement("tr");
+ thead.appendChild(tr);
+
+ // weekdays header
+ if (this._includeWeek) {
+ td = document.createElement("th");
+ text = document.createTextNode("w");
+ td.appendChild(text);
+ td.className = "weekNumberHead";
+ td.style.textAlign = "left";
+ tr.appendChild(td);
+ }
+ 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";
+ td.style.fontWeight = "bold";
+ td.style.borderBottom = "1px solid WindowText";
+ 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);
+
+ if (this._includeWeek) {
+ td = document.createElement("td");
+ td.className = "weekNumber";
+ td.style.fontWeight = "normal";
+ td.style.borderRight = "1px solid WindowText";
+ td.style.textAlign = "left";
+ text = document.createTextNode(String.fromCharCode(160));
+ td.appendChild(text);
+ //setCursor(td);
+ td.align="center";
+ tr.appendChild(td);
+ var tmp = new Object();
+ tmp.tag = "WEEK";
+ tmp.value = -1;
+ tmp.data = text;
+ this._weekSlot[week] = tmp;
+ }
+
+ for(day=0; day<7; ++day) {
+ td = document.createElement("td");
+ text = document.createTextNode(String.fromCharCode(160));
+ td.appendChild(text);
+ setCursor(td);
+ td.align="center";
+ td.style.fontWeight="normal";
+
+ tr.appendChild(td);
+ var tmp = new Object();
+ tmp.tag = "DATE";
+ tmp.value = -1;
+ tmp.data = text;
+ this._dateSlot[(week*7)+day] = tmp;
+
+ }
+ }
+
+ // 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");
+ 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");
+ this._clearButton = document.createElement("button");
+ var today = new Date();
+ this._clearButton.appendChild(document.createTextNode(this._clearButtonLabel));
+ td.appendChild(this._clearButton);
+ tr.appendChild(td);
+
+
+ this._update();
+ this._updateHeader();
+
+
+
+ // IE55+ extension
+ this._previousMonth.hideFocus = true;
+ this._nextMonth.hideFocus = true;
+ this._todayButton.hideFocus = true;
+ // end IE55+ extension
+
+ // hook up events
+ // buttons
+ this._previousMonth.onclick = function () {
+ dp.prevMonth();
+ };
+
+ this._nextMonth.onclick = function () {
+ dp.nextMonth();
+ };
+
+ this._todayButton.onclick = function () {
+ dp.setSelectedDate(new Date());
+ dp.hide();
+ };
+
+ this._clearButton.onclick = function () {
+ dp.clearSelectedDate();
+ dp.hide();
+ };
+
+
+ this._calDiv.onselectstart = function () {
+ return false;
+ };
+
+ this._table.onclick = function (e) {
+ // find event
+ if (e == null) e = document.parentWindow.event;
+
+ // find td
+ var el = e.target != null ? e.target : e.srcElement;
+ 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(dp._currentDate);
+ var n = Number(el.firstChild.data);
+ if (isNaN(n) || n <= 0 || n == null)
+ return;
+
+ if (el.className == "weekNumber")
+ return;
+
+ d.setDate(n);
+ dp.setSelectedDate(d);
+
+ if (!dp._alwaysVisible && dp._hideOnSelect) {
+ dp.hide();
+ }
+
+ };
+
+
+ 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;
+ }
+
+ // ie6 extension
+ this._calDiv.onmousewheel = function (e) {
+ if (e == null) e = document.parentWindow.event;
+ var n = - e.wheelDelta / 120;
+ var d = new Date(dp._currentDate);
+ var m = d.getMonth() + n;
+ d.setMonth(m);
+
+
+ dp.setCurrentDate(d);
+
+ return false;
+ }
+
+ this._monthSelect.onchange = function(e) {
+ if (e == null) e = document.parentWindow.event;
+ e = getEventObject(e);
+ dp.setMonth(e.value);
+ }
+
+ this._monthSelect.onclick = function(e) {
+ if (e == null) e = document.parentWindow.event;
+ e = getEventObject(e);
+ e.cancelBubble = true;
+ }
+
+ this._yearSelect.onchange = function(e) {
+ if (e == null) e = document.parentWindow.event;
+ e = getEventObject(e);
+ dp.setYear(e.value);
+ }
+
+
+ document.body.appendChild(this._calDiv);
+
+
+ return this._calDiv;
+}
+
+Calendar.prototype._update = function() {
+
+
+ // Calculate the number of days in the month for the selected date
+ var date = this._currentDate;
+ var today = toISODate(new Date());
+
+
+ var selected = "";
+ if (this._selectedDate != null) {
+ selected = toISODate(this._selectedDate);
+ }
+ var current = toISODate(this._currentDate);
+ 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 = "";
+ this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
+ this._dateSlot[index].data.parentNode.style.border= "none";
+ index++;
+ }
+
+ for (i = 1; i <= monthLength; i++, index++) {
+ this._dateSlot[index].value = i;
+ this._dateSlot[index].data.data = i;
+ this._dateSlot[index].data.parentNode.className = "";
+ this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
+ this._dateSlot[index].data.parentNode.style.border= "none";
+ if (toISODate(d1) == today) {
+ this._dateSlot[index].data.parentNode.className = "today";
+ this._dateSlot[index].data.parentNode.style.fontWeight = "bold";
+ }
+ if (toISODate(d1) == current) {
+ this._dateSlot[index].data.parentNode.className += " current";
+ this._dateSlot[index].data.parentNode.style.border= "1px dotted WindowText";
+ }
+ if (toISODate(d1) == selected) {
+ this._dateSlot[index].data.parentNode.className += " selected";
+ this._dateSlot[index].data.parentNode.style.border= "1px solid WindowText";
+ }
+ 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 = "";
+ this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
+ this._dateSlot[index].data.parentNode.style.border= "none";
+ ++index;
+ }
+
+ // Week numbers
+ if (this._includeWeek) {
+ d1 = new Date(date.getFullYear(), date.getMonth(), 1);
+ for (i=0; i < 6; ++i) {
+ if (i == 5 && lastDateIndex < 36) {
+ this._weekSlot[i].data.data = String.fromCharCode(160);
+ this._weekSlot[i].data.parentNode.style.borderRight = "none";
+ } else {
+ week = weekNumber(this, d1);
+ this._weekSlot[i].data.data = week;
+ this._weekSlot[i].data.parentNode.style.borderRight = "1px solid WindowText";
+ }
+ d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()+7);
+ }
+ }
+}
+
+Calendar.prototype.show = function(element) {
+ if(!this._showing) {
+ var p = getPoint(element);
+ this._calDiv.style.display = "block";
+ this._calDiv.style.top = (p.y + element.offsetHeight + 1) + "px";
+ this._calDiv.style.left = p.x + "px";
+ this._showing = true;
+
+ /* -------- */
+ if( this._bw.ie6 )
+ {
+ dw = this._calDiv.offsetWidth;
+ dh = this._calDiv.offsetHeight;
+ var els = document.getElementsByTagName("body");
+ var body = els[0];
+ if( !body ) return;
+
+ //paste iframe under the modal
+ var underDiv = this._calDiv.cloneNode(false);
+ underDiv.style.zIndex="390";
+ underDiv.style.margin = "0px";
+ underDiv.style.padding = "0px";
+ underDiv.style.display = "block";
+ underDiv.style.width = dw;
+ underDiv.style.height = dh;
+ underDiv.style.border = "1px solid WindowText";
+ underDiv.innerHTML = "<iframe width=\"100%\" height=\"100%\" frameborder=\"0\"></iframe>";
+ body.appendChild(underDiv);
+ this._underDiv = underDiv;
+ }
+ /* -------- */
+
+ if (this._calDiv.focus)
+ this._calDiv.focus();
+
+ }
+};
+
+Calendar.prototype.hide = function() {
+ if(this._showing) {
+ this._calDiv.style.display = "none";
+ this._showing = false;
+ if( this._bw.ie6 ) {
+ if( this._underDiv ) this._underDiv.removeNode(true);
+ }
+ }
+}
+
+Calendar.prototype.toggle = function(element) {
+ if(this._showing) {
+ this.hide();
+ } else {
+ this.show(element);
+ }
+}
+
+
+
+Calendar.prototype.onchange = function() {};
+
+
+Calendar.prototype.setCurrentDate = function(date) {
+ if (date == null) {
+ return;
+ }
+
+ // if string or number create a Date object
+ if (typeof date == "string" || typeof date == "number") {
+ 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();
+
+ }
+
+}
+
+Calendar.prototype.setSelectedDate = function(date) {
+ this._selectedDate = new Date(date);
+ this.setCurrentDate(this._selectedDate);
+ if (typeof this.onchange == "function") {
+ this.onchange();
+ }
+}
+
+Calendar.prototype.clearSelectedDate = function() {
+ this._selectedDate = null;
+ if (typeof this.onchange == "function") {
+ this.onchange();
+ }
+}
+
+Calendar.prototype.getElement = function() {
+ return this._calDiv;
+}
+
+Calendar.prototype.setIncludeWeek = function(v) {
+ if (this._calDiv == null) {
+ this._includeWeek = v;
+ }
+}
+
+Calendar.prototype.setClearButtonLabel = function(v) {
+ this._clearButtonLabel = v;
+}
+
+Calendar.prototype.getSelectedDate = function () {
+ if (this._selectedDate == null) {
+ return null;
+ } else {
+ return new Date(this._selectedDate);
+ }
+}
+
+Calendar.prototype.initialize = function(monthNames, shortMonthNames, weekDayNames, shortWeekDayNames, format,
+ firstDayOfWeek, includeWeek, minimalDaysInFirstWeek, clearButtonLabel)
+{
+ this.setMonthNames(monthNames);
+ this.setShortMonthNames(shortMonthNames);
+ this.setWeekDayNames(weekDayNames);
+ this.setShortWeekDayNames(shortWeekDayNames);
+ this.setFormat(format);
+ this.setFirstDayOfWeek(firstDayOfWeek);
+ this.setIncludeWeek(includeWeek);
+ this.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek);
+ this.setClearButtonLabel(clearButtonLabel);
+
+ this.create();
+}
+
+
+Calendar.prototype._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;
+ }
+ }
+
+}
+
+Calendar.prototype.setYear = function(year) {
+ var d = new Date(this._currentDate);
+ d.setFullYear(year);
+ this.setCurrentDate(d);
+}
+
+Calendar.prototype.setMonth = function (month) {
+ var d = new Date(this._currentDate);
+ d.setMonth(month);
+ this.setCurrentDate(d);
+}
+
+Calendar.prototype.nextMonth = function () {
+ this.setMonth(this._currentDate.getMonth()+1);
+}
+
+Calendar.prototype.prevMonth = function () {
+ this.setMonth(this._currentDate.getMonth()-1);
+}
+
+Calendar.prototype.setFirstDayOfWeek = function (nFirstWeekDay) {
+ this._firstDayOfWeek = nFirstWeekDay;
+}
+
+Calendar.prototype.getFirstDayOfWeek = function () {
+ return this._firstDayOfWeek;
+}
+
+Calendar.prototype.setMinimalDaysInFirstWeek = function(n) {
+ this._minimalDaysInFirstWeek = n;
+}
+
+
+Calendar.prototype.getMinimalDaysInFirstWeek = function () {
+ return this._minimalDaysInFirstWeek;
+}
+
+Calendar.prototype.setMonthNames = function(a) {
+ // sanity test
+ this._monthNames = a;
+}
+
+Calendar.prototype.setShortMonthNames = function(a) {
+ // sanity test
+ this._shortMonthNames = a;
+}
+
+Calendar.prototype.setWeekDayNames = function(a) {
+ // sanity test
+ this._weekDayNames = a;
+}
+
+Calendar.prototype.setShortWeekDayNames = function(a) {
+ // sanity test
+ this._shortWeekDayNames = a;
+}
+
+Calendar.prototype.getFormat = function() {
+ return this._format;
+}
+
+Calendar.prototype.setFormat = function(f) {
+ this._format = f;
+}
+
+Calendar.prototype.formatDate = function() {
+ if (this._selectedDate == null) {
+ return "";
+ }
+
+ var bits = new Array();
+ // work out what each bit should be
+ var date = this._selectedDate;
+ bits['d'] = date.getDate();
+ bits['dd'] = pad(date.getDate(),2);
+ bits['ddd'] = this._shortWeekDayNames[date.getDay()];
+ bits['dddd'] = this._weekDayNames[date.getDay()];
+
+ bits['M'] = date.getMonth()+1;
+ bits['MM'] = pad(date.getMonth()+1,2);
+ bits['MMM'] = this._shortMonthNames[date.getMonth()];
+ bits['MMMM'] = this._monthNames[date.getMonth()];
+
+ var yearStr = "" + date.getFullYear();
+ yearStr = (yearStr.length == 2) ? '19' + yearStr: yearStr;
+ bits['yyyy'] = yearStr;
+ bits['yy'] = bits['yyyy'].toString().substr(2,2);
+
+ bits['s'] = date.getSeconds();
+ bits['ss'] = pad(date.getSeconds(),2);
+
+ bits['m'] = date.getMinutes();
+ bits['mm'] = pad(date.getMinutes(),2);
+
+ bits['H'] = date.getHours();
+ bits['HH'] = pad(date.getHours(),2);
+
+ // do some funky regexs to replace the format string
+ // with the real values
+ var frm = new String(this._format);
+ // TAPESTRY-669: Have to be very explicit about keys, to keep functions added
+ // to Array (by the Prototype library, if its around) from getting mixed in.
+ var keys = new Array('dddd','ddd','dd','d','MMMM','MMM','MM','M','yyyy','yy', 'ss', 's', 'mm',
+ 'm', 'HH', 'H');
+ for (var i = 0; i < keys.length; i++) {
+ frm = eval("frm.replace(/" + keys[i] + "/,\"" + bits[keys[i]] + "\");");
+ }
+
+ return frm;
+}
+
+
+function isLeapYear(year) {
+ return ((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));
+}
+
+function yearLength(year) {
+ if (isLeapYear(year))
+ return 366;
+ else
+ return 365;
+}
+
+function dayOfYear(date) {
+ var a = Calendar.NUM_DAYS;
+ if (isLeapYear(date.getFullYear())) {
+ a = Calendar.LEAP_NUM_DAYS;
+ }
+ var month = date.getMonth();
+
+ return a[month] + date.getDate();
+}
+
+// ---------------------------------------------
+// Week number stuff
+// ---------------------------------------------
+
+function weekNumber(cal, date) {
+
+ var dow = date.getDay();
+ var doy = dayOfYear(date);
+ var year = date.getFullYear();
+
+ // Compute the week of the year. Valid week numbers run from 1 to 52
+ // or 53, depending on the year, the first day of the week, and the
+ // minimal days in the first week. Days at the start of the year may
+ // fall into the last week of the previous year; days at the end of
+ // the year may fall into the first week of the next year.
+ var relDow = (dow + 7 - cal.getFirstDayOfWeek()) % 7; // 0..6
+ var relDowJan1 = (dow - doy + 701 - cal.getFirstDayOfWeek()) % 7; // 0..6
+ var week = Math.floor((doy - 1 + relDowJan1) / 7); // 0..53
+ if ((7 - relDowJan1) >= cal.getMinimalDaysInFirstWeek()) {
+ ++week;
+ }
+
+ if (doy > 359) { // Fast check which eliminates most cases
+ // Check to see if we are in the last week; if so, we need
+ // to handle the case in which we are the first week of the
+ // next year.
+ var lastDoy = yearLength(year);
+ var lastRelDow = (relDow + lastDoy - doy) % 7;
+ if (lastRelDow < 0) {
+ lastRelDow += 7;
+ }
+ if (((6 - lastRelDow) >= cal.getMinimalDaysInFirstWeek())
+ && ((doy + 7 - relDow) > lastDoy)) {
+ week = 1;
+ }
+ } else if (week == 0) {
+ // We are the last week of the previous year.
+ var prevDoy = doy + yearLength(year - 1);
+ week = weekOfPeriod(cal, prevDoy, dow);
+ }
+
+ return week;
+}
+
+function weekOfPeriod(cal, dayOfPeriod, dayOfWeek) {
+ // Determine the day of the week of the first day of the period
+ // in question (either a year or a month). Zero represents the
+ // first day of the week on this calendar.
+ var periodStartDayOfWeek =
+ (dayOfWeek - cal.getFirstDayOfWeek() - dayOfPeriod + 1) % 7;
+ if (periodStartDayOfWeek < 0) {
+ periodStartDayOfWeek += 7;
+ }
+
+ // Compute the week number. Initially, ignore the first week, which
+ // may be fractional (or may not be). We add periodStartDayOfWeek in
+ // order to fill out the first week, if it is fractional.
+ var weekNo = Math.floor((dayOfPeriod + periodStartDayOfWeek - 1) / 7);
+
+ // If the first week is long enough, then count it. If
+ // the minimal days in the first week is one, or if the period start
+ // is zero, we always increment weekNo.
+ if ((7 - periodStartDayOfWeek) >= cal.getMinimalDaysInFirstWeek()) {
+ ++weekNo;
+ }
+
+ return weekNo;
+}
+
+
+
+
+function getEventObject(e) { // utility function to retrieve object from event
+ if (navigator.appName == "Microsoft Internet Explorer") {
+ return e.srcElement;
+ } else { // is mozilla/netscape
+ // need to crawl up the tree to get the first "real" element
+ // i.e. a tag, not raw text
+ var o = e.target;
+ while (!o.tagName) {
+ o = o.parentNode;
+ }
+ return o;
+ }
+}
+
+function addEvent(name, obj, funct) { // utility function to add event handlers
+
+ if (navigator.appName == "Microsoft Internet Explorer") {
+ obj.attachEvent("on"+name, funct);
+ } else { // is mozilla/netscape
+ obj.addEventListener(name, funct, false);
+ }
+}
+
+
+function deleteEvent(name, obj, funct) { // utility function to delete event handlers
+
+ if (navigator.appName == "Microsoft Internet Explorer") {
+ obj.detachEvent("on"+name, funct);
+ } else { // is mozilla/netscape
+ obj.removeEventListener(name, funct, false);
+ }
+}
+
+function setCursor(obj) {
+ if (navigator.appName == "Microsoft Internet Explorer") {
+ obj.style.cursor = "hand";
+ } else { // is mozilla/netscape
+ obj.style.cursor = "pointer";
+ }
+}
+
+function Point(iX, iY)
+{
+ this.x = iX;
+ this.y = iY;
+}
+
+
+function getPoint(aTag)
+{
+ var oTmp = aTag;
+ var point = new Point(0,0);
+
+ do
+ {
+ point.x += oTmp.offsetLeft;
+ point.y += oTmp.offsetTop;
+ oTmp = oTmp.offsetParent;
+ }
+ while (oTmp.tagName != "BODY" && oTmp.tagName != "HTML");
+
+ return point;
+}
+
+function toISODate(date) {
+ var s = date.getFullYear();
+ var m = date.getMonth() + 1;
+ if (m < 10) {
+ m = "0" + m;
+ }
+ var day = date.getDate();
+ if (day < 10) {
+ day = "0" + day;
+ }
+ return String(s) + String(m) + String(day);
+
+}
+
+function pad(number,X) { // utility function to pad a number to a given width
+ X = (!X ? 2 : X);
+ number = ""+number;
+ while (number.length < X) {
+ number = "0" + number;
+ }
+ return number;
+}
+
+function bw_check()
+{
+ var is_major = parseInt( navigator.appVersion );
+ this.nver = is_major;
+ this.ver = navigator.appVersion;
+ this.agent = navigator.userAgent;
+ this.dom = document.getElementById ? 1 : 0;
+ this.opera = window.opera ? 1 : 0;
+ this.ie5 = ( this.ver.indexOf( "MSIE 5" ) > -1 && this.dom && !this.opera ) ? 1 : 0;
+ this.ie6 = ( this.ver.indexOf( "MSIE 6" ) > -1 && this.dom && !this.opera ) ? 1 : 0;
+ this.ie4 = ( document.all && !this.dom && !this.opera ) ? 1 : 0;
+ this.ie = this.ie4 || this.ie5 || this.ie6;
+ this.mac = this.agent.indexOf( "Mac" ) > -1;
+ this.ns6 = ( this.dom && parseInt( this.ver ) >= 5 ) ? 1 : 0;
+ this.ie3 = ( this.ver.indexOf( "MSIE" ) && ( is_major < 4 ) );
+ this.hotjava = ( this.agent.toLowerCase().indexOf( 'hotjava' ) != -1 ) ? 1 : 0;
+ this.ns4 = ( document.layers && !this.dom && !this.hotjava ) ? 1 : 0;
+ this.bw = ( this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera );
+ this.ver3 = ( this.hotjava || this.ie3 );
+ this.opera7 = ( ( this.agent.toLowerCase().indexOf( 'opera 7' ) > -1 ) || ( this.agent.toLowerCase().indexOf( 'opera/7' ) > -1 ) );
+ this.operaOld = this.opera && !this.opera7;
+ return this;
+};
+
+
Added: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/DatePicker.js.merge-right.r384672
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/DatePicker.js.merge-right.r384672?rev=385164&view=auto
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/DatePicker.js.merge-right.r384672 (added)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/DatePicker.js.merge-right.r384672 Sat Mar 11 12:54:27 2006
@@ -0,0 +1,1024 @@
+//
+// calendar -- a javascript date picker designed for easy localization.
+//
+//
+//
+// Author: Per Norrman (pernorrman@telia.com)
+//
+// Based on Tapestry 2.3-beta1 Datepicker by Paul Geerts
+//
+// Thanks to:
+// Vladimir [vyc@quorus-ms.ru] for fixing the IE6 zIndex problem.
+//
+// The normal setup would be to have one text field for displaying the
+// selected date, and one button to show/hide the date picker control.
+// This is the recommended javascript code:
+//
+// <script language="javascript">
+// var cal;
+//
+// function init() {
+// cal = new Calendar();
+// cal.setIncludeWeek(true);
+// cal.setFormat("yyyy-MM-dd");
+// cal.setMonthNames(.....);
+// cal.setShortMonthNames(....);
+// cal.create();
+//
+// document.form.button1.onclick = function() {
+// cal.toggle(document.form.button1);
+// }
+// cal.onchange = function() {
+// document.form.textfield1.value = cal.formatDate();
+// }
+// }
+// </script>
+//
+// The init function is invoked when the body is loaded.
+//
+//
+
+function Calendar(date) {
+ if (arguments.length == 0) {
+ this._currentDate = new Date();
+ this._selectedDate = null;
+ }
+ else {
+ this._currentDate = new Date(date);
+ this._selectedDate = new Date(date);
+ }
+
+ // Accumulated days per month, for normal and for leap years.
+ // Used in week number calculations.
+ Calendar.NUM_DAYS = [0,31,59,90,120,151,181,212,243,273,304,334];
+
+ Calendar.LEAP_NUM_DAYS = [0,31,60,91,121,152,182,213,244,274,305,335];
+
+
+ this._bw = new bw_check();
+ this._showing = false;
+ this._includeWeek = false;
+ this._hideOnSelect = true;
+ this._alwaysVisible = false;
+
+ this._dateSlot = new Array(42);
+ this._weekSlot = new Array(6);
+
+ this._firstDayOfWeek = 1;
+ this._minimalDaysInFirstWeek = 4;
+
+ this._monthNames = [
+ "January", "February", "March", "April",
+ "May", "June", "July", "August",
+ "September", "October", "November", "December"
+ ];
+
+ this._shortMonthNames = [
+ "jan", "feb", "mar", "apr", "may", "jun",
+ "jul", "aug", "sep", "oct", "nov", "dec"
+ ];
+
+ // Week days start with Sunday=0, ... Saturday=6
+ this._weekDayNames = [
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+ ];
+
+ this._shortWeekDayNames =
+ ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ];
+
+ this._defaultFormat = "yyyy-MM-dd";
+
+ this._format = this._defaultFormat;
+
+ this._calDiv = null;
+
+ this._clearButtonLabel = "Clear";
+
+}
+
+/**
+ * CREATE the Calendar DOM element
+ */
+Calendar.prototype.create = function() {
+ var div;
+ var table;
+ var tbody;
+ var tr;
+ var td;
+ var dp = this;
+
+ // Create the top-level div element
+ this._calDiv = document.createElement("div");
+ this._calDiv.className = "calendar";
+ this._calDiv.style.position = "absolute";
+ this._calDiv.style.display = "none";
+ this._calDiv.style.border = "1px solid WindowText";
+ this._calDiv.style.textAlign = "center";
+ this._calDiv.style.background = "Window";
+ this._calDiv.style.zIndex = "400";
+
+
+ // header div
+ div = document.createElement("div");
+ div.className = "calendarHeader";
+ div.style.background = "ActiveCaption";
+ div.style.padding = "3px";
+ div.style.borderBottom = "1px solid WindowText";
+ 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");
+ this._previousMonth = document.createElement("button");
+ this._previousMonth.className = "prevMonthButton"
+ this._previousMonth.appendChild(document.createTextNode("<<"));
+ //this._previousMonth.appendChild(document.createTextNode(String.fromCharCode(9668)));
+ 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");
+ this._nextMonth = document.createElement("button");
+ this._nextMonth.appendChild(document.createTextNode(">>"));
+ //this._nextMonth.appendChild(document.createTextNode(String.fromCharCode(9654)));
+ this._nextMonth.className = "nextMonthButton";
+ 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";
+ table.style.font = "small-caption";
+ table.style.fontWeight = "normal";
+ table.style.textAalign = "center";
+ table.style.color = "WindowText";
+ table.style.cursor = "default";
+ table.cellPadding = "3";
+ table.cellSpacing = "0";
+
+ div.appendChild(table);
+ var thead = document.createElement("thead");
+ table.appendChild(thead);
+ tr = document.createElement("tr");
+ thead.appendChild(tr);
+
+ // weekdays header
+ if (this._includeWeek) {
+ td = document.createElement("th");
+ text = document.createTextNode("w");
+ td.appendChild(text);
+ td.className = "weekNumberHead";
+ td.style.textAlign = "left";
+ tr.appendChild(td);
+ }
+ 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";
+ td.style.fontWeight = "bold";
+ td.style.borderBottom = "1px solid WindowText";
+ 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);
+
+ if (this._includeWeek) {
+ td = document.createElement("td");
+ td.className = "weekNumber";
+ td.style.fontWeight = "normal";
+ td.style.borderRight = "1px solid WindowText";
+ td.style.textAlign = "left";
+ text = document.createTextNode(String.fromCharCode(160));
+ td.appendChild(text);
+ //setCursor(td);
+ td.align="center";
+ tr.appendChild(td);
+ var tmp = new Object();
+ tmp.tag = "WEEK";
+ tmp.value = -1;
+ tmp.data = text;
+ this._weekSlot[week] = tmp;
+ }
+
+ for(day=0; day<7; ++day) {
+ td = document.createElement("td");
+ text = document.createTextNode(String.fromCharCode(160));
+ td.appendChild(text);
+ setCursor(td);
+ td.align="center";
+ td.style.fontWeight="normal";
+
+ tr.appendChild(td);
+ var tmp = new Object();
+ tmp.tag = "DATE";
+ tmp.value = -1;
+ tmp.data = text;
+ this._dateSlot[(week*7)+day] = tmp;
+
+ }
+ }
+
+ // 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");
+ 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");
+ this._clearButton = document.createElement("button");
+ var today = new Date();
+ this._clearButton.appendChild(document.createTextNode(this._clearButtonLabel));
+ td.appendChild(this._clearButton);
+ tr.appendChild(td);
+
+
+ this._update();
+ this._updateHeader();
+
+
+
+ // IE55+ extension
+ this._previousMonth.hideFocus = true;
+ this._nextMonth.hideFocus = true;
+ this._todayButton.hideFocus = true;
+ // end IE55+ extension
+
+ // hook up events
+ // buttons
+ this._previousMonth.onclick = function () {
+ dp.prevMonth();
+ };
+
+ this._nextMonth.onclick = function () {
+ dp.nextMonth();
+ };
+
+ this._todayButton.onclick = function () {
+ dp.setSelectedDate(new Date());
+ dp.hide();
+ };
+
+ this._clearButton.onclick = function () {
+ dp.clearSelectedDate();
+ dp.hide();
+ };
+
+
+ this._calDiv.onselectstart = function () {
+ return false;
+ };
+
+ this._table.onclick = function (e) {
+ // find event
+ if (e == null) e = document.parentWindow.event;
+
+ // find td
+ var el = e.target != null ? e.target : e.srcElement;
+ 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(dp._currentDate);
+ var n = Number(el.firstChild.data);
+ if (isNaN(n) || n <= 0 || n == null)
+ return;
+
+ if (el.className == "weekNumber")
+ return;
+
+ d.setDate(n);
+ dp.setSelectedDate(d);
+
+ if (!dp._alwaysVisible && dp._hideOnSelect) {
+ dp.hide();
+ }
+
+ };
+
+
+ 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;
+ }
+
+ // ie6 extension
+ this._calDiv.onmousewheel = function (e) {
+ if (e == null) e = document.parentWindow.event;
+ var n = - e.wheelDelta / 120;
+ var d = new Date(dp._currentDate);
+ var m = d.getMonth() + n;
+ d.setMonth(m);
+
+
+ dp.setCurrentDate(d);
+
+ return false;
+ }
+
+ this._monthSelect.onchange = function(e) {
+ if (e == null) e = document.parentWindow.event;
+ e = getEventObject(e);
+ dp.setMonth(e.value);
+ }
+
+ this._monthSelect.onclick = function(e) {
+ if (e == null) e = document.parentWindow.event;
+ e = getEventObject(e);
+ e.cancelBubble = true;
+ }
+
+ this._yearSelect.onchange = function(e) {
+ if (e == null) e = document.parentWindow.event;
+ e = getEventObject(e);
+ dp.setYear(e.value);
+ }
+
+
+ document.body.appendChild(this._calDiv);
+
+
+ return this._calDiv;
+}
+
+Calendar.prototype._update = function() {
+
+
+ // Calculate the number of days in the month for the selected date
+ var date = this._currentDate;
+ var today = toISODate(new Date());
+
+
+ var selected = "";
+ if (this._selectedDate != null) {
+ selected = toISODate(this._selectedDate);
+ }
+ var current = toISODate(this._currentDate);
+ 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 = "";
+ this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
+ this._dateSlot[index].data.parentNode.style.border= "none";
+ index++;
+ }
+
+ for (i = 1; i <= monthLength; i++, index++) {
+ this._dateSlot[index].value = i;
+ this._dateSlot[index].data.data = i;
+ this._dateSlot[index].data.parentNode.className = "";
+ this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
+ this._dateSlot[index].data.parentNode.style.border= "none";
+ if (toISODate(d1) == today) {
+ this._dateSlot[index].data.parentNode.className = "today";
+ this._dateSlot[index].data.parentNode.style.fontWeight = "bold";
+ }
+ if (toISODate(d1) == current) {
+ this._dateSlot[index].data.parentNode.className += " current";
+ this._dateSlot[index].data.parentNode.style.border= "1px dotted WindowText";
+ }
+ if (toISODate(d1) == selected) {
+ this._dateSlot[index].data.parentNode.className += " selected";
+ this._dateSlot[index].data.parentNode.style.border= "1px solid WindowText";
+ }
+ 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 = "";
+ this._dateSlot[index].data.parentNode.style.fontWeight = "normal";
+ this._dateSlot[index].data.parentNode.style.border= "none";
+ ++index;
+ }
+
+ // Week numbers
+ if (this._includeWeek) {
+ d1 = new Date(date.getFullYear(), date.getMonth(), 1);
+ for (i=0; i < 6; ++i) {
+ if (i == 5 && lastDateIndex < 36) {
+ this._weekSlot[i].data.data = String.fromCharCode(160);
+ this._weekSlot[i].data.parentNode.style.borderRight = "none";
+ } else {
+ week = weekNumber(this, d1);
+ this._weekSlot[i].data.data = week;
+ this._weekSlot[i].data.parentNode.style.borderRight = "1px solid WindowText";
+ }
+ d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()+7);
+ }
+ }
+}
+
+Calendar.prototype.show = function(element) {
+ if(!this._showing) {
+ var p = getPoint(element);
+ this._calDiv.style.display = "block";
+ this._calDiv.style.top = (p.y + element.offsetHeight + 1) + "px";
+ this._calDiv.style.left = p.x + "px";
+ this._showing = true;
+
+ /* -------- */
+ if( this._bw.ie6 )
+ {
+ dw = this._calDiv.offsetWidth;
+ dh = this._calDiv.offsetHeight;
+ var els = document.getElementsByTagName("body");
+ var body = els[0];
+ if( !body ) return;
+
+ //paste iframe under the modal
+ var underDiv = this._calDiv.cloneNode(false);
+ underDiv.style.zIndex="390";
+ underDiv.style.margin = "0px";
+ underDiv.style.padding = "0px";
+ underDiv.style.display = "block";
+ underDiv.style.width = dw;
+ underDiv.style.height = dh;
+ underDiv.style.border = "1px solid WindowText";
+ underDiv.innerHTML = "<iframe width=\"100%\" height=\"100%\" frameborder=\"0\"></iframe>";
+ body.appendChild(underDiv);
+ this._underDiv = underDiv;
+ }
+ /* -------- */
+
+ if (this._calDiv.focus)
+ this._calDiv.focus();
+
+ }
+};
+
+Calendar.prototype.hide = function() {
+ if(this._showing) {
+ this._calDiv.style.display = "none";
+ this._showing = false;
+ if( this._bw.ie6 ) {
+ if( this._underDiv ) this._underDiv.removeNode(true);
+ }
+ }
+}
+
+Calendar.prototype.toggle = function(element) {
+ if(this._showing) {
+ this.hide();
+ } else {
+ this.show(element);
+ }
+}
+
+
+
+Calendar.prototype.onchange = function() {};
+
+
+Calendar.prototype.setCurrentDate = function(date) {
+ if (date == null) {
+ return;
+ }
+
+ // if string or number create a Date object
+ if (typeof date == "string" || typeof date == "number") {
+ 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();
+
+ }
+
+}
+
+Calendar.prototype.setSelectedDate = function(date) {
+ this._selectedDate = new Date(date);
+ this.setCurrentDate(this._selectedDate);
+ if (typeof this.onchange == "function") {
+ this.onchange();
+ }
+}
+
+Calendar.prototype.clearSelectedDate = function() {
+ this._selectedDate = null;
+ if (typeof this.onchange == "function") {
+ this.onchange();
+ }
+}
+
+Calendar.prototype.getElement = function() {
+ return this._calDiv;
+}
+
+Calendar.prototype.setIncludeWeek = function(v) {
+ if (this._calDiv == null) {
+ this._includeWeek = v;
+ }
+}
+
+Calendar.prototype.setClearButtonLabel = function(v) {
+ this._clearButtonLabel = v;
+}
+
+Calendar.prototype.getSelectedDate = function () {
+ if (this._selectedDate == null) {
+ return null;
+ } else {
+ return new Date(this._selectedDate);
+ }
+}
+
+Calendar.prototype.initialize = function(monthNames, shortMonthNames, weekDayNames, shortWeekDayNames, format,
+ firstDayOfWeek, includeWeek, minimalDaysInFirstWeek, clearButtonLabel)
+{
+ this.setMonthNames(monthNames);
+ this.setShortMonthNames(shortMonthNames);
+ this.setWeekDayNames(weekDayNames);
+ this.setShortWeekDayNames(shortWeekDayNames);
+ this.setFormat(format);
+ this.setFirstDayOfWeek(firstDayOfWeek);
+ this.setIncludeWeek(includeWeek);
+ this.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek);
+ this.setClearButtonLabel(clearButtonLabel);
+
+ this.create();
+}
+
+
+Calendar.prototype._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;
+ }
+ }
+
+}
+
+Calendar.prototype.setYear = function(year) {
+ var d = new Date(this._currentDate);
+ d.setFullYear(year);
+ this.setCurrentDate(d);
+}
+
+Calendar.prototype.setMonth = function (month) {
+ var d = new Date(this._currentDate);
+ d.setMonth(month);
+ this.setCurrentDate(d);
+}
+
+Calendar.prototype.nextMonth = function () {
+ this.setMonth(this._currentDate.getMonth()+1);
+}
+
+Calendar.prototype.prevMonth = function () {
+ this.setMonth(this._currentDate.getMonth()-1);
+}
+
+Calendar.prototype.setFirstDayOfWeek = function (nFirstWeekDay) {
+ this._firstDayOfWeek = nFirstWeekDay;
+}
+
+Calendar.prototype.getFirstDayOfWeek = function () {
+ return this._firstDayOfWeek;
+}
+
+Calendar.prototype.setMinimalDaysInFirstWeek = function(n) {
+ this._minimalDaysInFirstWeek = n;
+}
+
+
+Calendar.prototype.getMinimalDaysInFirstWeek = function () {
+ return this._minimalDaysInFirstWeek;
+}
+
+Calendar.prototype.setMonthNames = function(a) {
+ // sanity test
+ this._monthNames = a;
+}
+
+Calendar.prototype.setShortMonthNames = function(a) {
+ // sanity test
+ this._shortMonthNames = a;
+}
+
+Calendar.prototype.setWeekDayNames = function(a) {
+ // sanity test
+ this._weekDayNames = a;
+}
+
+Calendar.prototype.setShortWeekDayNames = function(a) {
+ // sanity test
+ this._shortWeekDayNames = a;
+}
+
+Calendar.prototype.getFormat = function() {
+ return this._format;
+}
+
+Calendar.prototype.setFormat = function(f) {
+ this._format = f;
+}
+
+Calendar.prototype.formatDate = function() {
+ if (this._selectedDate == null) {
+ return "";
+ }
+
+ var bits = new Array();
+ // work out what each bit should be
+ var date = this._selectedDate;
+ bits['d'] = date.getDate();
+ bits['dd'] = pad(date.getDate(),2);
+ bits['ddd'] = this._shortWeekDayNames[date.getDay()];
+ bits['dddd'] = this._weekDayNames[date.getDay()];
+
+ bits['M'] = date.getMonth()+1;
+ bits['MM'] = pad(date.getMonth()+1,2);
+ bits['MMM'] = this._shortMonthNames[date.getMonth()];
+ bits['MMMM'] = this._monthNames[date.getMonth()];
+
+ var yearStr = "" + date.getFullYear();
+ yearStr = (yearStr.length == 2) ? '19' + yearStr: yearStr;
+ bits['yyyy'] = yearStr;
+ bits['yy'] = bits['yyyy'].toString().substr(2,2);
+
+ bits['s'] = date.getSeconds();
+ bits['ss'] = pad(date.getSeconds(),2);
+
+ bits['m'] = date.getMinutes();
+ bits['mm'] = pad(date.getMinutes(),2);
+
+ bits['H'] = date.getHours();
+ bits['HH'] = pad(date.getHours(),2);
+
+ // do some funky regexs to replace the format string
+ // with the real values
+ var frm = new String(this._format);
+ // TAPESTRY-669: Have to be very explicit about keys, to keep functions added
+ // to Array (by the Prototype library, if its around) from getting mixed in.
+ var keys = new Array('d','dd','ddd','dddd','M','MM','MMM','MMMM','yyyy','yy', 's', 'ss', 'm',
+ 'mm', 'H', 'HH');
+ for (var i = 0; i < keys.length; i++) {
+ frm = eval("frm.replace(/\\b" + keys[i] + "\\b/,\"" + bits[keys[i]] + "\");");
+ }
+
+ return frm;
+}
+
+
+function isLeapYear(year) {
+ return ((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));
+}
+
+function yearLength(year) {
+ if (isLeapYear(year))
+ return 366;
+ else
+ return 365;
+}
+
+function dayOfYear(date) {
+ var a = Calendar.NUM_DAYS;
+ if (isLeapYear(date.getFullYear())) {
+ a = Calendar.LEAP_NUM_DAYS;
+ }
+ var month = date.getMonth();
+
+ return a[month] + date.getDate();
+}
+
+// ---------------------------------------------
+// Week number stuff
+// ---------------------------------------------
+
+function weekNumber(cal, date) {
+
+ var dow = date.getDay();
+ var doy = dayOfYear(date);
+ var year = date.getFullYear();
+
+ // Compute the week of the year. Valid week numbers run from 1 to 52
+ // or 53, depending on the year, the first day of the week, and the
+ // minimal days in the first week. Days at the start of the year may
+ // fall into the last week of the previous year; days at the end of
+ // the year may fall into the first week of the next year.
+ var relDow = (dow + 7 - cal.getFirstDayOfWeek()) % 7; // 0..6
+ var relDowJan1 = (dow - doy + 701 - cal.getFirstDayOfWeek()) % 7; // 0..6
+ var week = Math.floor((doy - 1 + relDowJan1) / 7); // 0..53
+ if ((7 - relDowJan1) >= cal.getMinimalDaysInFirstWeek()) {
+ ++week;
+ }
+
+ if (doy > 359) { // Fast check which eliminates most cases
+ // Check to see if we are in the last week; if so, we need
+ // to handle the case in which we are the first week of the
+ // next year.
+ var lastDoy = yearLength(year);
+ var lastRelDow = (relDow + lastDoy - doy) % 7;
+ if (lastRelDow < 0) {
+ lastRelDow += 7;
+ }
+ if (((6 - lastRelDow) >= cal.getMinimalDaysInFirstWeek())
+ && ((doy + 7 - relDow) > lastDoy)) {
+ week = 1;
+ }
+ } else if (week == 0) {
+ // We are the last week of the previous year.
+ var prevDoy = doy + yearLength(year - 1);
+ week = weekOfPeriod(cal, prevDoy, dow);
+ }
+
+ return week;
+}
+
+function weekOfPeriod(cal, dayOfPeriod, dayOfWeek) {
+ // Determine the day of the week of the first day of the period
+ // in question (either a year or a month). Zero represents the
+ // first day of the week on this calendar.
+ var periodStartDayOfWeek =
+ (dayOfWeek - cal.getFirstDayOfWeek() - dayOfPeriod + 1) % 7;
+ if (periodStartDayOfWeek < 0) {
+ periodStartDayOfWeek += 7;
+ }
+
+ // Compute the week number. Initially, ignore the first week, which
+ // may be fractional (or may not be). We add periodStartDayOfWeek in
+ // order to fill out the first week, if it is fractional.
+ var weekNo = Math.floor((dayOfPeriod + periodStartDayOfWeek - 1) / 7);
+
+ // If the first week is long enough, then count it. If
+ // the minimal days in the first week is one, or if the period start
+ // is zero, we always increment weekNo.
+ if ((7 - periodStartDayOfWeek) >= cal.getMinimalDaysInFirstWeek()) {
+ ++weekNo;
+ }
+
+ return weekNo;
+}
+
+
+
+
+function getEventObject(e) { // utility function to retrieve object from event
+ if (navigator.appName == "Microsoft Internet Explorer") {
+ return e.srcElement;
+ } else { // is mozilla/netscape
+ // need to crawl up the tree to get the first "real" element
+ // i.e. a tag, not raw text
+ var o = e.target;
+ while (!o.tagName) {
+ o = o.parentNode;
+ }
+ return o;
+ }
+}
+
+function addEvent(name, obj, funct) { // utility function to add event handlers
+
+ if (navigator.appName == "Microsoft Internet Explorer") {
+ obj.attachEvent("on"+name, funct);
+ } else { // is mozilla/netscape
+ obj.addEventListener(name, funct, false);
+ }
+}
+
+
+function deleteEvent(name, obj, funct) { // utility function to delete event handlers
+
+ if (navigator.appName == "Microsoft Internet Explorer") {
+ obj.detachEvent("on"+name, funct);
+ } else { // is mozilla/netscape
+ obj.removeEventListener(name, funct, false);
+ }
+}
+
+function setCursor(obj) {
+ if (navigator.appName == "Microsoft Internet Explorer") {
+ obj.style.cursor = "hand";
+ } else { // is mozilla/netscape
+ obj.style.cursor = "pointer";
+ }
+}
+
+function Point(iX, iY)
+{
+ this.x = iX;
+ this.y = iY;
+}
+
+
+function getPoint(aTag)
+{
+ var oTmp = aTag;
+ var point = new Point(0,0);
+
+ do
+ {
+ point.x += oTmp.offsetLeft;
+ point.y += oTmp.offsetTop;
+ oTmp = oTmp.offsetParent;
+ }
+ while (oTmp.tagName != "BODY" && oTmp.tagName != "HTML");
+
+ return point;
+}
+
+function toISODate(date) {
+ var s = date.getFullYear();
+ var m = date.getMonth() + 1;
+ if (m < 10) {
+ m = "0" + m;
+ }
+ var day = date.getDate();
+ if (day < 10) {
+ day = "0" + day;
+ }
+ return String(s) + String(m) + String(day);
+
+}
+
+function pad(number,X) { // utility function to pad a number to a given width
+ X = (!X ? 2 : X);
+ number = ""+number;
+ while (number.length < X) {
+ number = "0" + number;
+ }
+ return number;
+}
+
+function bw_check()
+{
+ var is_major = parseInt( navigator.appVersion );
+ this.nver = is_major;
+ this.ver = navigator.appVersion;
+ this.agent = navigator.userAgent;
+ this.dom = document.getElementById ? 1 : 0;
+ this.opera = window.opera ? 1 : 0;
+ this.ie5 = ( this.ver.indexOf( "MSIE 5" ) > -1 && this.dom && !this.opera ) ? 1 : 0;
+ this.ie6 = ( this.ver.indexOf( "MSIE 6" ) > -1 && this.dom && !this.opera ) ? 1 : 0;
+ this.ie4 = ( document.all && !this.dom && !this.opera ) ? 1 : 0;
+ this.ie = this.ie4 || this.ie5 || this.ie6;
+ this.mac = this.agent.indexOf( "Mac" ) > -1;
+ this.ns6 = ( this.dom && parseInt( this.ver ) >= 5 ) ? 1 : 0;
+ this.ie3 = ( this.ver.indexOf( "MSIE" ) && ( is_major < 4 ) );
+ this.hotjava = ( this.agent.toLowerCase().indexOf( 'hotjava' ) != -1 ) ? 1 : 0;
+ this.ns4 = ( document.layers && !this.dom && !this.hotjava ) ? 1 : 0;
+ this.bw = ( this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera );
+ this.ver3 = ( this.hotjava || this.ie3 );
+ this.opera7 = ( ( this.agent.toLowerCase().indexOf( 'opera 7' ) > -1 ) || ( this.agent.toLowerCase().indexOf( 'opera/7' ) > -1 ) );
+ this.operaOld = this.opera && !this.opera7;
+ return this;
+};
+
+
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.java?rev=385164&r1=385163&r2=385164&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.java Sat Mar 11 12:54:27 2006
@@ -1,4 +1,4 @@
-// Copyright 2004, 2005, 2006 The Apache Software Foundation
+// Copyright 2004, 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
package org.apache.tapestry.form;
+import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Location;
import org.apache.tapestry.AbstractComponent;
import org.apache.tapestry.IActionListener;
@@ -35,47 +36,38 @@
import org.apache.tapestry.web.WebResponse;
/**
- * Component which contains form element components. Forms use the action or
- * direct services to handle the form submission. A Form will wrap other
- * components and static HTML, including form components such as
- * {@link TextArea}, {@link TextField}, {@link Checkbox}, etc. [ <a
+ * Component which contains form element components. Forms use the action or direct services to
+ * handle the form submission. A Form will wrap other components and static HTML, including form
+ * components such as {@link TextArea}, {@link TextField}, {@link Checkbox}, etc. [ <a
* href="../../../../../ComponentReference/Form.html">Component Reference </a>]
* <p>
- * When a form is submitted, it continues through the rewind cycle until
- * <em>after</em> all of its wrapped elements have renderred. As the form
- * component render (in the rewind cycle), they will be updating properties of
- * the containing page and notifying thier listeners. Again: each form component
- * is responsible not only for rendering HTML (to present the form), but for
- * handling it's share of the form submission.
+ * When a form is submitted, it continues through the rewind cycle until <em>after</em> all of its
+ * wrapped elements have renderred. As the form component render (in the rewind cycle), they will be
+ * updating properties of the containing page and notifying thier listeners. Again: each form
+ * component is responsible not only for rendering HTML (to present the form), but for handling it's
+ * share of the form submission.
* <p>
* Only after all that is done will the Form notify its listener.
* <p>
- * Starting in release 1.0.2, a Form can use either the direct service or the
- * action service. The default is the direct service, even though in earlier
- * releases, only the action service was available.
+ * Starting in release 1.0.2, a Form can use either the direct service or the action service. The
+ * default is the direct service, even though in earlier releases, only the action service was
+ * available.
* <p>
- * Release 4.0 adds two new listeners, {@link #getCancel()} and
- * {@link #getRefresh()} and corresponding client-side behavior to force a form
- * to refresh (update, bypassing input field validation) or cancel (update
- * immediately).
+ * Release 4.0 adds two new listeners, {@link #getCancel()} and {@link #getRefresh()} and
+ * corresponding client-side behavior to force a form to refresh (update, bypassing input field
+ * validation) or cancel (update immediately).
*
* @author Howard Lewis Ship, David Solis
*/
public abstract class Form extends AbstractComponent implements IForm, IDirect
{
-
private String _name;
private FormSupport _formSupport;
- /**
- * Inner class to render informal parameters, passed to the
- * {@link FormSupport}.
- */
private class RenderInformalParameters implements IRender
{
-
public void render(IMarkupWriter writer, IRequestCycle cycle)
{
renderInformalParameters(writer, cycle);
@@ -85,22 +77,20 @@
private IRender _renderInformalParameters;
/**
- * Returns the currently active {@link IForm}, or null if no form is
- * active. This is a convienience method, the result will be null, or an
- * instance of {@link IForm}, but not necessarily a <code>Form</code>.
+ * Returns the currently active {@link IForm}, or null if no form is active. This is a
+ * convienience method, the result will be null, or an instance of {@link IForm}, but not
+ * necessarily a <code>Form</code>.
*
- * @deprecated Use {@link TapestryUtils#getForm(IRequestCycle, IComponent)}
- * instead.
+ * @deprecated Use {@link TapestryUtils#getForm(IRequestCycle, IComponent)} instead.
*/
public static IForm get(IRequestCycle cycle)
{
- return (IForm)cycle.getAttribute(ATTRIBUTE_NAME);
+ return (IForm) cycle.getAttribute(ATTRIBUTE_NAME);
}
/**
- * Indicates to any wrapped form components that they should respond to the
- * form submission.
+ * Indicates to any wrapped form components that they should respond to the form submission.
*
* @throws ApplicationRuntimeException
* if not rendering.
@@ -108,7 +98,8 @@
public boolean isRewinding()
{
- if (!isRendering()) throw Tapestry.createRenderOnlyPropertyException(this, "rewinding");
+ if (!isRendering())
+ throw Tapestry.createRenderOnlyPropertyException(this, "rewinding");
return _formSupport.isRewinding();
}
@@ -132,8 +123,7 @@
/**
* Returns true if this Form is configured to use the direct service.
* <p>
- * This is derived from the direct parameter, and defaults to true if not
- * bound.
+ * This is derived from the direct parameter, and defaults to true if not bound.
*
* @since 1.0.2
*/
@@ -141,8 +131,8 @@
public abstract boolean isDirect();
/**
- * Returns true if the stateful parameter is bound to a true value. If
- * stateful is not bound, also returns the default, true.
+ * Returns true if the stateful parameter is bound to a true value. If stateful is not bound,
+ * also returns the default, true.
*
* @since 1.0.1
*/
@@ -153,12 +143,12 @@
}
/**
- * Constructs a unique identifier (within the Form). The identifier consists
- * of the component's id, with an index number added to ensure uniqueness.
+ * Constructs a unique identifier (within the Form). The identifier consists of the component's
+ * id, with an index number added to ensure uniqueness.
* <p>
* Simply invokes
- * {@link #getElementId(org.apache.tapestry.form.IFormComponent, java.lang.String)}with
- * the component's id.
+ * {@link #getElementId(org.apache.tapestry.form.IFormComponent, java.lang.String)}with the
+ * component's id.
*
* @since 1.0.2
*/
@@ -169,11 +159,11 @@
}
/**
- * Constructs a unique identifier from the base id. If possible, the id is
- * used as-is. Otherwise, a unique identifier is appended to the id.
+ * Constructs a unique identifier from the base id. If possible, the id is used as-is.
+ * Otherwise, a unique identifier is appended to the id.
* <p>
- * This method is provided simply so that some components ({@link ImageSubmit})
- * have more specific control over their names.
+ * This method is provided simply so that some components ({@link ImageSubmit}) have more
+ * specific control over their names.
*
* @since 1.0.3
*/
@@ -184,16 +174,15 @@
}
/**
- * Returns the name generated for the form. This is used to faciliate
- * components that write JavaScript and need to access the form or its
- * contents.
+ * Returns the name generated for the form. This is used to faciliate components that write
+ * JavaScript and need to access the form or its contents.
* <p>
- * This value is generated when the form renders, and is not cleared. If the
- * Form is inside a {@link org.apache.tapestry.components.Foreach}, this
- * will be the most recently generated name for the Form.
+ * This value is generated when the form renders, and is not cleared. If the Form is inside a
+ * {@link org.apache.tapestry.components.Foreach}, this will be the most recently generated
+ * name for the Form.
* <p>
- * This property is exposed so that sophisticated applications can write
- * JavaScript handlers for the form and components within the form.
+ * This property is exposed so that sophisticated applications can write JavaScript handlers for
+ * the form and components within the form.
*
* @see AbstractFormComponent#getName()
*/
@@ -220,7 +209,8 @@
IValidationDelegate delegate = getDelegate();
- if (delegate != null) delegate.setFormComponent(null);
+ if (delegate != null)
+ delegate.setFormComponent(null);
super.cleanupAfterRender(cycle);
}
@@ -252,11 +242,12 @@
_name = baseName + getResponse().getNamespace();
- if (_renderInformalParameters == null) _renderInformalParameters = new RenderInformalParameters();
+ if (_renderInformalParameters == null)
+ _renderInformalParameters = new RenderInformalParameters();
ILink link = getLink(cycle, actionId);
-
- _formSupport.render(getMethod(), _renderInformalParameters, link, getScheme());
+
+ _formSupport.render(getMethod(), _renderInformalParameters, link, getScheme(), getPort());
}
IActionListener findListener(String mode)
@@ -267,20 +258,22 @@
result = getCancel();
else if (mode.equals(FormConstants.SUBMIT_REFRESH))
result = getRefresh();
- else if (!getDelegate().getHasErrors()) result = getSuccess();
+ else if (!getDelegate().getHasErrors())
+ result = getSuccess();
// If not success, cancel or refresh, or the corresponding listener
// is itself null, then use the default listener
// (which may be null as well!).
- if (result == null) result = getListener();
+ if (result == null)
+ result = getListener();
return result;
}
/**
- * Construct a form name for use with the action service. This
- * implementation returns "Form" appended with the actionId.
+ * Construct a form name for use with the action service. This implementation returns "Form"
+ * appended with the actionId.
*
* @since 4.0
*/
@@ -291,10 +284,9 @@
}
/**
- * Constructs a form name for use with the direct service. This
- * implementation bases the form name on the form component's id (but
- * ensures it is unique). Remember that Tapestry assigns an "ugly" id if an
- * explicit component id is not provided.
+ * Constructs a form name for use with the direct service. This implementation bases the form
+ * name on the form component's id (but ensures it is unique). Remember that Tapestry assigns an
+ * "ugly" id if an explicit component id is not provided.
*
* @since 4.0
*/
@@ -347,8 +339,7 @@
}
/**
- * Builds the EngineServiceLink for the form, using either the direct or
- * action service.
+ * Builds the EngineServiceLink for the form, using either the direct or action service.
*
* @since 1.0.3
*/
@@ -398,6 +389,9 @@
/** scheme parameter, may be null */
public abstract String getScheme();
+
+ /** port , may be null */
+ public abstract Integer getPort();
public void setEncodingType(String encodingType)
{
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.js
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.js?rev=385164&r1=385163&r2=385164&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.js (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.js Sat Mar 11 12:54:27 2006
@@ -85,14 +85,22 @@
Tapestry.set_focus = function (field)
{
- if (typeof field == "string")
- field = this.find(field);
-
- if (field.focus)
- field.focus();
-
- if (field.select)
- field.select();
+ if (typeof field == "string") {
+ field = this.find(field);
+
+ if (field) {
+ if (!field.disabled && field.clientWidth > 0) {
+ if (field.focus) {
+ field.focus();
+ }
+ if (field.isContentEditable || field.isContentEditable == null) {
+ if (field.select) {
+ field.select();
+ }
+ }
+ }
+ }
+ }
}
Tapestry.trim_field_value = function(fieldId)
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.jwc
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.jwc?rev=385164&r1=385163&r2=385164&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.jwc (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/Form.jwc Sat Mar 11 12:54:27 2006
@@ -109,6 +109,13 @@
</description>
</parameter>
+ <parameter name="port">
+ <description>
+ Forces the link to be generated as an absolute URL with the given port
+ (unless the port matches the port for the current request).
+ </description>
+ </parameter>
+
<reserved-parameter name="action"/>
<reserved-parameter name="name"/>
<reserved-parameter name="onsubmit"/>
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormEventType.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormEventType.java?rev=385164&r1=385163&r2=385164&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormEventType.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormEventType.java Sat Mar 11 12:54:27 2006
@@ -1,4 +1,4 @@
-// Copyright 2004, 2005, 2006 The Apache Software Foundation
+// Copyright 2004, 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
* a future release of Tapestry.
*/
-public final class FormEventType
+public class FormEventType
{
/**
* Form event triggered when the form is submitted. Allows an event handler to perform any final
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormMessages.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormMessages.java?rev=385164&r1=385163&r2=385164&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormMessages.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormMessages.java Sat Mar 11 12:54:27 2006
@@ -1,4 +1,4 @@
-// Copyright 2005, 2006 The Apache Software Foundation
+// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package org.apache.tapestry.form;
import org.apache.hivemind.HiveMind;
-import org.apache.hivemind.Messages;
import org.apache.hivemind.impl.MessageFormatter;
import org.apache.tapestry.IComponent;
@@ -23,48 +22,51 @@
* @author Howard M. Lewis Ship
* @since 4.0
*/
-final class FormMessages
+class FormMessages
{
-
- private final static Messages MESSAGES = new MessageFormatter(FormMessages.class);
-
- /** @since 4.1 */
- private FormMessages()
- {
- }
+ private final static MessageFormatter _formatter = new MessageFormatter(FormMessages.class);
static String formTooManyIds(IComponent form, int actualCount, IComponent component)
{
- return MESSAGES.format("form-too-many-ids", form.getExtendedId(), new Integer(actualCount), component
- .getExtendedId());
+ return _formatter.format(
+ "form-too-many-ids",
+ form.getExtendedId(),
+ new Integer(actualCount),
+ component.getExtendedId());
}
- static String formIdMismatch(IComponent form, int mismatchIndex, String expectedId, String actualId,
- IComponent component)
- {
- return MESSAGES.format("form-id-mismatch", new Object[] { form.getExtendedId(), new Integer(mismatchIndex + 1),
- expectedId, actualId, component.getExtendedId() });
+ static String formIdMismatch(IComponent form, int mismatchIndex, String expectedId,
+ String actualId, IComponent component)
+ {
+ return _formatter.format("form-id-mismatch", new Object[]
+ { form.getExtendedId(), new Integer(mismatchIndex + 1), expectedId, actualId,
+ component.getExtendedId() });
}
static String formTooFewIds(IComponent form, int remainingCount, String nextExpectedId)
{
- return MESSAGES.format("form-too-few-ids", form.getExtendedId(), new Integer(remainingCount), nextExpectedId);
+ return _formatter.format("form-too-few-ids", form.getExtendedId(), new Integer(
+ remainingCount), nextExpectedId);
}
- static String encodingTypeContention(IComponent form, String establishedEncodingType, String newEncodingType)
+ static String encodingTypeContention(IComponent form, String establishedEncodingType,
+ String newEncodingType)
{
- return MESSAGES.format("encoding-type-contention", form.getExtendedId(), establishedEncodingType,
+ return _formatter.format(
+ "encoding-type-contention",
+ form.getExtendedId(),
+ establishedEncodingType,
newEncodingType);
}
static String fieldAlreadyPrerendered(IComponent field)
{
- return MESSAGES.format("field-already-prerendered", field);
+ return _formatter.format("field-already-prerendered", field);
}
static String linkSubmitMayNotNest(IComponent inner, IComponent outer)
{
- return MESSAGES.format("link-submit-may-not-nest", inner.getExtendedId(), outer.getExtendedId(), HiveMind
- .getLocationString(outer));
+ return _formatter.format("link-submit-may-not-nest", inner.getExtendedId(), outer
+ .getExtendedId(), HiveMind.getLocationString(outer));
}
-}
+}
\ No newline at end of file
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormSupport.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormSupport.java?rev=385164&r1=385163&r2=385164&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormSupport.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormSupport.java Sat Mar 11 12:54:27 2006
@@ -44,7 +44,7 @@
* non-null, and the scheme does not match the current request's scheme, then an
* absolute URL with the specified scheme will be generated, rather than a URI.
*/
- public void render(String method, IRender informalParametersRenderer, ILink link, String scheme);
+ public void render(String method, IRender informalParametersRenderer, ILink link, String scheme, Integer port);
/**
* Invoked to rewind the form, which renders the body of the form, allowing form element
@@ -55,4 +55,4 @@
* {@link FormConstants#SUBMIT_CANCEL} or {@link FormConstants#SUBMIT_REFRESH}.
*/
public String rewind();
-}
\ No newline at end of file
+}
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java?rev=385164&r1=385163&r2=385164&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/FormSupportImpl.java Sat Mar 11 12:54:27 2006
@@ -78,14 +78,14 @@
public static final String SCRIPT = "/org/apache/tapestry/form/Form.js";
+ private final static Set _standardReservedIds;
+
/**
* Attribute set to true when a field has been focused; used to prevent conflicting JavaScript
* for field focusing from being emitted.
*/
public static final String FIELD_FOCUS_ATTRIBUTE = "org.apache.tapestry.field-focused";
-
- private static final Set RESERVED_IDS;
static
{
@@ -97,10 +97,10 @@
set.add(SUBMIT_MODE);
set.add(FormConstants.SUBMIT_NAME_PARAMETER);
- RESERVED_IDS = Collections.unmodifiableSet(set);
+ _standardReservedIds = Collections.unmodifiableSet(set);
}
- private static final Set SUBMIT_MODES;
+ private final static Set _submitModes;
static
{
@@ -109,7 +109,7 @@
set.add(FormConstants.SUBMIT_NORMAL);
set.add(FormConstants.SUBMIT_REFRESH);
- SUBMIT_MODES = Collections.unmodifiableSet(set);
+ _submitModes = Collections.unmodifiableSet(set);
}
/**
@@ -253,7 +253,7 @@
// Reserve the name.
- if (!RESERVED_IDS.contains(name))
+ if (!_standardReservedIds.contains(name))
{
_elementIdAllocator.allocateId(name);
@@ -459,8 +459,9 @@
for (int i = 0; i < ids.length; i++)
_elementIdAllocator.allocateId(ids[i]);
}
-
- public void render(String method, IRender informalParametersRenderer, ILink link, String scheme)
+
+ public void render(String method, IRender informalParametersRenderer, ILink link,
+ String scheme, Integer port)
{
String formId = _form.getName();
@@ -486,9 +487,10 @@
_form.renderBody(nested, _cycle);
runDeferredRunnables();
-
- writeTag(_writer, method, link.getURL(scheme, null, 0, null, false));
-
+
+ int portI = (port == null) ? 0 : port.intValue();
+ writeTag(_writer, method, link.getURL(scheme, null, portI, null, false));
+
// For HTML compatibility
_writer.attribute("name", formId);
@@ -579,7 +581,7 @@
runDeferredRunnables();
- if (SUBMIT_MODES.contains(mode))
+ if (_submitModes.contains(mode))
return mode;
// Either something wacky on the client side, or a client without
@@ -739,4 +741,4 @@
_delegate.registerForFocus(field, priority);
}
-}
+}
\ No newline at end of file
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/IPropertySelectionModel.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/IPropertySelectionModel.java?rev=385164&r1=385163&r2=385164&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/IPropertySelectionModel.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/IPropertySelectionModel.java Sat Mar 11 12:54:27 2006
@@ -41,20 +41,20 @@
* Returns the number of possible options.
*/
- int getOptionCount();
+ public int getOptionCount();
/**
* Returns one possible option that will be assigned to the server-side property.
*/
- Object getOption(int index);
+ public Object getOption(int index);
/**
* Returns the label for an option. It is the responsibility of the adaptor to make this value
* localized.
*/
- String getLabel(int index);
+ public String getLabel(int index);
/**
* Returns a String used to represent the option in the HTML (as the value of an <option>
@@ -62,12 +62,12 @@
* into an array.
*/
- String getValue(int index);
+ public String getValue(int index);
/**
* Returns the option corresponding to a value. This is used when interpreting submitted form
* parameters.
*/
- Object translateValue(String value);
-}
+ public Object translateValue(String value);
+}
\ No newline at end of file
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/IPropertySelectionRenderer.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/IPropertySelectionRenderer.java?rev=385164&r1=385163&r2=385164&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/IPropertySelectionRenderer.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/IPropertySelectionRenderer.java Sat Mar 11 12:54:27 2006
@@ -32,14 +32,14 @@
*
**/
- void beginRender(PropertySelection component, IMarkupWriter writer, IRequestCycle cycle);
+ public void beginRender(PropertySelection component, IMarkupWriter writer, IRequestCycle cycle);
/**
* Invoked for each element obtained from the {@link IPropertySelectionModel model}.
*
**/
- void renderOption(
+ public void renderOption(
PropertySelection component,
IMarkupWriter writer,
IRequestCycle cycle,
@@ -53,5 +53,5 @@
*
**/
- void endRender(PropertySelection component, IMarkupWriter writer, IRequestCycle cycle);
-}
+ public void endRender(PropertySelection component, IMarkupWriter writer, IRequestCycle cycle);
+}
\ No newline at end of file
Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/ImageSubmit.jwc
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/ImageSubmit.jwc?rev=385164&r1=385163&r2=385164&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/ImageSubmit.jwc (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/form/ImageSubmit.jwc Sat Mar 11 12:54:27 2006
@@ -57,19 +57,15 @@
<parameter name="listener">
<description>
- A listener that is notified when this component is triggered.
- The listener is notified immediately when the component is identified as clicked.
- This behaviour is useful when the component is in a loop, but not all elements
- enclosed by the Form would have had a chance to update their properties at the
- time of the listener invocation. Please see the 'action' parameter as an alternative.
+ Notified when the button is clicked.
</description>
</parameter>
<parameter name="action">
<description>
- A listener that is notified when this component is triggered.
- The listener notification is delayed until all components enclosed by the Form
- have had a chance to update their properties.
+ A listener that is notified if this component is triggered
+ just before the form's listener, after all components
+ enclosed by the Form have had a chance to update their properties.
</description>
</parameter>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org