source: ether_megapoli/trunk/web/resources/js/medias/scw.js @ 155

Last change on this file since 155 was 155, checked in by vmipsl, 13 years ago

Import medias files and cleanup

File size: 94.0 KB
Line 
1// *****************************************************************************
2//      Simple Calendar Widget - Cross-Browser Javascript pop-up calendar.
3//
4//   Copyright (C) 2005-2007  Anthony Garrett
5//
6//   This library is free software; you can redistribute it and/or
7//   modify it under the terms of the GNU Lesser General Public
8//   License as published by the Free Software Foundation; either
9//   version 2.1 of the License, or (at your option) any later version.
10//
11//   This library is distributed in the hope that it will be useful,
12//   but WITHOUT ANY WARRANTY; without even the implied warranty of
13//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14//   Lesser General Public License for more details.
15//
16//   You should have received a copy of the GNU Lesser General Public
17//   License along with this library; if not, it is available at
18//   the GNU web site (http://www.gnu.org/) or by writing to the
19//   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20//   Boston, MA  02110-1301  USA
21//
22// *****************************************************************************
23//
24// Contact:   Sorry, I can't offer support for this but if you find a problem
25//            (or just want to tell me how useful you find it), please send
26//            me an email at scwfeedback@tarrget.info (Note the two Rs in
27//            tarrget).  I will try to fix problems quickly but this is a
28//            spare time thing for me.
29//
30// Credits:   I wrote this from scratch myself but I couldn't have done it
31//            without the superb "JavaScript The Definitive Guide" by David
32//            Flanagan (Pub. O'Reilly ISBN 0-596-00048-0).  I also recognise
33//            a contribution from my experience with PopCalendar 4.1 by
34//            Liming(Victor) Weng.
35//
36// Link back: Please give me credit and link back to my page.  To ensure that
37//            search engines give my page a higher ranking you can add the
38//            following HTML to any indexed page on your web site:
39//
40//            <A HREF="http://www.tarrget.info/calendar/scw.htm">
41//              Simple Calendar Widget by Anthony Garrett
42//            </A>
43//
44// Features:  Easily customised
45//                  (output date format, colours, language, year range and
46//                   week start day)
47//            Accepts a date as input
48//                  (see comments below for formats).
49//            Cross-browser code tested against;
50//                  Internet Explorer 6.0.28     Mozilla  1.7.1
51//                  Opera             7.52+      Firefox  0.9.1+
52//                  Konqueror         3.4.0      Flock    0.4.9
53//
54// How to add the Calendar to your page:
55//            This script needs to be defined for your page so, immediately
56//            after the BODY tag add the following line;
57//
58//                  <script type='Text/JavaScript' src='scw.js'></script>
59//
60//            Your root directory of the web site should also contain an empty
61//            file called "scwblank.html". See
62//                  http://www.tarrget.info/calendar/IEnightmare.html
63//            for a full explanation.
64//
65// How to use the Calendar once it is defined for your page:
66//
67//            Simply choose an event to trigger the calendar (like an onClick
68//            or an onMouseOver) and an element to work on (for the calendar
69//            to take its initial date from and write its output date to) then
70//            write it like this;
71//
72//                  <<event>>="scwShow(<<element>>,event);"
73//
74//            e.g. onClick="scwShow(scwID('myElement'),event);"
75//            or   onMouseOver="scwShow(this,event);"
76//
77//            NOTE: If you wish to use the calendar with an Anchor tag, do
78//                  not use the syntax:   href="javascript:scwShow(...)"
79//                  Instead you should use the following;
80//
81//                  <a href="#" onclick="scwShow(<<element>>,event);return false;">
82//                      <<your text>>
83//                  </a>
84//
85//            If you are using a text node then specify the text's parent node
86//            in the function call. The date should be the only text under that
87//            node;
88//
89//            e.g.  <p onclick="scwShow(this,event);"><<date>></p>
90//
91//            You can also disable days of the week by adding arguments to the
92//            call to scwShow.  The values should be Sunday = 0 through to
93//            Saturday = 6.  A call to scwShow with Friday and Monday disabled
94//            would look something like this;
95//
96//                  scwShow(<<element>>,event,5,1);
97//
98//            Finally you can use the following technique to run a function
99//            when the calendar closes:
100//
101//                  scwNextAction=<<function>>.runsAfterSCW(this,<<arguments>>);
102//                  scwShow(<<element>>,event <<,optional arguments above>>);
103//
104//            Where <<function>> is a function defined on the calling page
105//            and <<arguments>> is the list of arguments being passed to that
106//            function.
107//
108//      No event? No problem!
109//
110//            Normally the calendar will be triggered by an event but if you wish to
111//            control it in code and the event is not available to you, simply pass
112//            an element as the second parameter;
113//
114//            E.G.  scwShow(<<target element>>,<<source element>>);
115//                  as in: scwShow(this,this);
116//
117//            ------------------------------------------------------------------
118//            Here's an extremely trivial but fully functioning example page
119//            showing two of the ways to trigger the calendar;
120//
121//            <html>
122//                <head><title>Basic Example</title></head>
123//                <body>
124//                    <script type='text/JavaScript' src='scw.js'></script>
125//                    <p onclick='scwShow(this,event);'>06-Dec-2006</p>
126//                    <input onclick='scwShow(this,event);' value='07-Dec-2006' />
127//                    <br/><br/>
128//                    <a href='#' onclick='scwShow(this,event);return false;'>
129//                        08-Dec-2006
130//                    </a>
131//                </body>
132//            </html>
133//
134// *****************************************************************************
135//
136// See http://www.tarrget.info/calendar/scw.htm for a complete version history
137//
138// Version   Date        By               Description
139// =======   ====        ===============  ===========
140//   3.58    2007-04-04  Anthony Garrett  Resolved an error caused when the date
141//                                         range does not include the current year.
142//                                         Thanks to Steve Davis for letting me know.
143//
144//                                        Fixed "Today" selector display which
145//                                         was incorrectly visible when year range
146//                                         ended last year. (Also the result of
147//                                         investigations based on Steve Davis'
148//                                         feedback).
149//
150//   3.59    2007-06-13  Anthony Garrett  Added Verdana to font list of
151//                                         calendar's CSS.  Resolves rendering
152//                                         bug in Safari Beta 3 for Windows.
153//
154//   3.60    2007-07-31  Anthony Garrett  Fixed javascript error that occurred
155//                                         when the target element had no value
156//                                         attribute.  The error had no impact
157//                                         on the behaviour of the script.  Thanks
158//                                         to John Phelps for reporting this bug.
159//
160//   3.70    2007-09-21  Anthony Garrett  Updated the event trapping to make it
161//                                         less intrusive on the page body.
162//                                         NOTE: This requires that a calendar's
163//                                         second parameter should be the calling
164//                                         event (not the calling object as in
165//                                         previous versions).
166//                                         Thanks to Steve Davis for the bug report
167//                                         that led to this change.
168//
169//                                        Fixed a bug that caused undelimited
170//                                         dates to be handled incorrectly. They
171//                                         are now parsed against the full date
172//                                         output format then checked for validity.
173//                                         Thanks to Dan Wood for raising this bug.
174//
175//                                        Replaced the date input sequence user
176//                                         configuration setting with parsing the
177//                                         sequence from the full format. New users
178//                                         are often confused by the sequence and
179//                                         in practice (to allow the calendar's date
180//                                         output to be used for input) the sequence
181//                                         must always match the full format element
182//                                         order.
183//
184//                                        Extended IFRAME backing to all calendar objects
185//                                         in order to improve calendar display over
186//                                         some embedded applets and objects.  Thanks to
187//                                         Stanko Kupcevic for his feedback on this.
188//                                         NOTE: It is not possible to protect any
189//                                         JavaScript object displayed over an
190//                                         embedded DYNAMIC (and, therefore refreshed)
191//                                         object because browsers usually do not
192//                                         directly control the screen handling within
193//                                         the object.  The best advice therefore remains
194//                                         to design pages in such a way that the calendar
195//                                         does not overlap embedded objects.
196//
197//  3.71     2008-12-14  Anthony Garrett  Restored the ability to use an element
198//                                         as the second parameter when opening a
199//                                         calendar while retaining the option
200//                                         of passing an event. Thanks to Thierry Blind
201//                                         and Sergey Snovsky for the feedback.
202//
203//  3.72     2008-02-24  Anthony Garrett  Trapped calls to script with only a
204//                                         NAME attribute is set for the target
205//                                         element when the script really requires
206//                                         an ID attribute.  This is the most
207//                                         frequent mistake reported to me.
208//
209//  3.73     2008-04-11  Anthony Garrett  Corrected the input month name parsing
210//                                         so that it set the calendar to the
211//                                         right month when long month names used.
212//                                         Thanks to Ben Diamand for this bug report.
213//
214//  3.80     2008-04-29  Anthony Garrett  Added optional auto-positioning of the
215//                                         calendar when its normal position would
216//                                         go off the visible area.
217//                                         Thanks to Chandramouli Iyer for this
218//                                         suggestion.
219//
220//  3.90     2008-05-05  Anthony Garrett  Added an optional "Clear" button for
221//                                         use when handling a read-only text
222//                                         input element. Thanks to Sanjay Gangwal
223//                                         for his suggestion.
224// *****************************************************************************
225
226// ************************************
227// Start of Simple Calendar Widget Code
228// ************************************
229
230// This date is used throughout to determine today's date.
231
232    var scwDateNow = new Date(Date.parse(new Date().toDateString()));
233
234//******************************************************************************
235//------------------------------------------------------------------------------
236// Customisation section
237//------------------------------------------------------------------------------
238//******************************************************************************
239
240    // Set the bounds for the calendar here...
241    // If you want the year to roll forward you can use something like this...
242    //      var scwBaseYear = scwDateNow.getFullYear()-5;
243    // alternatively, hard code a date like this...
244    //      var scwBaseYear = 1990;
245
246    var scwBaseYear        = scwDateNow.getFullYear()-10;
247
248    // How many years do want to be valid and to show in the drop-down list?
249
250    var scwDropDownYears   = 20;
251
252    // All language-dependent changes can be made here...
253
254    // If you wish to work in a single language (other than English) then
255    // just replace the English (in the function scwSetLanguage below) with
256    // your own text.
257
258    // Using multiple languages:
259    // In order to keep this script to a resonable size I have not included
260    // languages here.  You can set language fields in a function that you
261    // should call  scwSetLanguage  the script will use your languages.
262    // I have included all the translations that have been sent to me in
263    // such a function on the demonstration page.
264
265    var scwLanguage;
266
267    function scwSetDefaultLanguage()
268        {try
269            {scwSetLanguage();}
270         catch (exception)
271            {// English
272             scwToday               = 'Today:';
273             scwClear               = 'Clear';
274             scwDrag                = 'click here to drag';
275             scwArrMonthNames       = ['Jan','Feb','Mar','Apr','May','Jun',
276                                       'Jul','Aug','Sep','Oct','Nov','Dec'];
277             scwArrWeekInits        = ['S','M','T','W','T','F','S'];
278             scwInvalidDateMsg      = 'The entered date is invalid.\n';
279             scwOutOfRangeMsg       = 'The entered date is out of range.';
280             scwDoesNotExistMsg     = 'The entered date does not exist.';
281             scwInvalidAlert        = ['Invalid date (',') ignored.'];
282             scwDateDisablingError  = ['Error ',' is not a Date object.'];
283             scwRangeDisablingError = ['Error ',
284                                       ' should consist of two elements.'];
285            }
286        };
287
288    // Note:  Always start the scwArrWeekInits array with your string for
289    //        Sunday whatever scwWeekStart (below) is set to.
290
291    // scwWeekStart determines the start of the week in the display
292    // Set it to: 0 (Zero) for Sunday, 1 (One) for Monday etc..
293
294    var scwWeekStart       =    1;
295
296    // The week start day for the display is taken as the week start
297    // for week numbering.  This ensures that only one week number
298    // applies to one line of the calendar table.
299    // [ISO 8601 begins the week with Day 1 = Monday.]
300
301    // If you want to see week numbering on the calendar, set
302    // this to true.  If not, false.
303
304    var scwWeekNumberDisplay    = false;
305
306    // Week numbering rules are generally based on a day in the week
307    // that determines the first week of the year.  ISO 8601 uses
308    // Thursday (day four when Sunday is day zero).  You can alter
309    // the base day here.
310
311    // See http://www.cl.cam.ac.uk/~mgk25/iso-time.html for more information
312
313    var scwWeekNumberBaseDay    = 4;
314
315    // Each of the calendar's alert message types can be disabled
316    // independently here.
317
318    var scwShowInvalidDateMsg       = true,
319        scwShowOutOfRangeMsg        = true,
320        scwShowDoesNotExistMsg      = true,
321        scwShowInvalidAlert         = true,
322        scwShowDateDisablingError   = true,
323        scwShowRangeDisablingError  = true;
324
325    // Set the allowed input date delimiters here...
326    // E.g. To set the rising slash, hyphen, full-stop (aka stop or point),
327    //      comma and space as delimiters use
328    //              var scwArrDelimiters   = ['/','-','.',',',' '];
329
330    var scwArrDelimiters   = ['/','-','.',',',' '];
331
332    // Set the format for the displayed 'Today' date and for the output
333    // date here.
334    //
335    // The format is described using delimiters of your choice (as set
336    // in scwArrDelimiters above) and case insensitive letters D, M and Y.
337    //
338    // NOTE: If no delimiters are input then the date output format is used
339    //       to parse the value.  This allows less flexiblility in the input
340    //       value than using delimiters but an accurately entered date
341    //       remains parsable.
342    //
343    // Definition               Returns
344    // ----------               -------
345    // D            date in the month without zero filling
346    // DD           date in the month left zero filled
347    // M            month number without zero filling
348    // MM           month number left zero filled
349    // MMM          month string from scwArrMonthNames
350    // YY           year number in two digits
351    // YYYY         year number in four digits
352
353    // Displayed "Today" date format
354
355    var scwDateDisplayFormat = 'dd/mm/yy';     // e.g. 'MMM-DD-YYYY' for the US
356
357    // Output date format
358
359    var scwDateOutputFormat  = 'DD/MM/YYYY'; // e.g. 'MMM-DD-YYYY' for the US
360
361    // Note: The delimiters used should be in scwArrDelimiters.
362
363    // scwZindex controls how the pop-up calendar interacts with the rest
364    // of the page.  It is usually adequate to leave it as 1 (One) but I
365    // have made it available here to help anyone who needs to alter the
366    // level in order to ensure that the calendar displays correctly in
367    // relation to all other elements on the page.
368
369    var scwZindex          = 1;
370
371    // Personally I like the fact that entering 31-Sep-2005 displays
372    // 1-Oct-2005, however you may want that to be an error.  If so,
373    // set scwBlnStrict = true.  That will cause an error message to
374    // display and the selected month is displayed without a selected
375    // day. Thanks to Brad Allan for his feedback prompting this feature.
376
377    var scwBlnStrict       = false;
378
379    // If you are using ReadOnly or Disabled fields to return the date
380    // value into, it can be useful to show a button on the calendar
381    // that allows the value to be cleared.  If you want to do that,
382    // set scwClearButton = true;
383
384    var scwClearButton     = true;
385
386    // The calendar will position itself aligned with the bottom left
387    // corner of the target element.  If automatic positioning is turned
388    // on  with  scwAutoPosition = true  then if that would cause the
389    // calendar to display off the visible screen, it is shifted to
390    // a position that is visible.
391
392    var scwAutoPosition    = true;
393
394    // If you wish to disable any displayed day, e.g. Every Monday,
395    // you can do it by setting the following array.  The array elements
396    // match the displayed cells.
397    //
398    // You could put something like the following in your calling page
399    // to disable all weekend days;
400    //
401    //  for (var i=0;i<scwEnabledDay.length;i++)
402    //      {if (i%7%6==0) scwEnabledDay[i] = false;}
403    //
404    // The above approach will allow you to disable days of the week
405    // for the whole of your page easily.  If you need to set different
406    // disabled days for a number of date input fields on your page
407    // there is an easier way: You can pass additional arguments to
408    // scwShow. The syntax is described at the top of this script in
409    // the section:
410    //    "How to use the Calendar once it is defined for your page:"
411    //
412    // It is possible to use these two approaches in combination.
413
414    var scwEnabledDay      = [true, true, true, true, true, true, true,
415                              true, true, true, true, true, true, true,
416                              true, true, true, true, true, true, true,
417                              true, true, true, true, true, true, true,
418                              true, true, true, true, true, true, true,
419                              true, true, true, true, true, true, true];
420
421    // You can disable any specific date (e.g. 24-Jan-2006 or Today) by
422    // creating an element of the array scwDisabledDates as a date object
423    // with the value you want to disable.  Date ranges can be disabled
424    // by placing an array of two values (Start and End) into an element
425    // of this array.
426
427    var scwDisabledDates   = new Array();
428
429    // e.g. To disable 10-Dec-2005:
430    //          scwDisabledDates[0] = new Date(2005,11,10);
431    //
432    //      or a range from 2004-Dec-25 to 2005-Jan-01:
433    //          scwDisabledDates[1] = [new Date(2004,11,25),new Date(2005,0,1)];
434    //
435    // Remember that Javascript months are Zero-based.
436
437    // The disabling by date and date range does prevent the current day
438    // from being selected.  Disabling days of the week does not so you can set
439    // the scwActiveToday value to false to prevent selection.
440
441    var scwActiveToday = true;
442
443    // Dates that are out of the displayed month are shown at the start
444    // (unless the month starts on the first day of the week) and end of each
445    // month.
446    //
447    // Set scwOutOfMonthDisable to  true  to disable these dates (or  false
448    // to allow their selection).
449    //
450    // Set scwOutOfMonthHide    to  true  to hide    these dates (or  false
451    // to make them visible).
452
453    var scwOutOfMonthDisable = false;
454    var scwOutOfMonthHide    = false;
455
456    // Dates that are out of the specified range can be displayed at the start
457    // of the very first month and end of the very last.  Set
458    // scwOutOfRangeDisable to  true  to disable these dates (or  false  to
459    // allow their selection).
460
461    var scwOutOfRangeDisable = true;
462
463    // If you want a special format for the cell that contains the current day
464    // set this to true.  This sets a thin border around the cell in the colour
465    // set by scwTodayCellBorderColour.
466
467    var scwFormatTodayCell = true;
468    var scwTodayCellBorderColour = 'red';
469
470    // You can allow the calendar to be dragged around the screen by
471    // using the setting scwAllowDrag to true.
472    // I can't say I recommend it because of the danger of the user
473    // forgetting which date field the calendar will update when there
474    // are multiple date fields on a page.
475
476    var scwAllowDrag = false;
477
478    // Closing the calendar by clicking on it (rather than elsewhere on the
479    // main page) can be inconvenient.  The scwClickToHide boolean value
480    // controls this feature.
481
482    var scwClickToHide = false;
483
484    // I have made every effort to isolate the pop-up script from any
485    // CSS defined on the main page but if you have anything set that
486    // affects the pop-up (or you may want to change the way it looks)
487    // then you can address it in the following style sheets.
488
489    document.writeln(
490        '<style type="text/css">'                                       +
491            '.scw           {padding:1px;vertical-align:middle;}'       +
492            'iframe.scw     {position:absolute;z-index:' + scwZindex    +
493                            ';top:0px;left:0px;visibility:hidden;'      +
494                            'width:1px;height:1px;}'                    +
495            'table.scw      {padding:0px;visibility:hidden;'            +
496                            'position:absolute;cursor:default;'         +
497                            'width:200px;top:0px;left:0px;'             +
498                            'z-index:' + (scwZindex+1)                  +
499                            ';text-align:center;}'                      +
500        '</style>'  );
501
502    // This style sheet can be extracted from the script and edited into regular
503    // CSS (by removing all occurrences of + and '). That can be used as the
504    // basis for themes. Classes are described in comments within the style
505    // sheet.
506
507    document.writeln(
508        '<style type="text/css">'                                       +
509            '/* IMPORTANT:  The SCW calendar script requires all '      +
510            '               the classes defined here.'                  +
511            '*/'                                                        +
512            'table.scw      {padding:       1px;'                       +
513                            'vertical-align:middle;'                    +
514                            'border:        ridge 2px;'                 +
515                            'font-size:     10pt;'                      +
516                            'font-family:   ' +
517                                   'Verdana,Arial,Helvetica,Sans-Serif;'+
518                            'font-weight:   bold;}'                     +
519            'td.scwDrag,'                                               +
520            'td.scwHead                 {padding:       0px 0px;'       +
521                                        'text-align:    center;}'       +
522            'td.scwDrag                 {font-size:     8pt;}'          +
523            'select.scwHead             {margin:        3px 1px;'       +
524                                        'text-align:    center;}'       +
525            'input.scwHead              {height:        22px;'          +
526                                        'width:         22px;'          +
527                                        'vertical-align:middle;'        +
528                                        'text-align:    center;'        +
529                                        'margin:        2px 1px;'       +
530                                        'font-weight:   bold;'          +
531                                        'font-size:     10pt;'          +
532                                        'font-family:   fixedSys;}'     +
533            'td.scwWeekNumberHead,'                                     +
534            'td.scwWeek                 {padding:       0px;'           +
535                                        'text-align:    center;'        +
536                                        'font-weight:   bold;}'         +
537            'td.scwNow,'                                                +
538            'td.scwNowHover,'                                           +
539            'td.scwNow:hover,'                                          +
540            'td.scwNowDisabled          {padding:       0px;'           +
541                                        'text-align:    center;'        +
542                                        'vertical-align:middle;'        +
543                                        'font-weight:   normal;}'       +
544            'table.scwCells             {text-align:    right;'         +
545                                        'font-size:     8pt;'           +
546                                        'width:         96%;}'          +
547            'td.scwCells,'                  +
548            'td.scwCellsHover,'             +
549            'td.scwCells:hover,'            +
550            'td.scwCellsDisabled,'          +
551            'td.scwCellsExMonth,'           +
552            'td.scwCellsExMonthHover,'      +
553            'td.scwCellsExMonth:hover,'     +
554            'td.scwCellsExMonthDisabled,'   +
555            'td.scwCellsWeekend,'           +
556            'td.scwCellsWeekendHover,'      +
557            'td.scwCellsWeekend:hover,'     +
558            'td.scwCellsWeekendDisabled,'   +
559            'td.scwInputDate,'              +
560            'td.scwInputDateHover,'         +
561            'td.scwInputDate:hover,'        +
562            'td.scwInputDateDisabled,'      +
563            'td.scwWeekNo,'                 +
564            'td.scwWeeks                {padding:           3px;'       +
565                                        'width:             16px;'      +
566                                        'height:            16px;'      +
567                                        'border-width:      1px;'       +
568                                        'border-style:      solid;'     +
569                                        'font-weight:       bold;'      +
570                                        'vertical-align:    middle;}'   +
571            '/* Blend the colours into your page here...    */'         +
572            '/* Calendar background */'                                 +
573            'table.scw                  {background-color:  #04155D;}'  +
574            '/* Drag Handle */'                                         +
575            'td.scwDrag                 {background-color:  #9999CC;'   +
576                                        'color:             #CCCCFF;}'  +
577            '/* Week number heading */'                                 +
578            'td.scwWeekNumberHead       {color:             #6666CC;}'  +
579            '/* Week day headings */'                                   +
580            'td.scwWeek                 {color:             #CCCCCC;}'  +
581            '/* Week numbers */'                                        +
582            'td.scwWeekNo               {background-color:  #776677;'   +
583                                        'color:             #CCCCCC;}'  +
584            '/* Enabled Days */'                                        +
585            '/* Week Day */'                                            +
586            'td.scwCells                {background-color:  #CCCCCC;'   +
587                                        'color:             #000000;}'  +
588            '/* Day matching the input date */'                         +
589            'td.scwInputDate            {background-color:  #CC9999;'   +
590                                        'color:             #A90303;}'  +
591            '/* Weekend Day */'                                         +
592            'td.scwCellsWeekend         {background-color:  #CCCCCC;'   +
593                                        'color:             #CC6666;}'  +
594            '/* Day outside the current month */'                       +
595            'td.scwCellsExMonth         {background-color:  #CCCCCC;'   +
596                                        'color:             #666666;}'  +
597            '/* Today selector */'                                      +
598            'td.scwNow                  {background-color:  #04155D;'   +
599                                        'color:             #FFFFFF;}'  +
600            '/* Clear Button */'                                        +
601            'td.scwClear                {padding:           0px;}'      +
602            'input.scwClear             {padding:           0px;'       +
603                                        'text-align:        center;'    +
604                                        'font-size:         8pt;}'      +
605            '/* MouseOver/Hover formatting '                            +
606            '       If you want to "turn off" any of the formatting '   +
607            '       then just set to the same as the standard format'   +
608            '       above.'                                             +
609            ' '                                                         +
610            '       Note: The reason that the following are'            +
611            '       implemented using both a class and a :hover'        +
612            '       pseudoclass is because Opera handles the rendering' +
613            '       involved in the class swap very poorly and IE6 '    +
614            '       (and below) only implements pseudoclasses on the'   +
615            '       anchor tag.'                                        +
616            '*/'                                                        +
617            '/* Active cells */'                                        +
618            'td.scwCells:hover,'                                        +
619            'td.scwCellsHover           {background-color:  #FFFF00;'   +
620                                        'cursor:            pointer;'   +
621                                        'color:             #000000;}'  +
622            '/* Day matching the input date */'                         +
623            'td.scwInputDate:hover,'                                    +
624            'td.scwInputDateHover       {background-color:  #FFFF00;'   +
625                                        'cursor:            pointer;'   +
626                                        'color:             #000000;}'  +
627            '/* Weekend cells */'                                       +
628            'td.scwCellsWeekend:hover,'                                 +
629            'td.scwCellsWeekendHover    {background-color:  #FFFF00;'   +
630                                        'cursor:            pointer;'   +
631                                        'color:             #000000;}'  +
632            '/* Day outside the current month */'                       +
633            'td.scwCellsExMonth:hover,'                                 +
634            'td.scwCellsExMonthHover    {background-color:  #FFFF00;'   +
635                                        'cursor:            pointer;'   +
636                                        'color:             #000000;}'  +
637            '/* Today selector */'                                      +
638            'td.scwNow:hover,'                                          +
639            'td.scwNowHover             {color:             #FFFF00;'   +
640                                        'cursor:            pointer;'   +
641                                        'font-weight:       bold;}'     +
642            '/* Disabled cells */'                                      +
643            '/* Week Day */'                                            +
644            '/* Day matching the input date */'                         +
645            'td.scwInputDateDisabled    {background-color:  #999999;'   +
646                                        'color:             #000000;}'  +
647            'td.scwCellsDisabled        {background-color:  #999999;'   +
648                                        'color:             #000000;}'  +
649            '/* Weekend Day */'                                         +
650            'td.scwCellsWeekendDisabled {background-color:  #999999;'   +
651                                        'color:             #CC6666;}'  +
652            '/* Day outside the current month */'                       +
653            'td.scwCellsExMonthDisabled {background-color:  #999999;'   +
654                                        'color:             #666666;}'  +
655            'td.scwNowDisabled          {background-color:  #6666CC;'   +
656                                        'color:             #FFFFFF;}'  +
657        '</style>'
658                    );
659
660//******************************************************************************
661//------------------------------------------------------------------------------
662// End of customisation section
663//------------------------------------------------------------------------------
664//******************************************************************************
665
666//  Variables required by both scwShow and scwShowMonth
667
668    var scwTargetEle,
669        scwTriggerEle,
670        scwMonthSum            = 0,
671        scwBlnFullInputDate    = false,
672        scwPassEnabledDay      = new Array(),
673        scwSeedDate            = new Date(),
674        scwParmActiveToday     = true,
675        scwWeekStart           = scwWeekStart%7,
676        scwToday,
677        scwClear,
678        scwDrag,
679        scwArrMonthNames,
680        scwArrWeekInits,
681        scwInvalidDateMsg,
682        scwOutOfRangeMsg,
683        scwDoesNotExistMsg,
684        scwInvalidAlert,
685        scwDateDisablingError,
686        scwRangeDisablingError;
687
688    // Add a method to format a date into the required pattern
689
690    Date.prototype.scwFormat =
691        function(scwFormat)
692            {var charCount = 0,
693                 codeChar  = '',
694                 result    = '';
695
696             for (var i=0;i<=scwFormat.length;i++)
697                {if (i<scwFormat.length && scwFormat.charAt(i)==codeChar)
698                        {// If we haven't hit the end of the string and
699                         // the format string character is the same as
700                         // the previous one, just clock up one to the
701                         // length of the current element definition
702                         charCount++;
703                        }
704                 else   {switch (codeChar)
705                            {case 'y': case 'Y':
706                                result += (this.getFullYear()%Math.
707                                            pow(10,charCount)).toString().
708                                            scwPadLeft(charCount);
709                                break;
710                             case 'm': case 'M':
711                                // If we find an M, check the number of them to
712                                // determine whether to get the month number or
713                                // the month name.
714                                result += (charCount<3)
715                                            ?(this.getMonth()+1).
716                                                toString().scwPadLeft(charCount)
717                                            :scwArrMonthNames[this.getMonth()];
718                                break;
719                             case 'd': case 'D':
720                                // If we find a D, get the date and format it
721                                result += this.getDate().toString().
722                                            scwPadLeft(charCount);
723                                break;
724                             default:
725                                // Copy any unrecognised characters across
726                                while (charCount-- > 0) {result += codeChar;}
727                            }
728
729                         if (i<scwFormat.length)
730                            {// Store the character we have just worked on
731                             codeChar  = scwFormat.charAt(i);
732                             charCount = 1;
733                            }
734                        }
735                }
736             return result;
737            };
738
739    // Add a method to left pad zeroes
740
741    String.prototype.scwPadLeft =
742        function(padToLength)
743            {var result = '';
744             for (var i=0;i<(padToLength - this.length);i++) {result += '0';}
745             return (result + this);
746            };
747
748    // Set up a closure so that any next function can be triggered
749    // after the calendar has been closed AND that function can take
750    // arguments.
751
752    Function.prototype.runsAfterSCW =
753        function()  {var func = this,
754                         args = new Array(arguments.length);
755
756                     for (var i=0;i<args.length;++i) {args[i] = arguments[i];}
757
758                     return function()
759                        {// concat/join the two argument arrays
760                         for (var i=0;i<arguments.length;++i) {args[args.length] = arguments[i];}
761                         return (args.shift()==scwTriggerEle)?func.apply(this, args):null;
762                        };
763                    };
764
765    // Set up some shortcuts
766
767    function scwID(id)
768        {if (document.getElementById(id) || (!document.getElementById(id) && document.getElementsByName(id).length==0))
769                                    // IF   An ID attribute is assigned
770                                    // OR   No ID attribute is assigned but using IE and Opera
771                                    //          (which will find the NAME attribute value using getElementById)
772                                    // OR   No element has this ID or NAME attribute value
773                                    //          (used internally by the script)
774                                    // THEN Return the required element.
775                {return document.getElementById(id);}
776         else   {if (document.getElementsByName(id).length==1)
777                                // IF   No ID attribute is assigned
778                                // AND  Using a standards-based browser
779                                // AND  Only one element has the NAME attribute set to the value
780                                // THEN Return the required element (using the NAME attribute value).
781                        {return document.getElementsByName(id)[0];}
782                 else   {if (document.getElementsByName(id).length>1)
783                            {   // IF   No ID attribute is assigned
784                                // AND  using a standards-based browser
785                                // AND  more than one element has the NAME attribute set to the value
786                                // THEN alert developer to fix the fault.
787                             alert( 'SCW' +
788                                    ' \nCannot uniquely identify element named: ' + id +
789                                    '.\nMore than one identical NAME attribute defined' +
790                                    '.\nSolution: Assign the required element a unique ID attribute value.');
791                            }
792                        }
793                }
794        };
795
796    // Use a global variable for the return value from the next action
797    // IE fails to pass the function through if the target element is in
798    // a form and scwNextAction is not defined.
799
800    var scwNextActionReturn, scwNextAction;
801
802// ****************************************************************************
803// Start of Function Library
804//
805//  Exposed functions:
806//
807//      scwShow             Entry point for display of calendar,
808//                              called in main page.
809//      showCal             Legacy name of scwShow:
810//                              Passes only legacy arguments,
811//                              not the optional day disabling arguments.
812//
813//      scwShowMonth        Displays a month on the calendar,
814//                              Called when a month is set or changed.
815//
816//      scwBeginDrag        Controls calendar dragging.
817//
818//      scwCancel           Called when the calendar background is clicked:
819//                              Calls scwStopPropagation and may call scwHide.
820//      scwHide             Hides the calendar, called on various events.
821//      scwStopPropagation  Stops the propagation of an event.
822//
823// ****************************************************************************
824
825    function showCal(scwEle,scwSource) {scwShow(scwEle,scwSource);};
826    function scwShowHide(scwEle,scwSource) {
827        if (scwID('scw').style.visibility == '' || scwID('scw').style.visibility == 'hidden') {
828                scwShow(scwEle,scwSource);
829        } else {
830                scwHide();
831        }
832    }
833    function scwShow(scwEle,scwSource)
834        {if (!scwSource) {scwSource = window.event;}
835
836         if (scwSource.tagName) // Second parameter isn't an event it's an element
837            {var scwSourceEle = scwSource;
838
839             if (scwID('scwIE'))  {window.event.cancelBubble = true;}
840             else {scwSourceEle.parentNode.addEventListener('click',scwStopPropagation,false);}
841            }
842         else   // Second parameter is an event
843            {var scwSourceEle = (scwSource.target)
844                                    ?scwSource.target
845                                    :scwSource.srcElement;
846
847             // Stop the click event that opens the calendar from bubbling up to
848             // the document-level event handler that hides it!
849             if (scwSource.stopPropagation) {scwSource.stopPropagation();}
850             else                           {scwSource.cancelBubble = true;}
851            }
852
853         scwTriggerEle = scwSourceEle;
854
855         // Take any parameters that there might be from the third onwards as
856         // day numbers to be disabled 0 = Sunday through to 6 = Saturday.
857
858         scwParmActiveToday = true;
859
860         for (var i=0;i<7;i++)
861            {scwPassEnabledDay[(i+7-scwWeekStart)%7] = true;
862             for (var j=2;j<arguments.length;j++)
863                {if (arguments[j]==i)
864                    {scwPassEnabledDay[(i+7-scwWeekStart)%7] = false;
865                     if (scwDateNow.getDay()==i) {scwParmActiveToday = false;}
866                    }
867                }
868            }
869
870         //   If no value is preset then the seed date is
871         //      Today (when today is in range) OR
872         //      The middle of the date range.
873
874         scwSeedDate = scwDateNow;
875
876         // Find the date and Strip space characters from start and
877         // end of date input.
878
879         var scwDateValue = '';
880
881         if (scwEle.value) {scwDateValue = scwEle.value.replace(/^\s+/,'').replace(/\s+$/,'');}
882         else   {if (typeof scwEle.value == 'undefined')
883                    {var scwChildNodes = scwEle.childNodes;
884                     for (var i=0;i<scwChildNodes.length;i++)
885                        {if (scwChildNodes[i].nodeType == 3)
886                            {scwDateValue = scwChildNodes[i].nodeValue.replace(/^\s+/,'').replace(/\s+$/,'');
887                             if (scwDateValue.length > 0)
888                                {scwTriggerEle.scwTextNode = scwChildNodes[i];
889                                 scwTriggerEle.scwLength   = scwChildNodes[i].nodeValue.length;
890                                 break;
891                                }
892                            }
893                        }
894                    }
895                }
896
897         // Set the language-dependent elements
898
899         scwSetDefaultLanguage();
900
901         scwID('scwDragText').innerHTML = scwDrag;
902
903         scwID('scwMonths').options.length = 0;
904         for (var i=0;i<scwArrMonthNames.length;i++)
905            {scwID('scwMonths').options[i] = new Option(scwArrMonthNames[i],scwArrMonthNames[i]);}
906
907         scwID('scwYears').options.length = 0;
908         for (var i=0;i<scwDropDownYears;i++)
909            {scwID('scwYears').options[i] =  new Option((scwBaseYear+i),(scwBaseYear+i));}
910
911         for (var i=0;i<scwArrWeekInits.length;i++)
912            {scwID('scwWeekInit' + i).innerHTML = scwArrWeekInits[(i+scwWeekStart)%scwArrWeekInits.length];}
913
914         if (((new Date(scwBaseYear + scwDropDownYears, 0, 0)) > scwDateNow &&
915              (new Date(scwBaseYear, 0, 0))                    < scwDateNow) ||
916             (scwClearButton && (scwEle.readOnly || scwEle.disabled))
917            )   {scwID('scwFoot').style.display = '';
918                 scwID('scwNow').innerHTML = scwToday + ' ' + scwDateNow.scwFormat(scwDateDisplayFormat);
919                 scwID('scwClearButton').value = scwClear;
920                 if ((new Date(scwBaseYear + scwDropDownYears, 0, 0)) > scwDateNow &&
921                     (new Date(scwBaseYear, 0, 0))                    < scwDateNow
922                    )   {scwID('scwNow').style.display = '';
923                         if (scwClearButton && (scwEle.readOnly || scwEle.disabled))
924                                {scwID('scwClear').style.display   = '';
925                                 scwID('scwClear').style.textAlign = 'left';
926                                 scwID('scwNow').style.textAlign   = 'right';
927                                }
928                         else   {scwID('scwClear').style.display = 'none';
929                                 scwID('scwNow').style.textAlign = 'center';
930                                }
931                        }
932                 else   {scwID('scwClear').style.textAlign = 'center';
933                         scwID('scwClear').style.display = '';
934                         scwID('scwNow').style.display = 'none';
935                        }
936                }
937         else   {scwID('scwFoot').style.display = 'none';}
938
939         if (scwDateValue.length==0)
940            {// If no value is entered and today is within the range,
941             // use today's date, otherwise use the middle of the valid range.
942
943             scwBlnFullInputDate=false;
944
945             if ((new Date(scwBaseYear+scwDropDownYears,0,0))<scwSeedDate ||
946                 (new Date(scwBaseYear,0,1))                 >scwSeedDate
947                )
948                {scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears / 2), 5, 1);}
949            }
950         else
951            {function scwInputFormat()
952                {var scwArrSeed = new Array(),
953                     scwArrInput = scwDateValue.split(new RegExp('[\\'+scwArrDelimiters.join('\\')+']+','g'));
954
955                 // "Escape" all the user defined date delimiters above -
956                 // several delimiters will need it and it does no harm for
957                 // the others.
958
959                 // Strip any empty array elements (caused by delimiters)
960                 // from the beginning or end of the array. They will
961                 // still appear in the output string if in the output
962                 // format.
963
964                 if (scwArrInput[0]!=null)
965                    {if (scwArrInput[0].length==0)                      {scwArrInput.splice(0,1);}
966                     if (scwArrInput[scwArrInput.length-1].length==0)   {scwArrInput.splice(scwArrInput.length-1,1);}
967                    }
968
969                 scwBlnFullInputDate = false;
970
971                 scwDateOutputFormat = scwDateOutputFormat.toUpperCase();
972
973                 // List all the allowed letters in the date format
974                 var template = ['D','M','Y'];
975
976                 // Prepare the sequence of date input elements
977                 var result = new Array();
978
979                 for (var i=0;i<template.length;i++)
980                    {if (scwDateOutputFormat.search(template[i])>-1)
981                        {result[scwDateOutputFormat.search(template[i])] = template[i];}
982                    }
983
984                 var scwDateSequence = result.join('');
985
986                 // Separate the elements of the date input
987                 switch (scwArrInput.length)
988                    {case 1:
989                        {if (scwDateOutputFormat.indexOf('Y')>-1 &&
990                             scwArrInput[0].length>scwDateOutputFormat.lastIndexOf('Y'))
991                            {scwArrSeed[0] = parseInt(scwArrInput[0].substring(scwDateOutputFormat.indexOf('Y'),
992                                                                               scwDateOutputFormat.lastIndexOf('Y')+1),10);
993                            }
994                         else   {scwArrSeed[0] = 0;}
995
996                         if (scwDateOutputFormat.indexOf('M')>-1 &&
997                             scwArrInput[0].length>scwDateOutputFormat.lastIndexOf('M'))
998                            {scwArrSeed[1] = scwArrInput[0].substring(scwDateOutputFormat.indexOf('M'),
999                                                                      scwDateOutputFormat.lastIndexOf('M')+1);
1000                            }
1001                         else   {scwArrSeed[1] = '6';}
1002
1003                         if (scwDateOutputFormat.indexOf('D')>-1 &&
1004                             scwArrInput[0].length>scwDateOutputFormat.lastIndexOf('D'))
1005                            {scwArrSeed[2] = parseInt(scwArrInput[0].substring(scwDateOutputFormat.indexOf('D'),
1006                                                                               scwDateOutputFormat.lastIndexOf('D')+1),10);
1007                            }
1008                         else   {scwArrSeed[2] = 1;}
1009
1010                         if (scwArrInput[0].length==scwDateOutputFormat.length) {scwBlnFullInputDate = true;}
1011                         break;
1012                        }
1013                     case 2:
1014                        {// Year and Month entry
1015                         scwArrSeed[0] =
1016                             parseInt(scwArrInput[scwDateSequence.
1017                                                    replace(/D/i,'').
1018                                                    search(/Y/i)],10);  // Year
1019                         scwArrSeed[1] = scwArrInput[scwDateSequence.
1020                                                    replace(/D/i,'').
1021                                                    search(/M/i)];      // Month
1022                         scwArrSeed[2] = 1;                             // Day
1023                         break;
1024                        }
1025                     case 3:
1026                        {// Day Month and Year entry
1027
1028                         scwArrSeed[0] =
1029                             parseInt(scwArrInput[scwDateSequence.
1030                                                    search(/Y/i)],10);  // Year
1031                         scwArrSeed[1] = scwArrInput[scwDateSequence.
1032                                                    search(/M/i)];      // Month
1033                         scwArrSeed[2] =
1034                             parseInt(scwArrInput[scwDateSequence.
1035                                                    search(/D/i)],10);  // Day
1036
1037                         scwBlnFullInputDate = true;
1038                         break;
1039                        }
1040                     default:
1041                        {// A stuff-up has led to more than three elements in
1042                         // the date.
1043                         scwArrSeed[0] = 0;     // Year
1044                         scwArrSeed[1] = 0;     // Month
1045                         scwArrSeed[2] = 0;     // Day
1046                        }
1047                    }
1048
1049                 // These regular expressions validate the input date format
1050                 // to the following rules;
1051                 //         Day   1-31 (optional zero on single digits)
1052                 //         Month 1-12 (optional zero on single digits)
1053                 //                     or case insensitive name
1054                 //         Year  One, Two or four digits
1055
1056                 // Months names are as set in the language-dependent
1057                 // definitions and delimiters are set just below there
1058
1059                 var scwExpValDay    = new RegExp('^(0?[1-9]|[1-2][0-9]|3[0-1])$'),
1060                     scwExpValMonth  = new RegExp('^(0?[1-9]|1[0-2]|'        +
1061                                                  scwArrMonthNames.join('|') +
1062                                                  ')$','i'),
1063                     scwExpValYear   = new RegExp('^([0-9]{1,2}|[0-9]{4})$');
1064
1065                 // Apply validation and report failures
1066
1067                 if (scwExpValYear.exec(scwArrSeed[0])  == null ||
1068                     scwExpValMonth.exec(scwArrSeed[1]) == null ||
1069                     scwExpValDay.exec(scwArrSeed[2])   == null
1070                    )
1071                    {if (scwShowInvalidDateMsg)
1072                        {alert(scwInvalidDateMsg  +
1073                               scwInvalidAlert[0] + scwDateValue +
1074                               scwInvalidAlert[1]);}
1075                     scwBlnFullInputDate = false;
1076                     scwArrSeed[0] = scwBaseYear +
1077                                     Math.floor(scwDropDownYears/2); // Year
1078                     scwArrSeed[1] = '6';                            // Month
1079                     scwArrSeed[2] = 1;                              // Day
1080                    }
1081
1082                 // Return the  Year    in scwArrSeed[0]
1083                 //             Month   in scwArrSeed[1]
1084                 //             Day     in scwArrSeed[2]
1085
1086                 return scwArrSeed;
1087                };
1088
1089             // Parse the string into an array using the allowed delimiters
1090
1091             scwArrSeedDate = scwInputFormat();
1092
1093             // So now we have the Year, Month and Day in an array.
1094
1095             //   If the year is one or two digits then the routine assumes a
1096             //   year belongs in the 21st Century unless it is less than 50
1097             //   in which case it assumes the 20th Century is intended.
1098
1099             if (scwArrSeedDate[0]<100) {scwArrSeedDate[0] += (scwArrSeedDate[0]>50)?1900:2000;}
1100
1101             // Check whether the month is in digits or an abbreviation
1102
1103             if (scwArrSeedDate[1].search(/\d+/)<0)
1104                {for (i=0;i<scwArrMonthNames.length;i++)
1105                    {if (scwArrSeedDate[1].toUpperCase()==scwArrMonthNames[i].toUpperCase())
1106                        {scwArrSeedDate[1]=i+1;
1107                         break;
1108                        }
1109                    }
1110                }
1111
1112             scwSeedDate = new Date(scwArrSeedDate[0],scwArrSeedDate[1]-1,scwArrSeedDate[2]);
1113            }
1114
1115         // Test that we have arrived at a valid date
1116
1117         if (isNaN(scwSeedDate))
1118            {if (scwShowInvalidDateMsg) {alert(scwInvalidDateMsg + scwInvalidAlert[0] + scwDateValue + scwInvalidAlert[1]);}
1119             scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears/2),5,1);
1120             scwBlnFullInputDate=false;
1121            }
1122         else
1123            {// Test that the date is within range,
1124             // if not then set date to a sensible date in range.
1125
1126             if ((new Date(scwBaseYear,0,1)) > scwSeedDate)
1127                {if (scwBlnStrict && scwShowOutOfRangeMsg) {alert(scwOutOfRangeMsg);}
1128                 scwSeedDate = new Date(scwBaseYear,0,1);
1129                 scwBlnFullInputDate=false;
1130                }
1131             else
1132                {if ((new Date(scwBaseYear+scwDropDownYears,0,0))<scwSeedDate)
1133                    {if (scwBlnStrict && scwShowOutOfRangeMsg) {alert(scwOutOfRangeMsg);}
1134                     scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears)-1,11,1);
1135                     scwBlnFullInputDate=false;
1136                    }
1137                 else
1138                    {if (scwBlnStrict && scwBlnFullInputDate &&
1139                          (scwSeedDate.getDate()      != scwArrSeedDate[2] ||
1140                           (scwSeedDate.getMonth()+1) != scwArrSeedDate[1] ||
1141                           scwSeedDate.getFullYear()  != scwArrSeedDate[0]
1142                          )
1143                        )
1144                        {if (scwShowDoesNotExistMsg) alert(scwDoesNotExistMsg);
1145                         scwSeedDate = new Date(scwSeedDate.getFullYear(),scwSeedDate.getMonth()-1,1);
1146                         scwBlnFullInputDate=false;
1147                        }
1148                    }
1149                }
1150            }
1151
1152         // Test the disabled dates for validity
1153         // Give error message if not valid.
1154
1155         for (var i=0;i<scwDisabledDates.length;i++)
1156            {if (!((typeof scwDisabledDates[i] == 'object') && (scwDisabledDates[i].constructor == Date)))
1157                {if ((typeof scwDisabledDates[i] == 'object') && (scwDisabledDates[i].constructor == Array))
1158                    {var scwPass = true;
1159
1160                     if (scwDisabledDates[i].length !=2)
1161                        {if (scwShowRangeDisablingError)
1162                            {alert(scwRangeDisablingError[0] + scwDisabledDates[i] + scwRangeDisablingError[1]);}
1163                         scwPass = false;
1164                        }
1165                     else
1166                        {for (var j=0;j<scwDisabledDates[i].length;j++)
1167                            {if (!((typeof scwDisabledDates[i][j] == 'object') && (scwDisabledDates[i][j].constructor == Date)))
1168                                {if (scwShowRangeDisablingError)
1169                                    {alert(  scwDateDisablingError[0] + scwDisabledDates[i][j] + scwDateDisablingError[1]);}
1170                                 scwPass = false;
1171                                }
1172                            }
1173                        }
1174
1175                     if (scwPass && (scwDisabledDates[i][0] > scwDisabledDates[i][1])) {scwDisabledDates[i].reverse();}
1176                    }
1177                 else
1178                    {if (scwShowRangeDisablingError) {alert(scwDateDisablingError[0] + scwDisabledDates[i] + scwDateDisablingError[1]);}}
1179                }
1180            }
1181
1182         // Calculate the number of months that the entered (or
1183         // defaulted) month is after the start of the allowed
1184         // date range.
1185
1186         scwMonthSum =  12*(scwSeedDate.getFullYear()-scwBaseYear)+scwSeedDate.getMonth();
1187
1188         scwID('scwYears' ).options.selectedIndex = Math.floor(scwMonthSum/12);
1189         scwID('scwMonths').options.selectedIndex = (scwMonthSum%12);
1190
1191         // Check whether or not dragging is allowed and display drag handle if necessary
1192
1193         scwID('scwDrag').style.display=(scwAllowDrag)?'':'none';
1194
1195         // Display the month
1196
1197         scwShowMonth(0);
1198
1199         // Position the calendar box
1200
1201         // The object sniffing for Opera allows for the fact that Opera
1202         // is the only major browser that correctly reports the position
1203         // of an element in a scrollable DIV.  This is because IE and
1204         // Firefox omit the DIV from the offsetParent tree.
1205
1206         scwTargetEle=scwEle;
1207
1208         var offsetTop =parseInt(scwEle.offsetTop ,10) + parseInt(scwEle.offsetHeight,10),
1209             offsetLeft=parseInt(scwEle.offsetLeft,10);
1210       
1211         if (!window.opera)
1212             {while (scwEle.tagName!='BODY' && scwEle.tagName!='HTML')
1213                 {offsetTop -=parseInt(scwEle.scrollTop, 10);
1214                  offsetLeft-=parseInt(scwEle.scrollLeft,10);
1215                  scwEle=scwEle.parentNode;
1216                 }
1217              scwEle=scwTargetEle;
1218             }
1219
1220         do {scwEle=scwEle.offsetParent;
1221             offsetTop +=parseInt(scwEle.offsetTop, 10);
1222             offsetLeft+=parseInt(scwEle.offsetLeft,10);
1223            }
1224         while (scwEle.tagName!='BODY' && scwEle.tagName!='HTML');
1225
1226         if (scwAutoPosition)
1227             {var scwWidth      = parseInt(scwID('scw').offsetWidth, 10),
1228                  scwHeight     = parseInt(scwID('scw').offsetHeight,10),
1229                  scwWindowLeft =
1230                     (document.body && document.body.scrollLeft)
1231                          ?document.body.scrollLeft                  //DOM compliant
1232                          :(document.documentElement && document.documentElement.scrollLeft)
1233                              ?document.documentElement.scrollLeft   //IE6+ standards compliant
1234                              :0,                                    //Failed
1235                  scwWindowWidth =
1236                      (typeof(innerWidth) == 'number')
1237                          ?innerWidth                                //DOM compliant
1238                          :(document.documentElement && document.documentElement.clientWidth)
1239                              ?document.documentElement.clientWidth  //IE6+ standards compliant
1240                              :(document.body && document.body.clientWidth)
1241                                  ?document.body.clientWidth         //IE non-compliant
1242                                  :0,                                //Failed
1243                  scwWindowTop =
1244                      (document.body && document.body.scrollTop)
1245                          ?document.body.scrollTop                   //DOM compliant
1246                          :(document.documentElement && document.documentElement.scrollTop)
1247                              ?document.documentElement.scrollTop    //IE6+ standards compliant
1248                              :0,                                    //Failed
1249                  scwWindowHeight =
1250                      (typeof(innerHeight) == 'number')
1251                          ?innerHeight                               //DOM compliant
1252                          :(document.documentElement && document.documentElement.clientHeight)
1253                              ?document.documentElement.clientHeight //IE6+ standards compliant
1254                              :(document.body && document.body.clientHeight)
1255                                  ?document.body.clientHeight        //IE non-compliant
1256                                  :0;                                //Failed
1257
1258              offsetLeft -= (offsetLeft - scwWidth + parseInt(scwTargetEle.offsetWidth,10) >= scwWindowLeft &&
1259                             offsetLeft + scwWidth > scwWindowLeft + scwWindowWidth
1260                            )?(scwWidth - parseInt(scwTargetEle.offsetWidth,10)):0;
1261
1262              offsetTop -= (offsetTop - scwHeight - parseInt(scwTargetEle.offsetHeight,10) >= scwWindowTop &&
1263                            offsetTop + scwHeight > scwWindowTop + scwWindowHeight
1264                           )?(scwHeight + parseInt(scwTargetEle.offsetHeight,10)):0;
1265             }
1266
1267         scwID('scw').style.top         = offsetTop+'px';
1268         scwID('scw').style.left        = offsetLeft+'px';
1269         scwID('scwIframe').style.top   = offsetTop+'px';
1270         scwID('scwIframe').style.left  = offsetLeft+'px';
1271
1272         scwID('scwIframe').style.width =(scwID('scw').offsetWidth-(scwID('scwIE')?2:4))+'px';
1273         scwID('scwIframe').style.height=(scwID('scw').offsetHeight-(scwID('scwIE')?2:4))+'px';
1274         scwID('scwIframe').style.visibility='inherit';
1275
1276         // Show it on the page
1277         scwID('scw').style.visibility='inherit';
1278        };
1279
1280    function scwHide()
1281        {scwID('scw').style.visibility='hidden';
1282         scwID('scwIframe').style.visibility='hidden';
1283         if (typeof scwNextAction!='undefined' && scwNextAction!=null)
1284             {scwNextActionReturn = scwNextAction();
1285              // Explicit null set to prevent closure causing memory leak
1286              scwNextAction = null;
1287             }
1288        };
1289
1290    function scwCancel(scwEvt)
1291        {if (scwClickToHide) {scwHide();}
1292         scwStopPropagation(scwEvt);
1293        };
1294
1295    function scwStopPropagation(scwEvt)
1296        {if (scwEvt.stopPropagation)
1297                {scwEvt.stopPropagation();}     // Capture phase
1298         else   {scwEvt.cancelBubble = true;}   // Bubbling phase
1299        };
1300
1301    function scwBeginDrag(event)
1302        {var elementToDrag = scwID('scw');
1303
1304         var deltaX    = event.clientX,
1305             deltaY    = event.clientY,
1306             offsetEle = elementToDrag;
1307
1308         do {deltaX   -= parseInt(offsetEle.offsetLeft,10);
1309             deltaY   -= parseInt(offsetEle.offsetTop ,10);
1310             offsetEle = offsetEle.offsetParent;
1311            }
1312         while (offsetEle.tagName!='BODY' &&
1313                offsetEle.tagName!='HTML');
1314
1315         if (document.addEventListener)
1316                {document.addEventListener('mousemove',moveHandler,true);        // Capture phase
1317                 document.addEventListener('mouseup',  upHandler,  true);        // Capture phase
1318                }
1319         else   {elementToDrag.attachEvent('onmousemove',moveHandler); // Bubbling phase
1320                 elementToDrag.attachEvent('onmouseup',  upHandler);   // Bubbling phase
1321                 elementToDrag.setCapture();
1322                }
1323
1324         scwStopPropagation(event);
1325
1326         function moveHandler(scwEvt)
1327            {if (!scwEvt) scwEvt = window.event;
1328
1329             elementToDrag.style.left = (scwEvt.clientX - deltaX) + 'px';
1330             elementToDrag.style.top  = (scwEvt.clientY - deltaY) + 'px';
1331
1332             scwID('scwIframe').style.left = (scwEvt.clientX - deltaX) + 'px';
1333             scwID('scwIframe').style.top  = (scwEvt.clientY - deltaY) + 'px';
1334
1335             scwStopPropagation(scwEvt);
1336            };
1337
1338         function upHandler(scwEvt)
1339            {if (!scwEvt) scwEvt = window.event;
1340
1341             if (document.removeEventListener)
1342                    {document.removeEventListener('mousemove',moveHandler,true);     // Capture phase
1343                     document.removeEventListener('mouseup',  upHandler,  true);     // Capture phase
1344                    }
1345             else   {elementToDrag.detachEvent('onmouseup',  upHandler);   // Bubbling phase
1346                     elementToDrag.detachEvent('onmousemove',moveHandler); // Bubbling phase
1347                     elementToDrag.releaseCapture();
1348                    }
1349
1350             scwStopPropagation(scwEvt);
1351            };
1352        };
1353
1354    function scwShowMonth(scwBias)
1355        {// Set the selectable Month and Year
1356         // May be called: from the left and right arrows
1357         //                  (shift month -1 and +1 respectively)
1358         //                from the month selection list
1359         //                from the year selection list
1360         //                from the showCal routine
1361         //                  (which initiates the display).
1362
1363         var scwShowDate  = new Date(Date.parse(new Date().toDateString())),
1364             scwStartDate = new Date();
1365
1366         // Set the time to the middle of the day so that the handful of
1367         // regions that have daylight saving shifts that change the day
1368         // of the month (i.e. turn the clock back at midnight or forward
1369         // at 23:00) do not mess up the date display in the calendar.
1370
1371         scwShowDate.setHours(12);
1372
1373         scwSelYears  = scwID('scwYears');
1374         scwSelMonths = scwID('scwMonths');
1375
1376         if (scwSelYears.options.selectedIndex>-1)
1377            {scwMonthSum=12*(scwSelYears.options.selectedIndex)+scwBias;
1378             if (scwSelMonths.options.selectedIndex>-1) {scwMonthSum+=scwSelMonths.options.selectedIndex;}
1379            }
1380         else
1381            {if (scwSelMonths.options.selectedIndex>-1) {scwMonthSum+=scwSelMonths.options.selectedIndex;}}
1382
1383         scwShowDate.setFullYear(scwBaseYear + Math.floor(scwMonthSum/12),(scwMonthSum%12),1);
1384
1385         // If the Week numbers are displayed, shift the week day names to the right.
1386         scwID('scwWeek_').style.display=(scwWeekNumberDisplay)?'':'none';
1387
1388         // Opera has a bug with setting the selected index.
1389         // It requires the following work-around to force SELECTs to display correctly.
1390         if (window.opera)
1391            {scwID('scwMonths').style.display = 'inherit';
1392             scwID('scwYears' ).style.display = 'inherit';
1393           }
1394
1395         // Set the drop down boxes.
1396         scwTemp = (12*parseInt((scwShowDate.getFullYear()-scwBaseYear),10)) + parseInt(scwShowDate.getMonth(),10);
1397
1398         if (scwTemp > -1 && scwTemp < (12*scwDropDownYears))
1399            {scwSelYears.options.selectedIndex=Math.floor(scwMonthSum/12);
1400             scwSelMonths.options.selectedIndex=(scwMonthSum%12);
1401
1402             scwCurMonth = scwShowDate.getMonth();
1403
1404             scwShowDate.setDate((((scwShowDate.
1405                                    getDay()-scwWeekStart)<0)?-6:1)+
1406                                 scwWeekStart-scwShowDate.getDay());
1407
1408             // This statement moved by Michael Cerveny to make version 3.55
1409             var scwCompareDateValue = new Date(scwShowDate.getFullYear(),
1410                                                scwShowDate.getMonth(),
1411                                                scwShowDate.getDate()).valueOf();
1412
1413             scwStartDate = new Date(scwShowDate);
1414
1415             if ((new Date(scwBaseYear + scwDropDownYears, 0, 0)) > scwDateNow &&
1416                 (new Date(scwBaseYear, 0, 0))                    < scwDateNow)
1417                {var scwNow = scwID('scwNow');
1418
1419                 function scwNowOutput() {scwSetOutput(scwDateNow);};
1420
1421                 if (scwDisabledDates.length==0)
1422                    {if (scwActiveToday && scwParmActiveToday)
1423                        {scwNow.onclick     = scwNowOutput;
1424                         scwNow.className   = 'scwNow';
1425
1426                         if (scwID('scwIE'))
1427                            {scwNow.onmouseover  = scwChangeClass;
1428                             scwNow.onmouseout   = scwChangeClass;
1429                            }
1430
1431                        }
1432                     else
1433                        {scwNow.onclick     = null;
1434                         scwNow.className   = 'scwNowDisabled';
1435
1436                         if (scwID('scwIE'))
1437                            {scwNow.onmouseover  = null;
1438                             scwNow.onmouseout   = null;
1439                            }
1440
1441                         if (document.addEventListener)
1442                                {scwNow.addEventListener('click',scwStopPropagation,false);}
1443                         else   {scwNow.attachEvent('onclick',scwStopPropagation);}
1444                        }
1445                    }
1446                 else
1447                    {for (var k=0;k<scwDisabledDates.length;k++)
1448                        {if (!scwActiveToday || !scwParmActiveToday ||
1449                             ((typeof scwDisabledDates[k] == 'object')                   &&
1450                                 (((scwDisabledDates[k].constructor == Date)             &&
1451                                   scwDateNow.valueOf() == scwDisabledDates[k].valueOf()
1452                                  ) ||
1453                                  ((scwDisabledDates[k].constructor == Array)               &&
1454                                   scwDateNow.valueOf() >= scwDisabledDates[k][0].valueOf() &&
1455                                   scwDateNow.valueOf() <= scwDisabledDates[k][1].valueOf()
1456                                  )
1457                                 )
1458                             )
1459                            )
1460                            {scwNow.onclick     = null;
1461                             scwNow.className   = 'scwNowDisabled';
1462
1463                             if (scwID('scwIE'))
1464                                {scwNow.onmouseover  = null;
1465                                 scwNow.onmouseout   = null;
1466                                }
1467
1468                             if (document.addEventListener)
1469                                    {scwNow.addEventListener('click',scwStopPropagation,false);}
1470                             else   {scwNow.attachEvent('onclick',scwStopPropagation);}
1471                             break;
1472                            }
1473                         else
1474                            {scwNow.onclick=scwNowOutput;
1475                             scwNow.className='scwNow';
1476
1477                             if (scwID('scwIE'))
1478                                {scwNow.onmouseover  = scwChangeClass;
1479                                 scwNow.onmouseout   = scwChangeClass;
1480                                }
1481                            }
1482                        }
1483                    }
1484                }
1485
1486             function scwSetOutput(scwOutputDate)
1487                {if (typeof scwTargetEle.value == 'undefined')
1488                      {scwTriggerEle.scwTextNode.replaceData(0,scwTriggerEle.scwLength,scwOutputDate.scwFormat(scwDateOutputFormat));}
1489                 else {scwTargetEle.value = scwOutputDate.scwFormat(scwDateOutputFormat);}
1490                 scwHide();
1491                };
1492
1493             function scwCellOutput(scwEvt)
1494                {var scwEle = scwEventTrigger(scwEvt),
1495                     scwOutputDate = new Date(scwStartDate);
1496
1497                 if (scwEle.nodeType==3) scwEle=scwEle.parentNode;
1498
1499                 scwOutputDate.setDate(scwStartDate.getDate() + parseInt(scwEle.id.substr(8),10));
1500
1501                 scwSetOutput(scwOutputDate);
1502                };
1503
1504             function scwChangeClass(scwEvt)
1505                {var scwEle = scwEventTrigger(scwEvt);
1506
1507                 if (scwEle.nodeType==3) {scwEle=scwEle.parentNode;}
1508
1509                 switch (scwEle.className)
1510                    {case 'scwCells':
1511                        scwEle.className = 'scwCellsHover';
1512                        break;
1513                     case 'scwCellsHover':
1514                        scwEle.className = 'scwCells';
1515                        break;
1516                     case 'scwCellsExMonth':
1517                        scwEle.className = 'scwCellsExMonthHover';
1518                        break;
1519                     case 'scwCellsExMonthHover':
1520                        scwEle.className = 'scwCellsExMonth';
1521                        break;
1522                     case 'scwCellsWeekend':
1523                        scwEle.className = 'scwCellsWeekendHover';
1524                        break;
1525                     case 'scwCellsWeekendHover':
1526                        scwEle.className = 'scwCellsWeekend';
1527                        break;
1528                     case 'scwNow':
1529                        scwEle.className = 'scwNowHover';
1530                        break;
1531                     case 'scwNowHover':
1532                        scwEle.className = 'scwNow';
1533                        break;
1534                     case 'scwInputDate':
1535                        scwEle.className = 'scwInputDateHover';
1536                        break;
1537                     case 'scwInputDateHover':
1538                        scwEle.className = 'scwInputDate';
1539                    }
1540
1541                 return true;
1542                }
1543
1544             function scwEventTrigger(scwEvt)
1545                {if (!scwEvt) {scwEvt = event;}
1546                 return scwEvt.target||scwEvt.srcElement;
1547                };
1548
1549             function scwWeekNumber(scwInDate)
1550                {// The base day in the week of the input date
1551                 var scwInDateWeekBase = new Date(scwInDate);
1552
1553                 scwInDateWeekBase.setDate(scwInDateWeekBase.getDate()
1554                                            - scwInDateWeekBase.getDay()
1555                                            + scwWeekNumberBaseDay
1556                                            + ((scwInDate.getDay()>
1557                                                scwWeekNumberBaseDay)?7:0));
1558
1559                 // The first Base Day in the year
1560                 var scwFirstBaseDay = new Date(scwInDateWeekBase.getFullYear(),0,1);
1561
1562                 scwFirstBaseDay.setDate(scwFirstBaseDay.getDate()
1563                                            - scwFirstBaseDay.getDay()
1564                                            + scwWeekNumberBaseDay
1565                                        );
1566
1567                 if (scwFirstBaseDay < new Date(scwInDateWeekBase.getFullYear(),0,1))
1568                    {scwFirstBaseDay.setDate(scwFirstBaseDay.getDate()+7);}
1569
1570                 // Start of Week 01
1571                 var scwStartWeekOne = new Date(scwFirstBaseDay
1572                                                - scwWeekNumberBaseDay
1573                                                + scwInDate.getDay());
1574
1575                 if (scwStartWeekOne > scwFirstBaseDay)
1576                    {scwStartWeekOne.setDate(scwStartWeekOne.getDate()-7);}
1577
1578                 // Subtract the date of the current week from the date of the
1579                 // first week of the year to get the number of weeks in
1580                 // milliseconds.  Divide by the number of milliseconds
1581                 // in a week then round to no decimals in order to remove
1582                 // the effect of daylight saving.  Add one to make the first
1583                 // week, week 1.  Place a string zero on the front so that
1584                 // week numbers are zero filled.
1585
1586                 var scwWeekNo = '0' + (Math.round((scwInDateWeekBase - scwFirstBaseDay)/604800000,0) + 1);
1587
1588                 // Return the last two characters in the week number string
1589
1590                 return scwWeekNo.substring(scwWeekNo.length-2, scwWeekNo.length);
1591                };
1592
1593             // Treewalk to display the dates.
1594             // I tried to use getElementsByName but IE refused to cooperate
1595             // so I resorted to this method which works for all tested
1596             // browsers.
1597
1598             var scwCells = scwID('scwCells');
1599
1600             for (i=0;i<scwCells.childNodes.length;i++)
1601                {var scwRows = scwCells.childNodes[i];
1602                 if (scwRows.nodeType==1 && scwRows.tagName=='TR')
1603                    {if (scwWeekNumberDisplay)
1604                        {//Calculate the week number using scwShowDate
1605                         scwTmpEl = scwRows.childNodes[0];
1606                         scwTmpEl.innerHTML = scwWeekNumber(scwShowDate);
1607                         scwTmpEl.style.borderColor =
1608                             (scwTmpEl.currentStyle)
1609                                ?scwTmpEl.currentStyle['backgroundColor']
1610                                :(window.getComputedStyle)
1611                                    ?document.defaultView.getComputedStyle(scwTmpEl,null).getPropertyValue('background-color')
1612                                    :'';
1613                         scwTmpEl.style.display='';
1614                        }
1615                     else
1616                        {scwRows.childNodes[0].style.display='none';}
1617
1618                     for (j=1;j<scwRows.childNodes.length;j++)
1619                        {var scwCols = scwRows.childNodes[j];
1620                         if (scwCols.nodeType==1 && scwCols.tagName=='TD')
1621                            {scwRows.childNodes[j].innerHTML=
1622                                scwShowDate.getDate();
1623                             var scwCell=scwRows.childNodes[j],
1624                                 scwDisabled =
1625                                    ((scwOutOfRangeDisable &&
1626                                        (scwShowDate <
1627                                            (new Date(scwBaseYear,0,1,
1628                                                      scwShowDate.getHours()))
1629                                         ||
1630                                         scwShowDate >
1631                                            (new Date(scwBaseYear+
1632                                                      scwDropDownYears,0,0,
1633                                                      scwShowDate.getHours()))
1634                                        )
1635                                     ) ||
1636                                     (scwOutOfMonthDisable &&
1637                                        (scwShowDate <
1638                                            (new Date(scwShowDate.getFullYear(),
1639                                                      scwCurMonth,1,
1640                                                      scwShowDate.getHours()))
1641                                         ||
1642                                         scwShowDate >
1643                                            (new Date(scwShowDate.getFullYear(),
1644                                                      scwCurMonth+1,0,
1645                                                      scwShowDate.getHours()))
1646                                        )
1647                                     )
1648                                    )?true:false;
1649
1650                             scwCell.style.visibility =
1651                                (scwOutOfMonthHide &&
1652                                    (scwShowDate <
1653                                        (new Date(scwShowDate.getFullYear(),
1654                                                  scwCurMonth,1,
1655                                                  scwShowDate.getHours()))
1656                                     ||
1657                                     scwShowDate >
1658                                        (new Date(scwShowDate.getFullYear(),
1659                                                  scwCurMonth+1,0,
1660                                                  scwShowDate.getHours()))
1661                                    )
1662                                )?'hidden':'inherit';
1663
1664                             for (var k=0;k<scwDisabledDates.length;k++)
1665                                {if ((typeof scwDisabledDates[k]=='object') &&
1666                                     (scwDisabledDates[k].constructor == Date) &&
1667                                     scwCompareDateValue == scwDisabledDates[k].valueOf()
1668                                    )
1669                                    {scwDisabled = true;}
1670                                 else
1671                                    {if ((typeof scwDisabledDates[k]=='object') &&
1672                                         (scwDisabledDates[k].constructor == Array) &&
1673                                         scwCompareDateValue >= scwDisabledDates[k][0].valueOf() &&
1674                                         scwCompareDateValue <= scwDisabledDates[k][1].valueOf()
1675                                        )
1676                                        {scwDisabled = true;}
1677                                    }
1678                                }
1679
1680                             if (scwDisabled ||
1681                                 !scwEnabledDay[j-1+(7*((i*scwCells.childNodes.length)/6))] ||
1682                                 !scwPassEnabledDay[(j-1+(7*(i*scwCells.childNodes.length/6)))%7]
1683                                )
1684                                {scwRows.childNodes[j].onclick = null;
1685
1686                                 if (scwID('scwIE'))
1687                                    {scwRows.childNodes[j].onmouseover  = null;
1688                                     scwRows.childNodes[j].onmouseout   = null;
1689                                    }
1690
1691                                 scwCell.className=
1692                                    (scwShowDate.getMonth()!=scwCurMonth)
1693                                        ?'scwCellsExMonthDisabled'
1694                                        :(scwBlnFullInputDate &&
1695                                          scwShowDate.toDateString()==
1696                                          scwSeedDate.toDateString())
1697                                            ?'scwInputDateDisabled'
1698                                            :(scwShowDate.getDay()%6==0)
1699                                                ?'scwCellsWeekendDisabled'
1700                                                :'scwCellsDisabled';
1701
1702                                 scwCell.style.borderColor =
1703                                     (scwFormatTodayCell && scwShowDate.toDateString()==scwDateNow.toDateString())
1704                                        ?scwTodayCellBorderColour
1705                                        :(scwCell.currentStyle)
1706                                            ?scwCell.currentStyle['backgroundColor']
1707                                            :(window.getComputedStyle)
1708                                                ?document.defaultView.getComputedStyle(scwCell,null).getPropertyValue('background-color')
1709                                                :'';
1710                                }
1711                             else
1712                                {scwRows.childNodes[j].onclick=scwCellOutput;
1713
1714                                 if (scwID('scwIE'))
1715                                    {scwRows.childNodes[j].onmouseover  = scwChangeClass;
1716                                     scwRows.childNodes[j].onmouseout   = scwChangeClass;
1717                                    }
1718
1719                                 scwCell.className=
1720                                     (scwShowDate.getMonth()!=scwCurMonth)
1721                                        ?'scwCellsExMonth'
1722                                        :(scwBlnFullInputDate &&
1723                                          scwShowDate.toDateString()==
1724                                          scwSeedDate.toDateString())
1725                                            ?'scwInputDate'
1726                                            :(scwShowDate.getDay()%6==0)
1727                                                ?'scwCellsWeekend'
1728                                                :'scwCells';
1729
1730                                 scwCell.style.borderColor =
1731                                     (scwFormatTodayCell && scwShowDate.toDateString() == scwDateNow.toDateString())
1732                                        ?scwTodayCellBorderColour
1733                                        :(scwCell.currentStyle)
1734                                            ?scwCell.currentStyle['backgroundColor']
1735                                            :(window.getComputedStyle)
1736                                                ?document.defaultView.getComputedStyle(scwCell,null).getPropertyValue('background-color')
1737                                                :'';
1738                               }
1739
1740                             scwShowDate.setDate(scwShowDate.getDate()+1);
1741                             scwCompareDateValue = new Date(scwShowDate.getFullYear(),scwShowDate.getMonth(),scwShowDate.getDate()).valueOf();
1742                            }
1743                        }
1744                    }
1745                }
1746            }
1747
1748         // Opera has a bug with setting the selected index.
1749         // It requires the following work-around to force SELECTs to display correctly.
1750         // Also Opera's poor dynamic rendering prior to 9.5 requires
1751         // the visibility to be reset to prevent garbage in the calendar
1752         // when the displayed month is changed.
1753
1754         if (window.opera)
1755            {scwID('scwMonths').style.display = 'inline';
1756             scwID('scwYears' ).style.display = 'inline';
1757             scwID('scw').style.visibility='hidden';
1758             scwID('scw').style.visibility='inherit';
1759           }
1760        };
1761
1762// *************************
1763//  End of Function Library
1764// *************************
1765// ***************************
1766// Start of Calendar structure
1767// ***************************
1768
1769    document.writeln("<!--[if IE]><div id='scwIE'></div><![endif]-->");
1770    document.writeln("<!--[if lt IE 7]><div id='scwIElt7'></div><![endif]-->");
1771    document.write(
1772     "<iframe class='scw' " + (scwID('scwIElt7')?"src='/scwblank.html '":'') +
1773             "id='scwIframe' name='scwIframe' frameborder='0'>" +
1774     "</iframe>" +
1775     "<table id='scw' class='scw'>" +
1776       "<tr class='scw'>" +
1777         "<td class='scw'>" +
1778           "<table class='scwHead' id='scwHead' width='100%' " +
1779                    "cellspacing='0' cellpadding='0'>" +
1780            "<tr id='scwDrag' style='display:none;'>" +
1781                "<td colspan='4' class='scwDrag' " +
1782                    "onmousedown='scwBeginDrag(event);'>" +
1783                    "<span id='scwDragText'></span>" +
1784                "</td>" +
1785            "</tr>" +
1786            "<tr class='scwHead' >" +
1787                 "<td class='scwHead'>" +
1788                    "<input class='scwHead' id='scwHeadLeft' type='button' value='<' " +
1789                            "onclick='scwShowMonth(-1);'  /></td>" +
1790                 "<td class='scwHead'>" +
1791                    "<select id='scwMonths' class='scwHead' " +
1792                            "onchange='scwShowMonth(0);'>" +
1793                    "</select>" +
1794                 "</td>" +
1795                 "<td class='scwHead'>" +
1796                    "<select id='scwYears' class='scwHead' " +
1797                            "onchange='scwShowMonth(0);'>" +
1798                    "</select>" +
1799                 "</td>" +
1800                 "<td class='scwHead'>" +
1801                    "<input class='scwHead' id='scwHeadRight' type='button' value='>' " +
1802                            "onclick='scwShowMonth(1);' /></td>" +
1803                "</tr>" +
1804              "</table>" +
1805            "</td>" +
1806          "</tr>" +
1807          "<tr class='scw'>" +
1808            "<td class='scw'>" +
1809              "<table class='scwCells' align='center'>" +
1810                "<thead>" +
1811                  "<tr><td class='scwWeekNumberHead' id='scwWeek_' ></td>");
1812
1813    for (i=0;i<7;i++)
1814        {document.write(
1815                      "<td class='scwWeek' id='scwWeekInit" + i + "'></td>");
1816        }
1817
1818    document.write("</tr>" +
1819                "</thead>" +
1820                "<tbody id='scwCells' onClick='scwStopPropagation(event);'>");
1821
1822    for (i=0;i<6;i++)
1823        {document.write(
1824                    "<tr>" +
1825                      "<td class='scwWeekNo' id='scwWeek_" + i + "'></td>");
1826         for (j=0;j<7;j++)
1827            {document.write(
1828                        "<td class='scwCells' id='scwCell_" + (j+(i*7)) +
1829                        "'></td>");
1830            }
1831
1832         document.write(
1833                    "</tr>");
1834        }
1835
1836    document.write(
1837                "</tbody>" +
1838                "<tfoot>" +
1839                  "<tr id='scwFoot'>" +
1840                    "<td colspan='8' style='padding:0px;'>" +
1841                      "<table width='100%'>" +
1842                        "<tr>" +
1843                          "<td id='scwClear' class='scwClear'>" +
1844                            "<input type='button' id='scwClearButton' class='scwClear' " +
1845                                   "onclick='scwTargetEle.value = \"\";scwHide();' />" +
1846                          "</td>" +
1847                          "<td class='scwNow' id='scwNow'></td>" +
1848                        "</tr>" +
1849                      "</table>" +
1850                    "</td>" +
1851                  "</tr>" +
1852                "</tfoot>" +
1853              "</table>" +
1854            "</td>" +
1855          "</tr>" +
1856        "</table>");
1857
1858    if (document.addEventListener)
1859            {scwID('scw'         ).addEventListener('click',scwCancel,false);
1860             scwID('scwHeadLeft' ).addEventListener('click',scwStopPropagation,false);
1861             scwID('scwMonths'   ).addEventListener('click',scwStopPropagation,false);
1862             scwID('scwMonths'   ).addEventListener('change',scwStopPropagation,false);
1863             scwID('scwYears'    ).addEventListener('click',scwStopPropagation,false);
1864             scwID('scwYears'    ).addEventListener('change',scwStopPropagation,false);
1865             scwID('scwHeadRight').addEventListener('click',scwStopPropagation,false);
1866            }
1867    else    {scwID('scw'         ).attachEvent('onclick',scwCancel);
1868             scwID('scwHeadLeft' ).attachEvent('onclick',scwStopPropagation);
1869             scwID('scwMonths'   ).attachEvent('onclick',scwStopPropagation);
1870             scwID('scwMonths'   ).attachEvent('onchange',scwStopPropagation);
1871             scwID('scwYears'    ).attachEvent('onclick',scwStopPropagation);
1872             scwID('scwYears'    ).attachEvent('onchange',scwStopPropagation);
1873             scwID('scwHeadRight').attachEvent('onclick',scwStopPropagation);
1874            }
1875
1876// ***************************
1877//  End of Calendar structure
1878// ***************************
1879// ****************************************
1880// Start of document level event definition
1881// ****************************************
1882
1883    if (document.addEventListener)
1884            {document.addEventListener('click',scwHide, false);}
1885    else    {document.attachEvent('onclick',scwHide);}
1886
1887// ****************************************
1888//  End of document level event definition
1889// ****************************************
1890// ************************************
1891//  End of Simple Calendar Widget Code
1892// ************************************
Note: See TracBrowser for help on using the repository browser.