|
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 } |