rev |
line source |
bsw@11
|
1 //
|
bsw@11
|
2 // Copyright (c) 2009 Public Software Group e. V., Berlin
|
bsw@11
|
3 //
|
bsw@11
|
4 // Permission is hereby granted, free of charge, to any person obtaining a
|
bsw@11
|
5 // copy of this software and associated documentation files (the
|
bsw@11
|
6 // "Software"), to deal in the Software without restriction, including
|
bsw@11
|
7 // without limitation the rights to use, copy, modify, merge, publish,
|
bsw@11
|
8 // distribute, sublicense, and/or sell copies of the Software, and to
|
bsw@11
|
9 // permit persons to whom the Software is furnished to do so, subject to
|
bsw@11
|
10 // the following conditions:
|
bsw@11
|
11 //
|
bsw@11
|
12 // The above copyright notice and this permission notice shall be included
|
bsw@11
|
13 // in all copies or substantial portions of the Software.
|
bsw@11
|
14 //
|
bsw@11
|
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
bsw@11
|
16 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
bsw@11
|
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
bsw@11
|
18 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
bsw@11
|
19 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
bsw@11
|
20 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
bsw@11
|
21 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
bsw@11
|
22 //
|
bsw@11
|
23
|
bsw@11
|
24 //
|
bsw@11
|
25 // All date calculations are based on the gregorian calender, also for
|
bsw@11
|
26 // dates before 1582 (before the gegorian calendar was introduced).
|
bsw@11
|
27 // The supported range is from January 1st 0001 up to December 31st 9999.
|
bsw@11
|
28 //
|
bsw@11
|
29 // gregor_daycount({year: <year>, month: <month>, day: <day>}) returns
|
bsw@11
|
30 // the number of days between the given date and January 1st 0001 (greg.).
|
bsw@11
|
31 //
|
bsw@11
|
32 // gregor_completeDate({year: <year>, month: <month>, day: <day>}) returns
|
bsw@11
|
33 // a structure (an object) with the following properties:
|
bsw@11
|
34 // - daycount (days since January 1st 0001, see gregor_daycount)
|
bsw@11
|
35 // - year (with century)
|
bsw@11
|
36 // - month (from 1 to 12)
|
bsw@11
|
37 // - day (from 1 to 28, 29, 30 or 31)
|
bsw@11
|
38 // - iso_string (string with format YYYY-MM-DD)
|
bsw@11
|
39 // - us_weekday (from 0 for Sunday to 6 for Monday)
|
bsw@11
|
40 // - iso_weekday (from 0 for Monday to 6 for Sunday)
|
bsw@11
|
41 // - iso_weekyear (Year containing greater part of week st. w. Monday)
|
bsw@11
|
42 // - iso_week (from 1 to 52 or 53)
|
bsw@11
|
43 // - us_week (from 1 to 53 or 54)
|
bsw@11
|
44 //
|
bsw@11
|
45 // The structure (the object) passed as parameter to gregor_daycount or
|
bsw@11
|
46 // gregor_completeDate may describe a date in the following ways:
|
bsw@11
|
47 // - daycount
|
bsw@11
|
48 // - year, month, day
|
bsw@11
|
49 // - year, us_week, us_weekday
|
bsw@11
|
50 // - year, iso_week, iso_weekday
|
bsw@11
|
51 // - iso_weekyear, iso_week, iso_weekday
|
bsw@11
|
52 //
|
bsw@11
|
53 // gregor_sheet({...}) returns a calendar sheet as DOM object. The
|
bsw@11
|
54 // structure (the object) passed to the function as an argument is altered
|
bsw@11
|
55 // by the function and used to store state variables. Initially it can
|
bsw@11
|
56 // contain the following fields:
|
bsw@11
|
57 // - year (year to show, defaults to todays year)
|
bsw@11
|
58 // - month (month to show, defaults to todays month)
|
bsw@11
|
59 // - today (structure describing a day, e.g. year, month, day)
|
bsw@11
|
60 // - selected (structure describing a day, e.g. year, month, day)
|
bsw@11
|
61 // - navigation ("enabled", "disabled", "hidden", default "enabled")
|
bsw@11
|
62 // - week_mode ("iso" or "us", defaults to "iso")
|
bsw@11
|
63 // - week_numbers ("left", "right" or null, defaults to null)
|
bsw@11
|
64 // - month_names (e.g. ["January", "Feburary", ...])
|
bsw@11
|
65 // - weekday_names (e.g. ["Mon", "Tue", ...] or ["Sun", "Mon", ...])
|
bsw@11
|
66 // - day_callback (function to render a cell)
|
bsw@11
|
67 // - select_callback (function to be called, when a date was selected)
|
bsw@11
|
68 // - element (for internal use only)
|
bsw@11
|
69 // If "today" is undefined, it is automatically intitialized with the
|
bsw@11
|
70 // current clients date. If "selected" is undefined or null, no date is
|
bsw@11
|
71 // be initially selected. It is mandatory to provide month_names and
|
bsw@11
|
72 // weekday_names.
|
bsw@11
|
73 //
|
bsw@11
|
74 // gregor_addGui({...}) alters a referenced input field in a way that
|
bsw@11
|
75 // focussing on it causes a calendar being shown at its right side, where a
|
bsw@11
|
76 // date can be selected. The structure (the object) passed to this function
|
bsw@11
|
77 // is only evaluated once, and never modified. All options except "element"
|
bsw@11
|
78 // of the gregor_sheet({...}) function may be used as options to
|
bsw@11
|
79 // gregor_addGui({...}) as well. In addition an "element_id" must be
|
bsw@11
|
80 // provided as argument, containing the id of a text input field. The
|
bsw@11
|
81 // behaviour caused by the options "selected" and "select_callback" are
|
bsw@11
|
82 // slightly different: If "selected" === undefined, then the current value
|
bsw@11
|
83 // of the text field referenced by "element_id" will be parsed and used as
|
bsw@11
|
84 // date selection. If "selected" === null, then no date will be initially
|
bsw@11
|
85 // selected, and the text field will be cleared. The "select_callback"
|
bsw@11
|
86 // function is always called once with the pre-selected date (or with null,
|
bsw@11
|
87 // if no date is initially selected). Whenever the selected date is changed
|
bsw@11
|
88 // or unselected later, the callback function is called again with the new
|
poelzi@146
|
89 // date (or with null, in case of deselection). When the relaxed argument is set
|
poelzi@146
|
90 // the calendar will not normalize the parsed date. Thats usefull if you wan't to
|
poelzi@146
|
91 // allow relaxed input.
|
bsw@11
|
92 //
|
bsw@11
|
93 // EXAMPLE:
|
bsw@11
|
94 //
|
bsw@11
|
95 // <input type="text" id="test_field" name="test_field" value=""/>
|
bsw@11
|
96 // <script type="text/javascript">
|
bsw@11
|
97 // gregor_addGui({
|
bsw@11
|
98 // element_id: 'test_field',
|
bsw@11
|
99 // month_names: [
|
bsw@11
|
100 // "January", "February", "March", "April", "May", "June",
|
bsw@11
|
101 // "July", "August", "September", "October", "November", "December"
|
bsw@11
|
102 // ],
|
bsw@11
|
103 // weekday_names: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
|
bsw@11
|
104 // week_numbers: "left"
|
bsw@11
|
105 // });
|
bsw@11
|
106 // </script>
|
bsw@11
|
107 //
|
bsw@11
|
108
|
bsw@11
|
109
|
bsw@11
|
110
|
bsw@11
|
111
|
bsw@11
|
112 // Internal constants and helper functions for date calculation
|
bsw@11
|
113
|
bsw@11
|
114
|
bsw@11
|
115 gregor_c1 = 365; // days of a non-leap year
|
bsw@11
|
116 gregor_c4 = 4 * gregor_c1 + 1; // days of a full 4 year cycle
|
bsw@11
|
117 gregor_c100 = 25 * gregor_c4 - 1; // days of a full 100 year cycle
|
bsw@11
|
118 gregor_c400 = 4 * gregor_c100 + 1; // days of a full 400 year cycle
|
bsw@11
|
119
|
bsw@11
|
120 gregor_normalMonthOffsets = [
|
bsw@11
|
121 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
|
bsw@11
|
122 ];
|
bsw@11
|
123
|
bsw@11
|
124 function gregor_getMonthOffset(year, month) {
|
bsw@11
|
125 if (
|
bsw@11
|
126 (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) &&
|
bsw@11
|
127 month > 2
|
bsw@11
|
128 ) return gregor_normalMonthOffsets[month-1] + 1;
|
bsw@11
|
129 else return gregor_normalMonthOffsets[month-1];
|
bsw@11
|
130 }
|
bsw@11
|
131
|
bsw@11
|
132 function gregor_formatInteger(int, digits) {
|
bsw@11
|
133 var result = int.toFixed();
|
bsw@11
|
134 if (digits != null) {
|
bsw@11
|
135 while (result.length < digits) result = "0" + result;
|
bsw@11
|
136 }
|
bsw@11
|
137 return result;
|
bsw@11
|
138 }
|
bsw@11
|
139
|
bsw@11
|
140
|
bsw@11
|
141
|
bsw@11
|
142 // Calculate days since January 1st 0001 (Gegorian) for a given date
|
bsw@11
|
143
|
bsw@11
|
144
|
bsw@11
|
145 function gregor_daycount(obj) {
|
bsw@11
|
146 if (
|
bsw@11
|
147 obj.daycount >= 0 && obj.daycount <= 3652058 && obj.daycount % 1 == 0
|
bsw@11
|
148 ) {
|
bsw@11
|
149 return obj.daycount;
|
bsw@11
|
150 } else if (
|
bsw@11
|
151 obj.year >= 1 && obj.year <= 9999 && obj.year % 1 == 0 &&
|
bsw@11
|
152 obj.month >= 1 && obj.month <= 12 && obj.month % 1 == 0 &&
|
bsw@11
|
153 obj.day >= 0 && obj.day <= 31 && obj.day % 1 == 0
|
bsw@11
|
154 ) {
|
bsw@11
|
155 var n400 = Math.floor((obj.year-1) / 400);
|
bsw@11
|
156 var r400 = (obj.year-1) % 400;
|
bsw@11
|
157 var n100 = Math.floor(r400 / 100);
|
bsw@11
|
158 var r100 = r400 % 100;
|
bsw@11
|
159 var n4 = Math.floor(r100 / 4);
|
bsw@11
|
160 var n1 = r100 % 4;
|
bsw@11
|
161 return (
|
bsw@11
|
162 gregor_c400 * n400 +
|
bsw@11
|
163 gregor_c100 * n100 +
|
bsw@11
|
164 gregor_c4 * n4 +
|
bsw@11
|
165 gregor_c1 * n1 +
|
bsw@11
|
166 gregor_getMonthOffset(obj.year, obj.month) + (obj.day - 1)
|
bsw@11
|
167 );
|
bsw@11
|
168 } else if (
|
bsw@11
|
169 (
|
bsw@11
|
170 (
|
bsw@11
|
171 obj.year >= 1 && obj.year <= 9999 &&
|
bsw@11
|
172 obj.year % 1 == 0 && obj.iso_weekyear == null
|
bsw@11
|
173 ) || (
|
bsw@11
|
174 obj.iso_weekyear >= 1 && obj.iso_weekyear <= 9999 &&
|
bsw@11
|
175 obj.iso_weekyear % 1 == 0 && obj.year == null
|
bsw@11
|
176 )
|
bsw@11
|
177 ) &&
|
bsw@11
|
178 obj.iso_week >= 0 && obj.iso_week <= 53 && obj.iso_week % 1 == 0 &&
|
bsw@11
|
179 obj.iso_weekday >= 0 && obj.iso_weekday <= 6 &&
|
bsw@11
|
180 obj.iso_weekday % 1 == 0
|
bsw@11
|
181 ) {
|
bsw@11
|
182 var jan4th = gregor_daycount({
|
bsw@11
|
183 year: (obj.year != null) ? obj.year : obj.iso_weekyear,
|
bsw@11
|
184 month: 1,
|
bsw@11
|
185 day: 4
|
bsw@11
|
186 });
|
bsw@11
|
187 var monday0 = jan4th - (jan4th % 7) - 7; // monday of week 0
|
bsw@11
|
188 return monday0 + 7 * obj.iso_week + obj.iso_weekday;
|
bsw@11
|
189 } else if (
|
bsw@11
|
190 obj.year >= 1 && obj.year <= 9999 && obj.year % 1 == 0 &&
|
bsw@11
|
191 obj.us_week >= 0 && obj.us_week <= 54 && obj.us_week % 1 == 0 &&
|
bsw@11
|
192 obj.us_weekday >= 0 && obj.us_weekday <= 6 && obj.us_weekday % 1 == 0
|
bsw@11
|
193 ) {
|
bsw@11
|
194 var jan1st = gregor_daycount({
|
bsw@11
|
195 year: obj.year,
|
bsw@11
|
196 month: 1,
|
bsw@11
|
197 day: 1
|
bsw@11
|
198 });
|
bsw@11
|
199 var sunday0 = jan1st - ((jan1st+1) % 7) - 7; // sunday of week 0
|
bsw@11
|
200 return sunday0 + 7 * obj.us_week + obj.us_weekday;
|
bsw@11
|
201 }
|
bsw@11
|
202 }
|
bsw@11
|
203
|
bsw@11
|
204
|
bsw@11
|
205
|
bsw@11
|
206 // Calculate all calendar related numbers for a given date
|
bsw@11
|
207
|
bsw@11
|
208
|
bsw@11
|
209 function gregor_completeDate(obj) {
|
bsw@11
|
210 if (
|
bsw@11
|
211 obj.daycount >= 0 && obj.daycount <= 3652058 && obj.daycount % 1 == 0
|
bsw@11
|
212 ) {
|
bsw@11
|
213 var daycount = obj.daycount;
|
bsw@11
|
214 var n400 = Math.floor(daycount / gregor_c400);
|
bsw@11
|
215 var r400 = daycount % gregor_c400;
|
bsw@11
|
216 var n100 = Math.floor(r400 / gregor_c100);
|
bsw@11
|
217 var r100 = r400 % gregor_c100;
|
bsw@11
|
218 if (n100 == 4) { n100 = 3; r100 = gregor_c100; }
|
bsw@11
|
219 var n4 = Math.floor(r100 / gregor_c4);
|
bsw@11
|
220 var r4 = r100 % gregor_c4;
|
bsw@11
|
221 var n1 = Math.floor(r4 / gregor_c1);
|
bsw@11
|
222 var r1 = r4 % gregor_c1;
|
bsw@11
|
223 if (n1 == 4) { n1 = 3; r1 = gregor_c1; }
|
bsw@11
|
224 var year = 1 + 400 * n400 + 100 * n100 + 4 * n4 + n1;
|
bsw@11
|
225 var month = 1 + Math.floor(r1 / 31);
|
bsw@11
|
226 var monthOffset = gregor_getMonthOffset(year, month);
|
bsw@11
|
227 if (month < 12) {
|
bsw@11
|
228 var nextMonthOffset = gregor_getMonthOffset(year, month + 1);
|
bsw@11
|
229 if (r1 >= nextMonthOffset) {
|
bsw@11
|
230 month++;
|
bsw@11
|
231 monthOffset = nextMonthOffset;
|
bsw@11
|
232 }
|
bsw@11
|
233 }
|
bsw@11
|
234 var day = 1 + r1 - monthOffset;
|
bsw@11
|
235 var iso_string = ("" +
|
bsw@11
|
236 gregor_formatInteger(year, 4) + "-" +
|
bsw@11
|
237 gregor_formatInteger(month, 2) + "-" +
|
bsw@11
|
238 gregor_formatInteger(day, 2)
|
bsw@11
|
239 );
|
bsw@11
|
240 var us_weekday = (daycount+1) % 7;
|
bsw@11
|
241 var iso_weekday = daycount % 7;
|
bsw@11
|
242 var iso_weekyear = year;
|
bsw@11
|
243 if (
|
bsw@11
|
244 month == 1 && (
|
bsw@11
|
245 (day == 3 && iso_weekday == 6) ||
|
bsw@11
|
246 (day == 2 && iso_weekday >= 5) ||
|
bsw@11
|
247 (day == 1 && iso_weekday >= 4)
|
bsw@11
|
248 )
|
bsw@11
|
249 ) iso_weekyear--;
|
bsw@11
|
250 else if (
|
bsw@11
|
251 month == 12 && (
|
bsw@11
|
252 (day == 29 && iso_weekday == 0) ||
|
bsw@11
|
253 (day == 30 && iso_weekday <= 1) ||
|
bsw@11
|
254 (day == 31 && iso_weekday <= 2)
|
bsw@11
|
255 )
|
bsw@11
|
256 ) iso_weekyear++;
|
bsw@11
|
257 var jan4th = gregor_daycount({year: iso_weekyear, month: 1, day: 4});
|
bsw@11
|
258 var monday0 = jan4th - (jan4th % 7) - 7; // monday of week 0
|
bsw@11
|
259 var iso_week = Math.floor((daycount - monday0) / 7);
|
bsw@11
|
260 var jan1st = gregor_daycount({year: year, month: 1, day: 1});
|
bsw@11
|
261 var sunday0 = jan1st - ((jan1st+1) % 7) - 7; // sunday of week 0
|
bsw@11
|
262 var us_week = Math.floor((daycount - sunday0) / 7);
|
bsw@11
|
263 return {
|
bsw@11
|
264 daycount: daycount,
|
bsw@11
|
265 year: year,
|
bsw@11
|
266 month: month,
|
bsw@11
|
267 day: day,
|
bsw@11
|
268 iso_string: iso_string,
|
bsw@11
|
269 us_weekday: (daycount+1) % 7, // 0 = Sunday
|
bsw@11
|
270 iso_weekday: daycount % 7, // 0 = Monday
|
bsw@11
|
271 iso_weekyear: iso_weekyear,
|
bsw@11
|
272 iso_week: iso_week,
|
bsw@11
|
273 us_week: us_week
|
bsw@11
|
274 };
|
bsw@11
|
275 } else if (obj.daycount == null) {
|
bsw@11
|
276 var daycount = gregor_daycount(obj);
|
bsw@11
|
277 if (daycount != null) {
|
bsw@11
|
278 return gregor_completeDate({daycount: gregor_daycount(obj)});
|
bsw@11
|
279 }
|
bsw@11
|
280 }
|
bsw@11
|
281 }
|
bsw@11
|
282
|
bsw@11
|
283
|
bsw@11
|
284
|
bsw@11
|
285 // Test gregor_daycount and gregor_completeDate for consistency
|
bsw@11
|
286 // (Debugging only)
|
bsw@11
|
287
|
bsw@11
|
288
|
bsw@11
|
289 function gregor_test() {
|
bsw@11
|
290 for (i=650000; i<900000; i++) {
|
bsw@11
|
291 var obj = gregor_completeDate({daycount: i});
|
bsw@11
|
292 var j;
|
bsw@11
|
293 j = gregor_daycount({
|
bsw@11
|
294 year: obj.year,
|
bsw@11
|
295 month: obj.month,
|
bsw@11
|
296 day: obj.day
|
bsw@11
|
297 });
|
bsw@11
|
298 if (i != j) { alert("ERROR"); return; }
|
bsw@11
|
299 j = gregor_daycount({
|
bsw@11
|
300 iso_weekyear: obj.iso_weekyear,
|
bsw@11
|
301 iso_week: obj.iso_week,
|
bsw@11
|
302 iso_weekday: obj.iso_weekday
|
bsw@11
|
303 });
|
bsw@11
|
304 if (i != j) { alert("ERROR"); return; }
|
bsw@11
|
305 j = gregor_daycount({
|
bsw@11
|
306 year: obj.year,
|
bsw@11
|
307 iso_week:
|
bsw@11
|
308 (obj.iso_weekyear == obj.year + 1) ? 53 :
|
bsw@11
|
309 (obj.iso_weekyear == obj.year - 1) ? 0 :
|
bsw@11
|
310 obj.iso_week,
|
bsw@11
|
311 iso_weekday: obj.iso_weekday
|
bsw@11
|
312 });
|
bsw@11
|
313 if (i != j) { alert("ERROR"); return; }
|
bsw@11
|
314 j = gregor_daycount({
|
bsw@11
|
315 year: obj.year,
|
bsw@11
|
316 us_week: obj.us_week,
|
bsw@11
|
317 us_weekday: obj.us_weekday
|
bsw@11
|
318 });
|
bsw@11
|
319 if (i != j) { alert("ERROR"); return; }
|
bsw@11
|
320 }
|
bsw@11
|
321 alert("SUCCESS");
|
bsw@11
|
322 }
|
bsw@11
|
323
|
bsw@11
|
324
|
bsw@11
|
325
|
bsw@11
|
326 // Graphical calendar
|
bsw@11
|
327
|
bsw@11
|
328
|
bsw@11
|
329 gregor_iso_weekday_css = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
|
bsw@11
|
330
|
bsw@11
|
331 function gregor_sheet(args) {
|
bsw@11
|
332
|
bsw@11
|
333 // setting args.today and args.selected
|
bsw@11
|
334 if (args.today === undefined) {
|
bsw@11
|
335 var js_date = new Date();
|
bsw@11
|
336 args.today = gregor_completeDate({
|
bsw@11
|
337 year: js_date.getFullYear(),
|
bsw@11
|
338 month: js_date.getMonth() + 1,
|
bsw@11
|
339 day: js_date.getDate()
|
bsw@11
|
340 });
|
bsw@11
|
341 } else if (args.today != null) {
|
bsw@11
|
342 args.today = gregor_completeDate(args.today);
|
bsw@11
|
343 }
|
bsw@11
|
344 if (args.selected == "today") {
|
bsw@11
|
345 args.selected = args.today;
|
bsw@11
|
346 } else if (args.selected != null) {
|
bsw@11
|
347 args.selected = gregor_completeDate(args.selected);
|
bsw@11
|
348 }
|
bsw@11
|
349
|
bsw@11
|
350 // setting args.year and args.month
|
bsw@11
|
351 if (args.year == null) {
|
bsw@11
|
352 if (args.selected != null) args.year = args.selected.year;
|
bsw@11
|
353 else args.year = args.today.year;
|
bsw@11
|
354 }
|
bsw@11
|
355 if (args.month == null) {
|
bsw@11
|
356 if (args.selected != null) args.month = args.selected.month;
|
bsw@11
|
357 else args.month = args.today.month;
|
bsw@11
|
358 }
|
bsw@11
|
359
|
bsw@11
|
360 // setting first_day
|
bsw@11
|
361 var first_day = gregor_completeDate({
|
bsw@11
|
362 year: args.year,
|
bsw@11
|
363 month: args.month,
|
bsw@11
|
364 day: 1
|
bsw@11
|
365 });
|
bsw@11
|
366 if (first_day == null) return;
|
bsw@11
|
367
|
bsw@11
|
368 // checking args.navigation, args.week_mode and args.week_numbers
|
bsw@11
|
369 if (args.navigation == null) args.navigation = "enabled";
|
bsw@11
|
370 else if (
|
bsw@11
|
371 args.navigation != "enabled" &&
|
bsw@11
|
372 args.navigation != "disabled" &&
|
bsw@11
|
373 args.navigation != "hidden"
|
bsw@11
|
374 ) return;
|
bsw@11
|
375 if (args.week_mode == null) args.week_mode = "iso";
|
bsw@11
|
376 else if (args.week_mode != "iso" && args.week_mode != "us") return;
|
bsw@11
|
377 if (
|
bsw@11
|
378 args.week_numbers != null &&
|
bsw@11
|
379 args.week_numbers != "left" &&
|
bsw@11
|
380 args.week_numbers != "right"
|
bsw@11
|
381 ) return;
|
bsw@11
|
382
|
bsw@11
|
383 // checking args.month.names and args.weekday_names
|
bsw@11
|
384 if (args.month_names.length != 12) return;
|
bsw@11
|
385 if (args.weekday_names.length != 7) return;
|
bsw@11
|
386
|
bsw@11
|
387 // calculating number of days in month
|
bsw@11
|
388 var count;
|
bsw@11
|
389 if (args.year < 9999 || args.month < 12) {
|
bsw@11
|
390 count = gregor_daycount({
|
bsw@11
|
391 year: (args.month == 12) ? (args.year + 1) : args.year,
|
bsw@11
|
392 month: (args.month == 12) ? 1 : (args.month + 1),
|
bsw@11
|
393 day: 1
|
bsw@11
|
394 }) - first_day.daycount;
|
bsw@11
|
395 } else {
|
bsw@11
|
396 // workaround for year 9999
|
bsw@11
|
397 count = 31;
|
bsw@11
|
398 }
|
bsw@11
|
399
|
bsw@11
|
400 // locale variables for UI construction
|
bsw@11
|
401 var table, row, cell, element;
|
bsw@11
|
402
|
bsw@11
|
403 // take table element from args.element,
|
bsw@11
|
404 // if neccessary create and store it
|
bsw@11
|
405 if (args.element == null) {
|
bsw@11
|
406 table = document.createElement("table");
|
bsw@11
|
407 args.element = table;
|
bsw@11
|
408 } else {
|
bsw@11
|
409 table = args.element;
|
bsw@11
|
410 while (table.firstChild) table.removeChild(table.firstChild);
|
bsw@11
|
411 }
|
bsw@11
|
412
|
bsw@11
|
413 // set CSS class of table according to args.week_numbers
|
bsw@11
|
414 if (args.week_numbers == "left") {
|
bsw@11
|
415 table.className = "gregor_sheet gregor_weeks_left";
|
bsw@11
|
416 } else if (args.week_numbers == "right") {
|
bsw@11
|
417 table.className = "gregor_sheet gregor_weeks_right";
|
bsw@11
|
418 } else {
|
bsw@11
|
419 table.className = "gregor_sheet gregor_weeks_none";
|
bsw@11
|
420 }
|
bsw@11
|
421
|
bsw@11
|
422 // begin of table head
|
bsw@11
|
423 var thead = document.createElement("thead");
|
bsw@11
|
424
|
bsw@11
|
425 // navigation
|
bsw@11
|
426 if (args.navigation != "hidden") {
|
bsw@11
|
427
|
bsw@11
|
428 // UI head row containing the year
|
bsw@11
|
429 row = document.createElement("tr");
|
bsw@11
|
430 row.className = "gregor_year_row";
|
bsw@11
|
431 cell = document.createElement("th");
|
bsw@11
|
432 cell.className = "gregor_year";
|
bsw@11
|
433 cell.colSpan = args.week_numbers ? 8 : 7;
|
bsw@11
|
434 if (args.navigation == "enabled") {
|
bsw@11
|
435 element = document.createElement("a");
|
bsw@11
|
436 element.className = "gregor_turn gregor_turn_left";
|
bsw@11
|
437 element.style.cssFloat = "left";
|
bsw@11
|
438 element.style.styleFloat = "left";
|
bsw@11
|
439 element.href = "#";
|
bsw@11
|
440 element.onclick = function() {
|
bsw@11
|
441 if (args.year > 1) args.year--;
|
bsw@11
|
442 gregor_sheet(args);
|
bsw@11
|
443 return false;
|
bsw@11
|
444 }
|
bsw@11
|
445 element.ondblclick = element.onclick;
|
bsw@11
|
446 element.appendChild(document.createTextNode("<<"));
|
bsw@11
|
447 cell.appendChild(element);
|
bsw@11
|
448 element = document.createElement("a");
|
bsw@11
|
449 element.className = "gregor_turn gregor_turn_right";
|
bsw@11
|
450 element.style.cssFloat = "right";
|
bsw@11
|
451 element.style.styleFloat = "right";
|
bsw@11
|
452 element.href = "#";
|
bsw@11
|
453 element.onclick = function() {
|
bsw@11
|
454 if (args.year < 9999) args.year++;
|
bsw@11
|
455 gregor_sheet(args);
|
bsw@11
|
456 return false;
|
bsw@11
|
457 }
|
bsw@11
|
458 element.ondblclick = element.onclick;
|
bsw@11
|
459 element.appendChild(document.createTextNode(">>"));
|
bsw@11
|
460 cell.appendChild(element);
|
bsw@11
|
461 }
|
bsw@11
|
462 cell.appendChild(document.createTextNode(first_day.year));
|
bsw@11
|
463 row.appendChild(cell);
|
bsw@11
|
464 thead.appendChild(row);
|
bsw@11
|
465
|
bsw@11
|
466 // UI head row containing the month
|
bsw@11
|
467 row = document.createElement("tr");
|
bsw@11
|
468 row.className = "gregor_month_row";
|
bsw@11
|
469 cell = document.createElement("th");
|
bsw@11
|
470 cell.className = "gregor_month";
|
bsw@11
|
471 cell.colSpan = args.week_numbers ? 8 : 7;
|
bsw@11
|
472 if (args.navigation == "enabled") {
|
bsw@11
|
473 element = document.createElement("a");
|
bsw@11
|
474 element.className = "gregor_turn gregor_turn_left";
|
bsw@11
|
475 element.style.cssFloat = "left";
|
bsw@11
|
476 element.style.styleFloat = "left";
|
bsw@11
|
477 element.href = "#";
|
bsw@11
|
478 element.onclick = function() {
|
bsw@11
|
479 if (args.year > 1 || args.month > 1) {
|
bsw@11
|
480 args.month--;
|
bsw@11
|
481 if (args.month < 1) {
|
bsw@11
|
482 args.month = 12;
|
bsw@11
|
483 args.year--;
|
bsw@11
|
484 }
|
bsw@11
|
485 }
|
bsw@11
|
486 gregor_sheet(args);
|
bsw@11
|
487 return false;
|
bsw@11
|
488 }
|
bsw@11
|
489 element.ondblclick = element.onclick;
|
bsw@11
|
490 element.appendChild(document.createTextNode("<<"));
|
bsw@11
|
491 cell.appendChild(element);
|
bsw@11
|
492 element = document.createElement("a");
|
bsw@11
|
493 element.className = "gregor_turn gregor_turn_right";
|
bsw@11
|
494 element.style.cssFloat = "right";
|
bsw@11
|
495 element.style.styleFloat = "right";
|
bsw@11
|
496 element.href = "#";
|
bsw@11
|
497 element.onclick = function() {
|
bsw@11
|
498 if (args.year < 9999 || args.month < 12) {
|
bsw@11
|
499 args.month++;
|
bsw@11
|
500 if (args.month > 12) {
|
bsw@11
|
501 args.month = 1;
|
bsw@11
|
502 args.year++;
|
bsw@11
|
503 }
|
bsw@11
|
504 }
|
bsw@11
|
505 gregor_sheet(args);
|
bsw@11
|
506 return false;
|
bsw@11
|
507 }
|
bsw@11
|
508 element.ondblclick = element.onclick;
|
bsw@11
|
509 element.appendChild(document.createTextNode(">>"));
|
bsw@11
|
510 cell.appendChild(element);
|
bsw@11
|
511 }
|
bsw@11
|
512 cell.appendChild(document.createTextNode(
|
bsw@11
|
513 args.month_names[first_day.month-1]
|
bsw@11
|
514 ));
|
bsw@11
|
515 row.appendChild(cell);
|
bsw@11
|
516 thead.appendChild(row);
|
bsw@11
|
517
|
bsw@11
|
518 // end of navigation
|
bsw@11
|
519 }
|
bsw@11
|
520
|
bsw@11
|
521 // UI weekday row
|
bsw@11
|
522 row = document.createElement("tr");
|
bsw@11
|
523 row.className = "gregor_weekday_row";
|
bsw@11
|
524 if (args.week_numbers == "left") {
|
bsw@11
|
525 cell = document.createElement("th");
|
bsw@11
|
526 cell.className = "gregor_corner";
|
bsw@11
|
527 row.appendChild(cell);
|
bsw@11
|
528 }
|
bsw@11
|
529 for (var i=0; i<7; i++) {
|
bsw@11
|
530 cell = document.createElement("th");
|
bsw@11
|
531 cell.className = (
|
bsw@11
|
532 "gregor_weekday gregor_" +
|
bsw@11
|
533 gregor_iso_weekday_css[(args.week_mode == "us") ? ((i+6)%7) : i]
|
bsw@11
|
534 );
|
bsw@11
|
535 cell.appendChild(document.createTextNode(args.weekday_names[i]));
|
bsw@11
|
536 row.appendChild(cell);
|
bsw@11
|
537 }
|
bsw@11
|
538 if (args.week_numbers == "right") {
|
bsw@11
|
539 cell = document.createElement("th");
|
bsw@11
|
540 cell.className = "gregor_corner";
|
bsw@11
|
541 row.appendChild(cell);
|
bsw@11
|
542 }
|
bsw@11
|
543 thead.appendChild(row);
|
bsw@11
|
544
|
bsw@11
|
545 // end of table head and begin of table body
|
bsw@11
|
546 table.appendChild(thead);
|
bsw@11
|
547 var tbody = document.createElement("tbody");
|
bsw@11
|
548
|
bsw@11
|
549 // definition of insert_week function
|
bsw@11
|
550 var week = (
|
bsw@11
|
551 (args.week_mode == "us") ? first_day.us_week : first_day.iso_week
|
bsw@11
|
552 );
|
bsw@11
|
553 insert_week = function() {
|
bsw@11
|
554 cell = document.createElement("th");
|
bsw@11
|
555 cell.className = "gregor_week";
|
bsw@11
|
556 cell.appendChild(document.createTextNode(
|
bsw@11
|
557 (week < 10) ? ("0" + week) : week)
|
bsw@11
|
558 );
|
bsw@11
|
559 week++;
|
bsw@11
|
560 if (
|
bsw@11
|
561 args.week_mode == "iso" && (
|
bsw@11
|
562 (
|
bsw@11
|
563 args.month == 1 && week > 52
|
bsw@11
|
564 ) || (
|
bsw@11
|
565 args.month == 12 && week == 53 && (
|
bsw@11
|
566 first_day.iso_weekday == 0 ||
|
bsw@11
|
567 first_day.iso_weekday == 5 ||
|
bsw@11
|
568 first_day.iso_weekday == 6
|
bsw@11
|
569 )
|
bsw@11
|
570 )
|
bsw@11
|
571 )
|
bsw@11
|
572 ) week = 1;
|
bsw@11
|
573 row.appendChild(cell);
|
bsw@11
|
574 }
|
bsw@11
|
575
|
bsw@11
|
576 // output data fields
|
bsw@11
|
577 row = document.createElement("tr");
|
bsw@11
|
578 if (args.week_numbers == "left") insert_week();
|
bsw@11
|
579 var filler_count = (
|
bsw@11
|
580 (args.week_mode == "us") ? first_day.us_weekday : first_day.iso_weekday
|
bsw@11
|
581 );
|
bsw@11
|
582 for (var i=0; i<filler_count; i++) {
|
bsw@11
|
583 cell = document.createElement("td");
|
bsw@11
|
584 cell.className = "gregor_empty";
|
bsw@11
|
585 row.appendChild(cell);
|
bsw@11
|
586 }
|
bsw@11
|
587 for (var i=0; i<count; i++) {
|
bsw@11
|
588 var date = gregor_completeDate({daycount: first_day.daycount + i});
|
bsw@11
|
589 if (row == null) {
|
bsw@11
|
590 row = document.createElement("tr");
|
bsw@11
|
591 if (args.week_numbers == "left") insert_week();
|
bsw@11
|
592 }
|
bsw@11
|
593 cell = document.createElement("td");
|
bsw@11
|
594 var cssClass = (
|
bsw@11
|
595 "gregor_day gregor_" + gregor_iso_weekday_css[date.iso_weekday]
|
bsw@11
|
596 );
|
bsw@11
|
597 if (args.today != null && date.daycount == args.today.daycount) {
|
bsw@11
|
598 cssClass += " gregor_today";
|
bsw@11
|
599 }
|
bsw@11
|
600 if (args.selected != null && date.daycount == args.selected.daycount) {
|
bsw@11
|
601 cssClass += " gregor_selected";
|
bsw@11
|
602 }
|
bsw@11
|
603 cell.className = cssClass;
|
bsw@11
|
604 if (args.day_callback) {
|
bsw@11
|
605 args.day_callback(cell, date);
|
bsw@11
|
606 } else {
|
bsw@11
|
607 element = document.createElement("a");
|
bsw@11
|
608 element.href = "#";
|
bsw@11
|
609 var generate_onclick = function(date) {
|
bsw@11
|
610 return function() {
|
bsw@11
|
611 args.selected = date;
|
bsw@11
|
612 gregor_sheet(args);
|
bsw@11
|
613 if (args.select_callback != null) {
|
bsw@11
|
614 args.select_callback(date);
|
bsw@11
|
615 }
|
bsw@11
|
616 return false;
|
bsw@11
|
617 }
|
bsw@11
|
618 }
|
bsw@11
|
619 element.onclick = generate_onclick(date);
|
bsw@11
|
620 element.ondblclick = element.onclick;
|
bsw@11
|
621 element.appendChild(document.createTextNode(first_day.day + i));
|
bsw@11
|
622 cell.appendChild(element);
|
bsw@11
|
623 }
|
bsw@11
|
624 row.appendChild(cell);
|
bsw@11
|
625 if (row.childNodes.length == ((args.week_numbers == "left") ? 8 : 7)) {
|
bsw@11
|
626 if (args.week_numbers == "right") insert_week();
|
bsw@11
|
627 tbody.appendChild(row);
|
bsw@11
|
628 row = null;
|
bsw@11
|
629 }
|
bsw@11
|
630 }
|
bsw@11
|
631 if (row != null) {
|
bsw@11
|
632 while (row.childNodes.length < ((args.week_numbers == "left") ? 8 : 7)) {
|
bsw@11
|
633 cell = document.createElement("td");
|
bsw@11
|
634 cell.className = "gregor_empty";
|
bsw@11
|
635 row.appendChild(cell);
|
bsw@11
|
636 }
|
bsw@11
|
637 if (args.week_numbers == "right") insert_week();
|
bsw@11
|
638 tbody.appendChild(row);
|
bsw@11
|
639 }
|
bsw@11
|
640
|
bsw@11
|
641 // end of table body
|
bsw@11
|
642 table.appendChild(tbody);
|
bsw@11
|
643
|
bsw@11
|
644 // return table
|
bsw@11
|
645 return table;
|
bsw@11
|
646 }
|
bsw@11
|
647
|
bsw@11
|
648
|
bsw@11
|
649
|
bsw@11
|
650 // Rich form field support
|
bsw@11
|
651
|
bsw@11
|
652
|
bsw@11
|
653 function gregor_getAbsoluteLeft(elem) {
|
bsw@11
|
654 var result = 0;
|
bsw@11
|
655 while (elem && elem.style.position != "static") {
|
bsw@11
|
656 result += elem.offsetLeft;
|
bsw@11
|
657 elem = elem.offsetParent;
|
bsw@11
|
658 }
|
bsw@11
|
659 return result;
|
bsw@11
|
660 }
|
bsw@11
|
661
|
bsw@11
|
662 function gregor_getAbsoluteTop(elem) {
|
bsw@11
|
663 var result = 0;
|
bsw@11
|
664 while (elem && elem.style.position != "static") {
|
bsw@11
|
665 result += elem.offsetTop;
|
bsw@11
|
666 elem = elem.offsetParent;
|
bsw@11
|
667 }
|
bsw@11
|
668 return result;
|
bsw@11
|
669 }
|
bsw@11
|
670
|
bsw@11
|
671 function gregor_formatDate(format, date) {
|
bsw@11
|
672 if (date == null) return "";
|
bsw@11
|
673 var result = format;
|
bsw@11
|
674 result = result.replace(/Y+/, function(s) {
|
bsw@11
|
675 if (s.length == 2) return gregor_formatInteger(date.year % 100, 2);
|
bsw@11
|
676 else return gregor_formatInteger(date.year, s.length);
|
bsw@11
|
677 });
|
bsw@11
|
678 result = result.replace(/M+/, function(s) {
|
bsw@11
|
679 return gregor_formatInteger(date.month, s.length);
|
bsw@11
|
680 });
|
bsw@11
|
681 result = result.replace(/D+/, function(s) {
|
bsw@11
|
682 return gregor_formatInteger(date.day, s.length);
|
bsw@11
|
683 });
|
bsw@11
|
684 return result;
|
bsw@11
|
685 }
|
bsw@11
|
686
|
bsw@11
|
687 function gregor_map2digitYear(y2, maxYear) {
|
bsw@11
|
688 var guess = Math.floor(maxYear / 100) * 100 + y2;
|
bsw@11
|
689 if (guess <= maxYear) return guess;
|
bsw@11
|
690 else return guess - 100;
|
bsw@11
|
691 }
|
bsw@11
|
692
|
bsw@11
|
693 function gregor_parseDate(format, string, terminated, maxYear) {
|
bsw@11
|
694 var numericParts, formatParts;
|
bsw@11
|
695 numericParts = string.match(/^\s*([0-9]{4})-([0-9]{2})-([0-9]{2})\s*$/);
|
bsw@11
|
696 if (numericParts != null) {
|
bsw@11
|
697 return gregor_completeDate({
|
bsw@11
|
698 year: numericParts[1],
|
bsw@11
|
699 month: numericParts[2],
|
bsw@11
|
700 day: numericParts[3]
|
bsw@11
|
701 });
|
bsw@11
|
702 }
|
bsw@11
|
703 numericParts = string.match(/[0-9]+/g);
|
bsw@11
|
704 if (numericParts == null) return null;
|
bsw@11
|
705 formatParts = format.match(/[YMD]+/g);
|
bsw@11
|
706 if (numericParts.length != formatParts.length) return null;
|
bsw@11
|
707 if (
|
bsw@11
|
708 !terminated && (
|
bsw@11
|
709 numericParts[numericParts.length-1].length <
|
bsw@11
|
710 formatParts[formatParts.length-1].length
|
bsw@11
|
711 )
|
bsw@11
|
712 ) return null;
|
bsw@11
|
713 var year, month, day;
|
bsw@11
|
714 for (var i=0; i<numericParts.length; i++) {
|
bsw@11
|
715 var numericPart = numericParts[i];
|
bsw@11
|
716 var formatPart = formatParts[i];
|
bsw@11
|
717 if (formatPart.match(/^Y+$/)) {
|
bsw@11
|
718 if (numericPart.length == 2 && maxYear != null) {
|
bsw@11
|
719 year = gregor_map2digitYear(parseInt(numericPart, 10), maxYear);
|
bsw@11
|
720 } else if (numericPart.length > 2) {
|
bsw@11
|
721 year = parseInt(numericPart, 10);
|
bsw@11
|
722 }
|
bsw@11
|
723 } else if (formatPart.match(/^M+$/)) {
|
bsw@11
|
724 month = parseInt(numericPart, 10);
|
bsw@11
|
725 } else if (formatPart.match(/^D+$/)) {
|
bsw@11
|
726 day = parseInt(numericPart, 10);
|
bsw@11
|
727 } else {
|
bsw@11
|
728 //alert("Not implemented.");
|
bsw@11
|
729 return null;
|
bsw@11
|
730 }
|
bsw@11
|
731 }
|
bsw@11
|
732 return gregor_completeDate({year: year, month: month, day: day});
|
bsw@11
|
733 }
|
bsw@11
|
734
|
bsw@11
|
735 function gregor_addGui(args) {
|
bsw@11
|
736
|
bsw@11
|
737 // copy argument structure
|
bsw@11
|
738 var state = {};
|
bsw@11
|
739 for (key in args) state[key] = args[key];
|
bsw@11
|
740
|
bsw@11
|
741 // unset state.element, which should never be set anyway
|
bsw@11
|
742 state.element = null;
|
bsw@11
|
743
|
bsw@11
|
744 // save original values of "year" and "month" options
|
bsw@11
|
745 var original_year = state.year;
|
bsw@11
|
746 var original_month = state.month;
|
bsw@11
|
747
|
bsw@11
|
748 // get text field element
|
bsw@11
|
749 var element = document.getElementById(state.element_id);
|
bsw@11
|
750 state.element_id = null;
|
bsw@11
|
751
|
bsw@11
|
752 // setup state.today, state.selected and state.format options
|
bsw@11
|
753 if (state.today === undefined) {
|
bsw@11
|
754 var js_date = new Date();
|
bsw@11
|
755 state.today = gregor_completeDate({
|
bsw@11
|
756 year: js_date.getFullYear(),
|
bsw@11
|
757 month: js_date.getMonth() + 1,
|
bsw@11
|
758 day: js_date.getDate()
|
bsw@11
|
759 });
|
bsw@11
|
760 } else if (state.today != null) {
|
bsw@11
|
761 state.today = gregor_completeDate(args.today);
|
bsw@11
|
762 }
|
bsw@11
|
763 if (state.selected == "today") {
|
bsw@11
|
764 state.selected = state.today;
|
bsw@11
|
765 } else if (args.selected != null) {
|
bsw@11
|
766 state.selected = gregor_completeDate(state.selected);
|
bsw@11
|
767 }
|
bsw@11
|
768 if (state.format == null) state.format = "YYYY-MM-DD";
|
bsw@11
|
769
|
bsw@11
|
770 // using state.future to calculate maxYear (for 2 digit year conversions)
|
bsw@11
|
771 var maxYear = (state.today == null) ? null : (
|
bsw@11
|
772 state.today.year +
|
bsw@11
|
773 ((state.future == null) ? 12 : state.future)
|
bsw@11
|
774 );
|
bsw@11
|
775
|
bsw@11
|
776 // hook into state.select_callback
|
bsw@11
|
777 var select_callback = state.select_callback;
|
bsw@11
|
778 state.select_callback = function(date) {
|
bsw@11
|
779 element.value = gregor_formatDate(state.format, date);
|
bsw@11
|
780 if (select_callback) select_callback(date);
|
bsw@11
|
781 };
|
bsw@11
|
782 // function to parse text field and update calendar sheet state
|
bsw@11
|
783 var updateSheet = function(terminated) {
|
bsw@11
|
784 var date = gregor_parseDate(
|
bsw@11
|
785 state.format, element.value, terminated, maxYear
|
bsw@11
|
786 );
|
bsw@11
|
787 if (date) {
|
bsw@11
|
788 state.year = null;
|
bsw@11
|
789 state.month = null;
|
bsw@11
|
790 }
|
bsw@11
|
791 state.selected = date;
|
bsw@11
|
792 gregor_sheet(state);
|
bsw@11
|
793 };
|
bsw@11
|
794
|
bsw@11
|
795 // Initial synchronization
|
bsw@11
|
796 if (state.selected === undefined) updateSheet(true);
|
poelzi@146
|
797 if (!state.relaxed)
|
poelzi@146
|
798 element.value = gregor_formatDate(state.format, state.selected);
|
poelzi@146
|
799
|
bsw@11
|
800 if (select_callback) select_callback(state.selected);
|
bsw@11
|
801
|
bsw@11
|
802 // variables storing popup status
|
bsw@11
|
803 var visible = false;
|
bsw@11
|
804 var focus = false;
|
bsw@11
|
805 var protection = false;
|
bsw@11
|
806
|
bsw@11
|
807 // event handlers for text field
|
bsw@11
|
808 element.onfocus = function() {
|
bsw@11
|
809 focus = true;
|
bsw@11
|
810 if (!visible) {
|
bsw@11
|
811 state.year = original_year;
|
bsw@11
|
812 state.month = original_month;
|
bsw@11
|
813 gregor_sheet(state);
|
bsw@11
|
814 state.element.style.position = "absolute";
|
bsw@11
|
815 state.element.style.top = gregor_getAbsoluteTop(element) + element.offsetHeight;
|
bsw@11
|
816 state.element.style.left = gregor_getAbsoluteLeft(element);
|
bsw@11
|
817 state.element.onmousedown = function() {
|
bsw@11
|
818 protection = true;
|
bsw@11
|
819 };
|
bsw@11
|
820 state.element.onmouseup = function() {
|
bsw@11
|
821 protection = false;
|
bsw@11
|
822 element.focus();
|
bsw@11
|
823 };
|
bsw@11
|
824 state.element.onmouseout = state.element.onmouseup;
|
bsw@11
|
825 element.parentNode.appendChild(state.element);
|
bsw@11
|
826 visible = true;
|
bsw@11
|
827 }
|
bsw@11
|
828 };
|
bsw@11
|
829 element.onblur = function() {
|
bsw@11
|
830 focus = false;
|
bsw@11
|
831 window.setTimeout(function() {
|
bsw@11
|
832 if (visible && !focus && !protection) {
|
bsw@11
|
833 updateSheet(true);
|
poelzi@146
|
834 if(!state.relaxed)
|
poelzi@146
|
835 element.value = gregor_formatDate(state.format, state.selected);
|
bsw@11
|
836 if (select_callback) select_callback(state.selected);
|
bsw@11
|
837 state.element.parentNode.removeChild(state.element);
|
bsw@11
|
838 visible = false;
|
bsw@11
|
839 protection = false;
|
bsw@11
|
840 }
|
bsw@11
|
841 }, 1);
|
bsw@11
|
842 };
|
bsw@11
|
843 element.onkeyup = function() {
|
bsw@11
|
844 updateSheet(false);
|
bsw@11
|
845 if (select_callback) select_callback(state.selected);
|
bsw@11
|
846 };
|
bsw@11
|
847
|
bsw@11
|
848 }
|
bsw@11
|
849
|