-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalendarDateInput.js
executable file
·593 lines (558 loc) · 31.5 KB
/
calendarDateInput.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
/***********************************************
Fool-Proof Date Input Script with DHTML Calendar
by Jason Moon - http://calendar.moonscript.com/dateinput.cfm
************************************************/
// Customizable variables
var DefaultDateFormat = 'MM/DD/YYYY'; // If no date format is supplied, this will be used instead
var HideWait = 3; // Number of seconds before the calendar will disappear
var Y2kPivotPoint = 76; // 2-digit years before this point will be created in the 21st century
var UnselectedMonthText = ''; // Text to display in the 1st month list item when the date isn't required
var FontSize = 15; // In pixels
var FontFamily = 'Tahoma';
var CellWidth = 20;
var CellHeight = 16;
var ImageURL = 'calendar.jpg';
var NextURL = 'next.gif';
var PrevURL = 'prev.gif';
var CalBGColor = 'white';
var TopRowBGColor = 'buttonface';
var DayBGColor = 'lightgrey';
// Global variables
var ZCounter = 100;
var Today = new Date();
Today.setTime(Today.getTime()+(1000*3600*24));
var WeekDays = new Array('S','M','T','W','T','F','S');
var MonthDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var MonthNames = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
// Write out the stylesheet definition for the calendar
with (document) {
writeln('<style>');
writeln('td.calendarDateInput {letter-spacing:normal;line-height:normal;font-family:' + FontFamily + ',Sans-Serif;font-size:' + FontSize + 'px;}');
writeln('select.calendarDateInput {letter-spacing:.06em;font-family:Verdana,Sans-Serif;font-size:15px;}');
writeln('input.calendarDateInput {letter-spacing:.06em;font-family:Verdana,Sans-Serif;font-size:15px;}');
writeln('.calendarDateInput{position:relative; left:300px; bottom:34px;}');
writeln('</style>');
}
// Only allows certain keys to be used in the date field
function YearDigitsOnly(e) {
var KeyCode = (e.keyCode) ? e.keyCode : e.which;
return ((KeyCode == 8) // backspace
|| (KeyCode == 9) // tab
|| (KeyCode == 37) // left arrow
|| (KeyCode == 39) // right arrow
|| (KeyCode == 46) // delete
|| ((KeyCode > 47) && (KeyCode < 58)) // 0 - 9
);
}
// Gets the absolute pixel position of the supplied element
function GetTagPixels(StartTag, Direction) {
var PixelAmt = (Direction == 'LEFT') ? StartTag.offsetLeft : StartTag.offsetTop;
while ((StartTag.tagName != 'BODY') && (StartTag.tagName != 'HTML')) {
StartTag = StartTag.offsetParent;
PixelAmt += (Direction == 'LEFT') ? StartTag.offsetLeft : StartTag.offsetTop;
}
return PixelAmt;
}
// Is the specified select-list behind the calendar?
function BehindCal(SelectList, CalLeftX, CalRightX, CalTopY, CalBottomY, ListTopY) {
var ListLeftX = GetTagPixels(SelectList, 'LEFT');
var ListRightX = ListLeftX + SelectList.offsetWidth;
var ListBottomY = ListTopY + SelectList.offsetHeight;
return (((ListTopY < CalBottomY) && (ListBottomY > CalTopY)) && ((ListLeftX < CalRightX) && (ListRightX > CalLeftX)));
}
// For IE, hides any select-lists that are behind the calendar
function FixSelectLists(Over) {
if (navigator.appName == 'Microsoft Internet Explorer') {
var CalDiv = this.getCalendar();
var CalLeftX = CalDiv.offsetLeft;
var CalRightX = CalLeftX + CalDiv.offsetWidth;
var CalTopY = CalDiv.offsetTop;
var CalBottomY = CalTopY + (CellHeight * 9);
var FoundCalInput = false;
formLoop :
for (var j=this.formNumber;j<document.forms.length;j++) {
for (var i=0;i<document.forms[j].elements.length;i++) {
if (typeof document.forms[j].elements[i].type == 'string') {
if ((document.forms[j].elements[i].type == 'hidden') && (document.forms[j].elements[i].name == this.hiddenFieldName)) {
FoundCalInput = true;
i += 3; // 3 elements between the 1st hidden field and the last year input field
}
if (FoundCalInput) {
if (document.forms[j].elements[i].type.substr(0,6) == 'select') {
ListTopY = GetTagPixels(document.forms[j].elements[i], 'TOP');
if (ListTopY < CalBottomY) {
if (BehindCal(document.forms[j].elements[i], CalLeftX, CalRightX, CalTopY, CalBottomY, ListTopY)) {
document.forms[j].elements[i].style.visibility = (Over) ? 'hidden' : 'visible';
}
}
else break formLoop;
}
}
}
}
}
}
}
// Displays a message in the status bar when hovering over the calendar days
function DayCellHover(Cell, Over, Color, HoveredDay) {
Cell.style.backgroundColor = (Over) ? DayBGColor : Color;
if (Over) {
if ((this.yearValue == Today.getFullYear()) && (this.monthIndex == Today.getMonth()) && (HoveredDay == Today.getDate())) self.status = 'Click to select today';
else {
var Suffix = HoveredDay.toString();
switch (Suffix.substr(Suffix.length - 1, 1)) {
case '1' : Suffix += (HoveredDay == 11) ? 'th' : 'st'; break;
case '2' : Suffix += (HoveredDay == 12) ? 'th' : 'nd'; break;
case '3' : Suffix += (HoveredDay == 13) ? 'th' : 'rd'; break;
default : Suffix += 'th'; break;
}
self.status = 'Click to select ' + this.monthName + ' ' + Suffix;
}
}
else self.status = '';
return true;
}
// Sets the form elements after a day has been picked from the calendar
function PickDisplayDay(ClickedDay) {
this.show();
var MonthList = this.getMonthList();
var DayList = this.getDayList();
var YearField = this.getYearField();
FixDayList(DayList, GetDayCount(this.displayed.yearValue, this.displayed.monthIndex));
// Select the month and day in the lists
for (var i=0;i<MonthList.length;i++) {
if (MonthList.options[i].value == this.displayed.monthIndex) MonthList.options[i].selected = true;
}
for (var j=1;j<=DayList.length;j++) {
if (j == ClickedDay) DayList.options[j-1].selected = true;
}
this.setPicked(this.displayed.yearValue, this.displayed.monthIndex, ClickedDay);
// Change the year, if necessary
YearField.value = this.picked.yearPad;
YearField.defaultValue = YearField.value;
}
// Builds the HTML for the calendar days
function BuildCalendarDays() {
var Rows = 5;
if (((this.displayed.dayCount == 31) && (this.displayed.firstDay > 4)) || ((this.displayed.dayCount == 30) && (this.displayed.firstDay == 6))) Rows = 6;
else if ((this.displayed.dayCount == 28) && (this.displayed.firstDay == 0)) Rows = 4;
var HTML = '<table width="' + (CellWidth * 7) + '" cellspacing="0" cellpadding="1" style="cursor:default">';
for (var j=0;j<Rows;j++) {
HTML += '<tr>';
for (var i=1;i<=7;i++) {
Day = (j * 7) + (i - this.displayed.firstDay);
if ((Day >= 1) && (Day <= this.displayed.dayCount)) {
if ((this.displayed.yearValue == this.picked.yearValue) && (this.displayed.monthIndex == this.picked.monthIndex) && (Day == this.picked.day)) {
TextStyle = 'color:white;font-weight:bold;'
BackColor = DayBGColor;
}
else {
TextStyle = 'color:black;'
BackColor = CalBGColor;
}
if ((this.displayed.yearValue == Today.getFullYear()) && (this.displayed.monthIndex == Today.getMonth()) && (Day == Today.getDate())) TextStyle += 'border:1px solid darkred;padding:0px;';
HTML += '<td align="center" class="calendarDateInput" style="cursor:default;height:' + CellHeight + ';width:' + CellWidth + ';' + TextStyle + ';background-color:' + BackColor + '" onClick="' + this.objName + '.pickDay(' + Day + ')" onMouseOver="return ' + this.objName + '.displayed.dayHover(this,true,\'' + BackColor + '\',' + Day + ')" onMouseOut="return ' + this.objName + '.displayed.dayHover(this,false,\'' + BackColor + '\')">' + Day + '</td>';
}
else HTML += '<td class="calendarDateInput" style="height:' + CellHeight + '"> </td>';
}
HTML += '</tr>';
}
return HTML += '</table>';
}
// Determines which century to use (20th or 21st) when dealing with 2-digit years
function GetGoodYear(YearDigits) {
if (YearDigits.length == 4) return YearDigits;
else {
var Millennium = (YearDigits < Y2kPivotPoint) ? 2000 : 1900;
return Millennium + parseInt(YearDigits,10);
}
}
// Returns the number of days in a month (handles leap-years)
function GetDayCount(SomeYear, SomeMonth) {
return ((SomeMonth == 1) && ((SomeYear % 400 == 0) || ((SomeYear % 4 == 0) && (SomeYear % 100 != 0)))) ? 29 : MonthDays[SomeMonth];
}
// Highlights the buttons
function VirtualButton(Cell, ButtonDown) {
if (ButtonDown) {
Cell.style.borderLeft = 'buttonshadow 1px solid';
Cell.style.borderTop = 'buttonshadow 1px solid';
Cell.style.borderBottom = 'buttonhighlight 1px solid';
Cell.style.borderRight = 'buttonhighlight 1px solid';
}
else {
Cell.style.borderLeft = 'buttonhighlight 1px solid';
Cell.style.borderTop = 'buttonhighlight 1px solid';
Cell.style.borderBottom = 'buttonshadow 1px solid';
Cell.style.borderRight = 'buttonshadow 1px solid';
}
}
// Mouse-over for the previous/next month buttons
function NeighborHover(Cell, Over, DateObj) {
if (Over) {
VirtualButton(Cell, false);
self.status = 'Click to view ' + DateObj.fullName;
}
else {
Cell.style.border = 'buttonface 1px solid';
self.status = '';
}
return true;
}
// Adds/removes days from the day list, depending on the month/year
function FixDayList(DayList, NewDays) {
var DayPick = DayList.selectedIndex + 1;
if (NewDays != DayList.length) {
var OldSize = DayList.length;
for (var k=Math.min(NewDays,OldSize);k<Math.max(NewDays,OldSize);k++) {
(k >= NewDays) ? DayList.options[NewDays] = null : DayList.options[k] = new Option(k+1, k+1);
}
DayPick = Math.min(DayPick, NewDays);
DayList.options[DayPick-1].selected = true;
}
return DayPick;
}
// Resets the year to its previous valid value when something invalid is entered
function FixYearInput(YearField) {
var YearRE = new RegExp('\\d{' + YearField.defaultValue.length + '}');
if (!YearRE.test(YearField.value)) YearField.value = YearField.defaultValue;
}
// Displays a message in the status bar when hovering over the calendar icon
function CalIconHover(Over) {
var Message = (this.isShowing()) ? 'hide' : 'show';
self.status = (Over) ? 'Click to ' + Message + ' the calendar' : '';
return true;
}
// Starts the timer over from scratch
function CalTimerReset() {
eval('clearTimeout(' + this.timerID + ')');
eval(this.timerID + '=setTimeout(\'' + this.objName + '.show()\',' + (HideWait * 1000) + ')');
}
// The timer for the calendar
function DoTimer(CancelTimer) {
if (CancelTimer) eval('clearTimeout(' + this.timerID + ')');
else {
eval(this.timerID + '=null');
this.resetTimer();
}
}
// Show or hide the calendar
function ShowCalendar() {
if (this.isShowing()) {
var StopTimer = true;
this.getCalendar().style.zIndex = --ZCounter;
this.getCalendar().style.visibility = 'hidden';
this.fixSelects(false);
}
else {
var StopTimer = false;
this.fixSelects(true);
this.getCalendar().style.zIndex = ++ZCounter;
this.getCalendar().style.visibility = 'visible';
}
this.handleTimer(StopTimer);
self.status = '';
}
// Hides the input elements when the "blank" month is selected
function SetElementStatus(Hide) {
this.getDayList().style.visibility = (Hide) ? 'hidden' : 'visible';
this.getYearField().style.visibility = (Hide) ? 'hidden' : 'visible';
this.getCalendarLink().style.visibility = (Hide) ? 'hidden' : 'visible';
}
// Sets the date, based on the month selected
function CheckMonthChange(MonthList) {
var DayList = this.getDayList();
if (MonthList.options[MonthList.selectedIndex].value == '') {
DayList.selectedIndex = 0;
this.hideElements(true);
this.setHidden('');
}
else {
this.hideElements(false);
if (this.isShowing()) {
this.resetTimer(); // Gives the user more time to view the calendar with the newly-selected month
this.getCalendar().style.zIndex = ++ZCounter; // Make sure this calendar is on top of any other calendars
}
var DayPick = FixDayList(DayList, GetDayCount(this.picked.yearValue, MonthList.options[MonthList.selectedIndex].value));
this.setPicked(this.picked.yearValue, MonthList.options[MonthList.selectedIndex].value, DayPick);
}
}
// Sets the date, based on the day selected
function CheckDayChange(DayList) {
if (this.isShowing()) this.show();
this.setPicked(this.picked.yearValue, this.picked.monthIndex, DayList.selectedIndex+1);
}
// Changes the date when a valid year has been entered
function CheckYearInput(YearField) {
if ((YearField.value.length == YearField.defaultValue.length) && (YearField.defaultValue != YearField.value)) {
if (this.isShowing()) {
this.resetTimer(); // Gives the user more time to view the calendar with the newly-entered year
this.getCalendar().style.zIndex = ++ZCounter; // Make sure this calendar is on top of any other calendars
}
var NewYear = GetGoodYear(YearField.value);
var MonthList = this.getMonthList();
var NewDay = FixDayList(this.getDayList(), GetDayCount(NewYear, this.picked.monthIndex));
this.setPicked(NewYear, this.picked.monthIndex, NewDay);
YearField.defaultValue = YearField.value;
}
}
// Holds characteristics about a date
function dateObject() {
if (Function.call) { // Used when 'call' method of the Function object is supported
var ParentObject = this;
var ArgumentStart = 0;
}
else { // Used with 'call' method of the Function object is NOT supported
var ParentObject = arguments[0];
var ArgumentStart = 1;
}
ParentObject.date = (arguments.length == (ArgumentStart+1)) ? new Date(arguments[ArgumentStart+0]) : new Date(arguments[ArgumentStart+0], arguments[ArgumentStart+1], arguments[ArgumentStart+2]);
ParentObject.yearValue = ParentObject.date.getFullYear();
ParentObject.monthIndex = ParentObject.date.getMonth();
ParentObject.monthName = MonthNames[ParentObject.monthIndex];
ParentObject.fullName = ParentObject.monthName + ' ' + ParentObject.yearValue;
ParentObject.day = ParentObject.date.getDate();
ParentObject.dayCount = GetDayCount(ParentObject.yearValue, ParentObject.monthIndex);
var FirstDate = new Date(ParentObject.yearValue, ParentObject.monthIndex, 1);
ParentObject.firstDay = FirstDate.getDay();
}
// Keeps track of the date that goes into the hidden field
function storedMonthObject(DateFormat, DateYear, DateMonth, DateDay) {
(Function.call) ? dateObject.call(this, DateYear, DateMonth, DateDay) : dateObject(this, DateYear, DateMonth, DateDay);
this.yearPad = this.yearValue.toString();
this.monthPad = (this.monthIndex < 9) ? '0' + String(this.monthIndex + 1) : this.monthIndex + 1;
this.dayPad = (this.day < 10) ? '0' + this.day.toString() : this.day;
this.monthShort = this.monthName.substr(0,3).toUpperCase();
// Formats the year with 2 digits instead of 4
if (DateFormat.indexOf('YYYY') == -1) this.yearPad = this.yearPad.substr(2);
// Define the date-part delimiter
if (DateFormat.indexOf('/') >= 0) var Delimiter = '/';
else if (DateFormat.indexOf('-') >= 0) var Delimiter = '-';
else var Delimiter = '';
// Determine the order of the months and days
if (/DD?.?((MON)|(MM?M?))/.test(DateFormat)) {
this.formatted = this.dayPad + Delimiter;
this.formatted += (RegExp.$1.length == 3) ? this.monthShort : this.monthPad;
}
else if (/((MON)|(MM?M?))?.?DD?/.test(DateFormat)) {
this.formatted = (RegExp.$1.length == 3) ? this.monthShort : this.monthPad;
this.formatted += Delimiter + this.dayPad;
}
// Either prepend or append the year to the formatted date
this.formatted = (DateFormat.substr(0,2) == 'YY') ? this.yearPad + Delimiter + this.formatted : this.formatted + Delimiter + this.yearPad;
}
// Object for the current displayed month
function displayMonthObject(ParentObject, DateYear, DateMonth, DateDay) {
(Function.call) ? dateObject.call(this, DateYear, DateMonth, DateDay) : dateObject(this, DateYear, DateMonth, DateDay);
this.displayID = ParentObject.hiddenFieldName + '_Current_ID';
this.getDisplay = new Function('return document.getElementById(this.displayID)');
this.dayHover = DayCellHover;
this.goCurrent = new Function(ParentObject.objName + '.getCalendar().style.zIndex=++ZCounter;' + ParentObject.objName + '.setDisplayed(Today.getFullYear(),Today.getMonth());');
if (ParentObject.formNumber >= 0) this.getDisplay().innerHTML = this.fullName;
}
// Object for the previous/next buttons
function neighborMonthObject(ParentObject, IDText, DateMS) {
(Function.call) ? dateObject.call(this, DateMS) : dateObject(this, DateMS);
this.buttonID = ParentObject.hiddenFieldName + '_' + IDText + '_ID';
this.hover = new Function('C','O','NeighborHover(C,O,this)');
this.getButton = new Function('return document.getElementById(this.buttonID)');
this.go = new Function(ParentObject.objName + '.getCalendar().style.zIndex=++ZCounter;' + ParentObject.objName + '.setDisplayed(this.yearValue,this.monthIndex);');
if (ParentObject.formNumber >= 0) this.getButton().title = this.monthName;
}
// Sets the currently-displayed month object
function SetDisplayedMonth(DispYear, DispMonth) {
this.displayed = new displayMonthObject(this, DispYear, DispMonth, 1);
// Creates the previous and next month objects
this.previous = new neighborMonthObject(this, 'Previous', this.displayed.date.getTime() - 86400000);
this.next = new neighborMonthObject(this, 'Next', this.displayed.date.getTime() + (86400000 * (this.displayed.dayCount + 1)));
// Creates the HTML for the calendar
if (this.formNumber >= 0) this.getDayTable().innerHTML = this.buildCalendar();
}
// Sets the current selected date
function SetPickedMonth(PickedYear, PickedMonth, PickedDay) {
this.picked = new storedMonthObject(this.format, PickedYear, PickedMonth, PickedDay);
this.setHidden(this.picked.formatted);
this.setDisplayed(PickedYear, PickedMonth);
}
// The calendar object
function calendarObject(DateName, DateFormat, DefaultDate) {
/* Properties */
this.hiddenFieldName = DateName;
this.monthListID = DateName + '_Month_ID';
this.dayListID = DateName + '_Day_ID';
this.yearFieldID = DateName + '_Year_ID';
this.monthDisplayID = DateName + '_Current_ID';
this.calendarID = DateName + '_ID';
this.dayTableID = DateName + '_DayTable_ID';
this.calendarLinkID = this.calendarID + '_Link';
this.timerID = this.calendarID + '_Timer';
this.objName = DateName + '_Object';
this.format = DateFormat;
this.formNumber = -1;
this.picked = null;
this.displayed = null;
this.previous = null;
this.next = null;
/* Methods */
this.setPicked = SetPickedMonth;
this.setDisplayed = SetDisplayedMonth;
this.checkYear = CheckYearInput;
this.fixYear = FixYearInput;
this.changeMonth = CheckMonthChange;
this.changeDay = CheckDayChange;
this.resetTimer = CalTimerReset;
this.hideElements = SetElementStatus;
this.show = ShowCalendar;
this.handleTimer = DoTimer;
this.iconHover = CalIconHover;
this.buildCalendar = BuildCalendarDays;
this.pickDay = PickDisplayDay;
this.fixSelects = FixSelectLists;
this.setHidden = new Function('D','if (this.formNumber >= 0) this.getHiddenField().value=D');
// Returns a reference to these elements
this.getHiddenField = new Function('return document.forms[this.formNumber].elements[this.hiddenFieldName]');
this.getMonthList = new Function('return document.getElementById(this.monthListID)');
this.getDayList = new Function('return document.getElementById(this.dayListID)');
this.getYearField = new Function('return document.getElementById(this.yearFieldID)');
this.getCalendar = new Function('return document.getElementById(this.calendarID)');
this.getDayTable = new Function('return document.getElementById(this.dayTableID)');
this.getCalendarLink = new Function('return document.getElementById(this.calendarLinkID)');
this.getMonthDisplay = new Function('return document.getElementById(this.monthDisplayID)');
this.isShowing = new Function('return !(this.getCalendar().style.visibility != \'visible\')');
/* Constructor */
// Functions used only by the constructor
function getMonthIndex(MonthAbbr) { // Returns the index (0-11) of the supplied month abbreviation
for (var MonPos=0;MonPos<MonthNames.length;MonPos++) {
if (MonthNames[MonPos].substr(0,3).toUpperCase() == MonthAbbr.toUpperCase()) break;
}
return MonPos;
}
function SetGoodDate(CalObj, Notify) { // Notifies the user about their bad default date, and sets the current system date
CalObj.setPicked(Today.getFullYear(), Today.getMonth(), Today.getDate());
if (Notify) alert('WARNING: The supplied date is not in valid \'' + DateFormat + '\' format: ' + DefaultDate + '.\nTherefore, the current system date will be used instead: ' + CalObj.picked.formatted);
}
// Main part of the constructor
if (DefaultDate != '') {
if ((this.format == 'YYYYMMDD') && (/^(\d{4})(\d{2})(\d{2})$/.test(DefaultDate))) this.setPicked(RegExp.$1, parseInt(RegExp.$2,10)-1, RegExp.$3);
else {
// Get the year
if ((this.format.substr(0,2) == 'YY') && (/^(\d{2,4})(-|\/)/.test(DefaultDate))) { // Year is at the beginning
var YearPart = GetGoodYear(RegExp.$1);
// Determine the order of the months and days
if (/(-|\/)(\w{1,3})(-|\/)(\w{1,3})$/.test(DefaultDate)) {
var MidPart = RegExp.$2;
var EndPart = RegExp.$4;
if (/D$/.test(this.format)) { // Ends with days
var DayPart = EndPart;
var MonthPart = MidPart;
}
else {
var DayPart = MidPart;
var MonthPart = EndPart;
}
MonthPart = (/\d{1,2}/i.test(MonthPart)) ? parseInt(MonthPart,10)-1 : getMonthIndex(MonthPart);
this.setPicked(YearPart, MonthPart, DayPart);
}
else SetGoodDate(this, true);
}
else if (/(-|\/)(\d{2,4})$/.test(DefaultDate)) { // Year is at the end
var YearPart = GetGoodYear(RegExp.$2);
// Determine the order of the months and days
if (/^(\w{1,3})(-|\/)(\w{1,3})(-|\/)/.test(DefaultDate)) {
if (this.format.substr(0,1) == 'D') { // Starts with days
var DayPart = RegExp.$1;
var MonthPart = RegExp.$3;
}
else { // Starts with months
var MonthPart = RegExp.$1;
var DayPart = RegExp.$3;
}
MonthPart = (/\d{1,2}/i.test(MonthPart)) ? parseInt(MonthPart,10)-1 : getMonthIndex(MonthPart);
this.setPicked(YearPart, MonthPart, DayPart);
}
else SetGoodDate(this, true);
}
else SetGoodDate(this, true);
}
}
}
// Main function that creates the form elements
function DateInput(DateName, Required, DateFormat, DefaultDate) {
if (arguments.length == 0) document.writeln('<span style="color:red;font-size:' + FontSize + 'px;font-family:' + FontFamily + ';">ERROR: Missing required parameter in call to \'DateInput\': [name of hidden date field].</span>');
else {
// Handle DateFormat
if (arguments.length < 3) { // The format wasn't passed in, so use default
DateFormat = DefaultDateFormat;
if (arguments.length < 2) Required = false;
}
else if (/^(Y{2,4}(-|\/)?)?((MON)|(MM?M?)|(DD?))(-|\/)?((MON)|(MM?M?)|(DD?))((-|\/)Y{2,4})?$/i.test(DateFormat)) DateFormat = DateFormat.toUpperCase();
else { // Passed-in DateFormat was invalid, use default format instead
var AlertMessage = 'WARNING: The supplied date format for the \'' + DateName + '\' field is not valid: ' + DateFormat + '\nTherefore, the default date format will be used instead: ' + DefaultDateFormat;
DateFormat = DefaultDateFormat;
if (arguments.length == 4) { // DefaultDate was passed in with an invalid date format
var CurrentDate = new storedMonthObject(DateFormat, Today.getFullYear(), Today.getMonth(), Today.getDate());
AlertMessage += '\n\nThe supplied date (' + DefaultDate + ') cannot be interpreted with the invalid format.\nTherefore, the current system date will be used instead: ' + CurrentDate.formatted;
DefaultDate = CurrentDate.formatted;
}
alert(AlertMessage);
}
// Define the current date if it wasn't set already
if (!CurrentDate) var CurrentDate = new storedMonthObject(DateFormat, Today.getFullYear(), Today.getMonth(), Today.getDate());
// Handle DefaultDate
if (arguments.length < 4) { // The date wasn't passed in
DefaultDate = (Required) ? CurrentDate.formatted : ''; // If required, use today's date
}
// Creates the calendar object!
eval(DateName + '_Object=new calendarObject(\'' + DateName + '\',\'' + DateFormat + '\',\'' + DefaultDate + '\')');
// Determine initial viewable state of day, year, and calendar icon
if ((Required) || (arguments.length == 4)) {
var InitialStatus = '';
var InitialDate = eval(DateName + '_Object.picked.formatted');
}
else {
var InitialStatus = ' style="visibility:hidden"';
var InitialDate = '';
eval(DateName + '_Object.setPicked(' + Today.getFullYear() + ',' + Today.getMonth() + ',' + Today.getDate() + ')');
}
// Create the form elements
with (document) {
writeln('<input type="hidden" name="' + DateName + '" value="' + InitialDate + '">');
// Find this form number
for (var f=0;f<forms.length;f++) {
for (var e=0;e<forms[f].elements.length;e++) {
if (typeof forms[f].elements[e].type == 'string') {
if ((forms[f].elements[e].type == 'hidden') && (forms[f].elements[e].name == DateName)) {
eval(DateName + '_Object.formNumber='+f);
break;
}
}
}
}
writeln('<table cellpadding="0" cellspacing="2"><tr>' + String.fromCharCode(13) + '<td valign="middle">');
writeln('<select class="calendarDateInput" id="' + DateName + '_Month_ID" onChange="' + DateName + '_Object.changeMonth(this)">');
if (!Required) {
var NoneSelected = (DefaultDate == '') ? ' selected' : '';
writeln('<option value=""' + NoneSelected + '>' + UnselectedMonthText + '</option>');
}
for (var i=0;i<12;i++) {
MonthSelected = ((DefaultDate != '') && (eval(DateName + '_Object.picked.monthIndex') == i)) ? ' selected' : '';
writeln('<option value="' + i + '"' + MonthSelected + '>' + MonthNames[i].substr(0,3) + '</option>');
}
writeln('</select>' + String.fromCharCode(13) + '</td>' + String.fromCharCode(13) + '<td valign="middle">');
writeln('<select' + InitialStatus + ' class="calendarDateInput" id="' + DateName + '_Day_ID" onChange="' + DateName + '_Object.changeDay(this)">');
for (var j=1;j<=eval(DateName + '_Object.picked.dayCount');j++) {
DaySelected = ((DefaultDate != '') && (eval(DateName + '_Object.picked.day') == j)) ? ' selected' : '';
writeln('<option' + DaySelected + '>' + j + '</option>');
}
writeln('</select>' + String.fromCharCode(13) + '</td>' + String.fromCharCode(13) + '<td valign="middle">');
writeln('<input' + InitialStatus + ' class="calendarDateInput" type="text" id="' + DateName + '_Year_ID" size="' + eval(DateName + '_Object.picked.yearPad.length') + '" maxlength="' + eval(DateName + '_Object.picked.yearPad.length') + '" title="Year" value="' + eval(DateName + '_Object.picked.yearPad') + '" onKeyPress="return YearDigitsOnly(window.event)" onKeyUp="' + DateName + '_Object.checkYear(this)" onBlur="' + DateName + '_Object.fixYear(this)">');
write('<td valign="middle">' + String.fromCharCode(13) + '<a' + InitialStatus + ' id="' + DateName + '_ID_Link" href="javascript:' + DateName + '_Object.show()" onMouseOver="return ' + DateName + '_Object.iconHover(true)" onMouseOut="return ' + DateName + '_Object.iconHover(false)"><img src="' + ImageURL + '" class="calendarDateInput" align="baseline" title="Calendar" border="0"></a> ');
writeln('<span id="' + DateName + '_ID" style="position:absolute;visibility:hidden;width:' + (CellWidth * 7) + 'px;background-color:' + CalBGColor + ';border:1px solid dimgray;" onMouseOver="' + DateName + '_Object.handleTimer(true)" onMouseOut="' + DateName + '_Object.handleTimer(false)">');
writeln('<table width="' + (CellWidth * 7) + '" cellspacing="0" cellpadding="1">' + String.fromCharCode(13) + '<tr style="background-color:' + TopRowBGColor + ';">');
writeln('<td id="' + DateName + '_Previous_ID" style="cursor:default" align="center" class="calendarDateInput" style="height:' + CellHeight + '" onClick="' + DateName + '_Object.previous.go()" onMouseDown="VirtualButton(this,true)" onMouseUp="VirtualButton(this,false)" onMouseOver="return ' + DateName + '_Object.previous.hover(this,true)" onMouseOut="return ' + DateName + '_Object.previous.hover(this,false)" title="' + eval(DateName + '_Object.previous.monthName') + '"><img src="' + PrevURL + '"></td>');
writeln('<td id="' + DateName + '_Current_ID" style="cursor:pointer" align="center" class="calendarDateInput" style="height:' + CellHeight + '" colspan="5" onClick="' + DateName + '_Object.displayed.goCurrent()" onMouseOver="self.status=\'Click to view ' + CurrentDate.fullName + '\';return true;" onMouseOut="self.status=\'\';return true;" title="Show Current Month">' + eval(DateName + '_Object.displayed.fullName') + '</td>');
writeln('<td id="' + DateName + '_Next_ID" style="cursor:default" align="center" class="calendarDateInput" style="height:' + CellHeight + '" onClick="' + DateName + '_Object.next.go()" onMouseDown="VirtualButton(this,true)" onMouseUp="VirtualButton(this,false)" onMouseOver="return ' + DateName + '_Object.next.hover(this,true)" onMouseOut="return ' + DateName + '_Object.next.hover(this,false)" title="' + eval(DateName + '_Object.next.monthName') + '"><img src="' + NextURL + '"></td></tr>' + String.fromCharCode(13) + '<tr>');
for (var w=0;w<7;w++) writeln('<td width="' + CellWidth + '" align="center" class="calendarDateInput" style="height:' + CellHeight + ';width:' + CellWidth + ';font-weight:bold;border-top:1px solid dimgray;border-bottom:1px solid dimgray;">' + WeekDays[w] + '</td>');
writeln('</tr>' + String.fromCharCode(13) + '</table>' + String.fromCharCode(13) + '<span id="' + DateName + '_DayTable_ID">' + eval(DateName + '_Object.buildCalendar()') + '</span>' + String.fromCharCode(13) + '</span>' + String.fromCharCode(13) + '</td>' + String.fromCharCode(13) + '</tr>' + String.fromCharCode(13) + '</table>');
}
}
}