|
0
|
1 |
/* |
|
|
2 |
* Copyright (C) 2004 Baron Schwartz <baron at sequent dot org> |
|
|
3 |
* |
|
|
4 |
* This program is free software; you can redistribute it and/or modify it |
|
|
5 |
* under the terms of the GNU Lesser General Public License as published by the |
|
|
6 |
* Free Software Foundation, version 2.1. |
|
|
7 |
* |
|
|
8 |
* This program is distributed in the hope that it will be useful, but WITHOUT |
|
|
9 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
|
10 |
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
|
11 |
* details. |
|
|
12 |
* |
|
|
13 |
* $Revision: 1.1 $ |
|
|
14 |
*/ |
|
|
15 |
|
|
|
16 |
// Shows or hides the date chooser on the page |
|
|
17 |
function showChooser(obj, inputId, divId, start, end, format, isTimeChooser) { |
|
|
18 |
if (document.getElementById) { |
|
|
19 |
var input = document.getElementById(inputId); |
|
|
20 |
var div = document.getElementById(divId); |
|
|
21 |
if (input !== undefined && div !== undefined) { |
|
|
22 |
if (input.DateChooser === undefined) { |
|
|
23 |
input.DateChooser = new DateChooser(input, div, start, end, format, isTimeChooser); |
|
|
24 |
} |
|
|
25 |
input.DateChooser.setDate(Date.parseDate(input.value, format)); |
|
|
26 |
if (input.DateChooser.isVisible()) { |
|
|
27 |
input.DateChooser.hide(); |
|
|
28 |
} |
|
|
29 |
else { |
|
|
30 |
input.DateChooser.show(); |
|
|
31 |
} |
|
|
32 |
} |
|
|
33 |
} |
|
|
34 |
} |
|
|
35 |
|
|
|
36 |
// Sets a date on the object attached to 'inputId' |
|
|
37 |
function dateChooserSetDate(inputId, value) { |
|
|
38 |
var input = document.getElementById(inputId); |
|
|
39 |
if (input !== undefined && input.DateChooser !== undefined) { |
|
|
40 |
input.DateChooser.setDate(Date.parseDate(value, input.DateChooser._format)); |
|
|
41 |
if (input.DateChooser.isTimeChooser()) { |
|
|
42 |
var theForm = input.form; |
|
|
43 |
var prefix = input.DateChooser._prefix; |
|
|
44 |
input.DateChooser.setTime( |
|
|
45 |
parseInt(theForm.elements[prefix + 'hour'].options[ |
|
|
46 |
theForm.elements[prefix + 'hour'].selectedIndex].value) |
|
|
47 |
+ parseInt(theForm.elements[prefix + 'ampm'].options[ |
|
|
48 |
theForm.elements[prefix + 'ampm'].selectedIndex].value), |
|
|
49 |
parseInt(theForm.elements[prefix + 'min'].options[ |
|
|
50 |
theForm.elements[prefix + 'min'].selectedIndex].value)); |
|
|
51 |
} |
|
|
52 |
input.value = input.DateChooser.getValue(); |
|
|
53 |
input.DateChooser.hide(); |
|
|
54 |
} |
|
|
55 |
} |
|
|
56 |
|
|
|
57 |
// The callback function for when someone changes the pulldown menus on the date |
|
|
58 |
// chooser |
|
|
59 |
function dateChooserDateChange(theForm, prefix) { |
|
|
60 |
var input = document.getElementById( |
|
|
61 |
theForm.elements[prefix + 'inputId'].value); |
|
|
62 |
var newDate = new Date( |
|
|
63 |
theForm.elements[prefix + 'year'].options[ |
|
|
64 |
theForm.elements[prefix + 'year'].selectedIndex].value, |
|
|
65 |
theForm.elements[prefix + 'month'].options[ |
|
|
66 |
theForm.elements[prefix + 'month'].selectedIndex].value, |
|
|
67 |
1); |
|
|
68 |
// Try to preserve the day of month (watch out for months with 31 days) |
|
|
69 |
newDate.setDate(Math.max(1, Math.min(newDate.getDaysInMonth(), |
|
|
70 |
input.DateChooser._date.getDate()))); |
|
|
71 |
input.DateChooser.setDate(newDate); |
|
|
72 |
if (input.DateChooser.isTimeChooser()) { |
|
|
73 |
input.DateChooser.setTime( |
|
|
74 |
parseInt(theForm.elements[prefix + 'hour'].options[ |
|
|
75 |
theForm.elements[prefix + 'hour'].selectedIndex].value) |
|
|
76 |
+ parseInt(theForm.elements[prefix + 'ampm'].options[ |
|
|
77 |
theForm.elements[prefix + 'ampm'].selectedIndex].value), |
|
|
78 |
parseInt(theForm.elements[prefix + 'min'].options[ |
|
|
79 |
theForm.elements[prefix + 'min'].selectedIndex].value)); |
|
|
80 |
} |
|
|
81 |
input.DateChooser.show(); |
|
|
82 |
} |
|
|
83 |
|
|
|
84 |
// Gets the absolute position on the page of the element passed in |
|
|
85 |
function getAbsolutePosition(obj) { |
|
|
86 |
var result = [0, 0]; |
|
|
87 |
while (obj != null) { |
|
|
88 |
result[0] += obj.offsetTop; |
|
|
89 |
result[1] += obj.offsetLeft; |
|
|
90 |
obj = obj.offsetParent; |
|
|
91 |
} |
|
|
92 |
return result; |
|
|
93 |
} |
|
|
94 |
|
|
|
95 |
// DateChooser constructor |
|
|
96 |
function DateChooser(input, div, start, end, format, isTimeChooser) { |
|
|
97 |
this._input = input; |
|
|
98 |
this._div = div; |
|
|
99 |
this._start = start; |
|
|
100 |
this._end = end; |
|
|
101 |
this._format = format; |
|
|
102 |
this._date = new Date(); |
|
|
103 |
this._isTimeChooser = isTimeChooser; |
|
|
104 |
// Choose a random prefix for all pulldown menus |
|
|
105 |
this._prefix = ""; |
|
|
106 |
var letters = ["a", "b", "c", "d", "e", "f", "h", "i", "j", "k", "l", |
|
|
107 |
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]; |
|
|
108 |
for (var i = 0; i < 10; ++i) { |
|
|
109 |
this._prefix += letters[Math.floor(Math.random() * letters.length)]; |
|
|
110 |
} |
|
|
111 |
} |
|
|
112 |
|
|
|
113 |
// DateChooser prototype variables |
|
|
114 |
DateChooser.prototype._isVisible = false; |
|
|
115 |
|
|
|
116 |
// Returns true if the chooser is currently visible |
|
|
117 |
DateChooser.prototype.isVisible = function() { |
|
|
118 |
return this._isVisible; |
|
|
119 |
} |
|
|
120 |
|
|
|
121 |
// Returns true if the chooser is to allow choosing the time as well as the date |
|
|
122 |
DateChooser.prototype.isTimeChooser = function() { |
|
|
123 |
return this._isTimeChooser; |
|
|
124 |
} |
|
|
125 |
|
|
|
126 |
// Gets the value, as a formatted string, of the date attached to the chooser |
|
|
127 |
DateChooser.prototype.getValue = function() { |
|
|
128 |
return this._date.dateFormat(this._format); |
|
|
129 |
} |
|
|
130 |
|
|
|
131 |
// Hides the chooser |
|
|
132 |
DateChooser.prototype.hide = function() { |
|
|
133 |
this._div.style.visibility = "hidden"; |
|
|
134 |
this._div.style.display = "none"; |
|
|
135 |
this._div.innerHTML = ""; |
|
|
136 |
this._isVisible = false; |
|
|
137 |
} |
|
|
138 |
|
|
|
139 |
// Shows the chooser on the page |
|
|
140 |
DateChooser.prototype.show = function() { |
|
|
141 |
// calculate the position before making it visible |
|
|
142 |
var inputPos = getAbsolutePosition(this._input); |
|
|
143 |
this._div.style.top = (inputPos[0] + this._input.offsetHeight) + "px"; |
|
|
144 |
this._div.style.left = (inputPos[1] + this._input.offsetWidth) + "px"; |
|
|
145 |
this._div.innerHTML = this.createChooserHtml(); |
|
|
146 |
this._div.style.display = "block"; |
|
|
147 |
this._div.style.visibility = "visible"; |
|
|
148 |
this._div.style.position = "absolute"; |
|
|
149 |
this._isVisible = true; |
|
|
150 |
} |
|
|
151 |
|
|
|
152 |
// Sets the date to what is in the input box |
|
|
153 |
DateChooser.prototype.initializeDate = function() { |
|
|
154 |
if (this._input.value != null && this._input.value != "") { |
|
|
155 |
this._date = Date.parseDate(this._input.value, this._format); |
|
|
156 |
} |
|
|
157 |
else { |
|
|
158 |
this._date = new Date(); |
|
|
159 |
} |
|
|
160 |
} |
|
|
161 |
|
|
|
162 |
// Sets the date attached to the chooser |
|
|
163 |
DateChooser.prototype.setDate = function(date) { |
|
|
164 |
this._date = date ? date : new Date(); |
|
|
165 |
} |
|
|
166 |
|
|
|
167 |
// Sets the time portion of the date attached to the chooser |
|
|
168 |
DateChooser.prototype.setTime = function(hour, minute) { |
|
|
169 |
this._date.setHours(hour); |
|
|
170 |
this._date.setMinutes(minute); |
|
|
171 |
} |
|
|
172 |
|
|
|
173 |
// Creates the HTML for the whole chooser |
|
|
174 |
DateChooser.prototype.createChooserHtml = function() { |
|
|
175 |
var formHtml = "<input type=\"hidden\" name=\"" |
|
|
176 |
+ this._prefix + "inputId\" value=\"" |
|
|
177 |
+ this._input.getAttribute('id') + "\">" |
|
|
178 |
+ "\r\n <select name=\"" + this._prefix |
|
|
179 |
+ "month\" onChange=\"dateChooserDateChange(this.form, '" |
|
|
180 |
+ this._prefix + "');\">"; |
|
|
181 |
for (var monIndex = 0; monIndex <= 11; monIndex++) { |
|
|
182 |
formHtml += "\r\n <option value=\"" + monIndex + "\"" |
|
|
183 |
+ (monIndex == this._date.getMonth() ? " selected=\"1\"" : "") |
|
|
184 |
+ ">" + Date.monthNames[monIndex] + "</option>"; |
|
|
185 |
} |
|
|
186 |
formHtml += "\r\n </select>\r\n <select name=\"" |
|
|
187 |
+ this._prefix + "year\" onChange=\"dateChooserDateChange(this.form, '" |
|
|
188 |
+ this._prefix + "');\">"; |
|
|
189 |
for (var i = this._start; i <= this._end; ++i) { |
|
|
190 |
formHtml += "\r\n <option value=\"" + i + "\"" |
|
|
191 |
+ (i == this._date.getFullYear() ? " selected=\"1\"" : "") |
|
|
192 |
+ ">" + i + "</option>"; |
|
|
193 |
} |
|
|
194 |
formHtml += "\r\n </select>"; |
|
|
195 |
formHtml += this.createCalendarHtml(); |
|
|
196 |
if (this._isTimeChooser) { |
|
|
197 |
formHtml += this.createTimeChooserHtml(); |
|
|
198 |
} |
|
|
199 |
return formHtml; |
|
|
200 |
} |
|
|
201 |
|
|
|
202 |
// Creates the extra HTML needed for choosing the time |
|
|
203 |
DateChooser.prototype.createTimeChooserHtml = function() { |
|
|
204 |
// Add hours |
|
|
205 |
var result = "\r\n <select name=\"" + this._prefix + "hour\">"; |
|
|
206 |
for (var i = 0; i < 12; ++i) { |
|
|
207 |
result += "\r\n <option value=\"" + i + "\"" |
|
|
208 |
+ (((this._date.getHours() % 12) == i) ? " selected=\"1\">" : ">") |
|
|
209 |
+ i + "</option>"; |
|
|
210 |
} |
|
|
211 |
// Add extra entry for 12:00 |
|
|
212 |
result += "\r\n <option value=\"0\">12</option>"; |
|
|
213 |
result += "\r\n </select>"; |
|
|
214 |
// Add minutes |
|
|
215 |
result += "\r\n <select name=\"" + this._prefix + "min\">"; |
|
|
216 |
for (var i = 0; i < 60; i += 15) { |
|
|
217 |
result += "\r\n <option value=\"" + i + "\"" |
|
|
218 |
+ ((this._date.getMinutes() == i) ? " selected=\"1\">" : ">") |
|
|
219 |
+ String.leftPad(i, 2, '0') + "</option>"; |
|
|
220 |
} |
|
|
221 |
result += "\r\n </select>"; |
|
|
222 |
// Add AM/PM |
|
|
223 |
result += "\r\n <select name=\"" + this._prefix + "ampm\">"; |
|
|
224 |
result += "\r\n <option value=\"0\"" |
|
|
225 |
+ (this._date.getHours() < 12 ? " selected=\"1\">" : ">") |
|
|
226 |
+ "AM</option>"; |
|
|
227 |
result += "\r\n <option value=\"12\"" |
|
|
228 |
+ (this._date.getHours() >= 12 ? " selected=\"1\">" : ">") |
|
|
229 |
+ "PM</option>"; |
|
|
230 |
result += "\r\n </select>"; |
|
|
231 |
return result; |
|
|
232 |
} |
|
|
233 |
|
|
|
234 |
// Creates the HTML for the actual calendar part of the chooser |
|
|
235 |
DateChooser.prototype.createCalendarHtml = function() { |
|
|
236 |
var result = "\r\n<table cellspacing=\"0\" class=\"dateChooser\">" |
|
|
237 |
+ "\r\n <tr><th>S</th><th>M</th><th>T</th>" |
|
|
238 |
+ "<th>W</th><th>T</th><th>F</th><th>S</th></tr>\r\n <tr>"; |
|
|
239 |
// Fill up the days of the week until we get to the first day of the month |
|
|
240 |
var firstDay = this._date.getFirstDayOfMonth(); |
|
|
241 |
var lastDay = this._date.getLastDayOfMonth(); |
|
|
242 |
if (firstDay != 0) { |
|
|
243 |
result += "<td colspan=\"" + firstDay + "\"> </td>"; |
|
|
244 |
} |
|
|
245 |
// Fill in the days of the month |
|
|
246 |
var i = 0; |
|
|
247 |
while (i < this._date.getDaysInMonth()) { |
|
|
248 |
if (((i++ + firstDay) % 7) == 0) { |
|
|
249 |
result += "</tr>\r\n <tr>"; |
|
|
250 |
} |
|
|
251 |
var thisDay = new Date( |
|
|
252 |
this._date.getFullYear(), |
|
|
253 |
this._date.getMonth(), i); |
|
|
254 |
var js = '"dateChooserSetDate(\'' |
|
|
255 |
+ this._input.getAttribute('id') + "', '" |
|
|
256 |
+ thisDay.dateFormat(this._format) + '\');"' |
|
|
257 |
result += "\r\n <td class=\"dateChooserActive" |
|
|
258 |
// If the date is the currently chosen date, highlight it |
|
|
259 |
+ (i == this._date.getDate() ? " dateChooserActiveToday" : "") |
|
|
260 |
+ "\" onClick=" + js + ">" + i + "</td>"; |
|
|
261 |
} |
|
|
262 |
// Fill in any days after the end of the month |
|
|
263 |
if (lastDay != 6) { |
|
|
264 |
result += "<td colspan=\"" + (6 - lastDay) + "\"> </td>"; |
|
|
265 |
} |
|
|
266 |
return result + "\r\n </tr>\r\n</table><!--[if lte IE 6.5]><iframe></iframe><![endif]-->"; |
|
|
267 |
} |