/aspnet/scw.js

http://genericgrid.codeplex.com · JavaScript · 1890 lines · 1085 code · 247 blank · 558 comment · 154 complexity · 3c64a195c5bf823c8c14eea2f1c98cf7 MD5 · raw file

  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. // Start of Simple Calendar Widget Code
  227. // ************************************
  228. // This date is used throughout to determine today's date.
  229. var scwDateNow = new Date(Date.parse(new Date().toDateString()));
  230. //******************************************************************************
  231. //------------------------------------------------------------------------------
  232. // Customisation section
  233. //------------------------------------------------------------------------------
  234. //******************************************************************************
  235. // Set the bounds for the calendar here...
  236. // If you want the year to roll forward you can use something like this...
  237. // var scwBaseYear = scwDateNow.getFullYear()-5;
  238. // alternatively, hard code a date like this...
  239. // var scwBaseYear = 1990;
  240. var scwBaseYear = scwDateNow.getFullYear()-10;
  241. // How many years do want to be valid and to show in the drop-down list?
  242. var scwDropDownYears = 20;
  243. // All language-dependent changes can be made here...
  244. // If you wish to work in a single language (other than English) then
  245. // just replace the English (in the function scwSetLanguage below) with
  246. // your own text.
  247. // Using multiple languages:
  248. // In order to keep this script to a resonable size I have not included
  249. // languages here. You can set language fields in a function that you
  250. // should call scwSetLanguage the script will use your languages.
  251. // I have included all the translations that have been sent to me in
  252. // such a function on the demonstration page.
  253. var scwLanguage;
  254. function scwSetDefaultLanguage()
  255. {try
  256. {scwSetLanguage();}
  257. catch (exception)
  258. {// English
  259. scwToday = 'Today:';
  260. scwClear = 'Clear';
  261. scwDrag = 'click here to drag';
  262. scwArrMonthNames = ['Jan','Feb','Mar','Apr','May','Jun',
  263. 'Jul','Aug','Sep','Oct','Nov','Dec'];
  264. scwArrWeekInits = ['S','M','T','W','T','F','S'];
  265. scwInvalidDateMsg = 'The entered date is invalid.\n';
  266. scwOutOfRangeMsg = 'The entered date is out of range.';
  267. scwDoesNotExistMsg = 'The entered date does not exist.';
  268. scwInvalidAlert = ['Invalid date (',') ignored.'];
  269. scwDateDisablingError = ['Error ',' is not a Date object.'];
  270. scwRangeDisablingError = ['Error ',
  271. ' should consist of two elements.'];
  272. }
  273. };
  274. // Note: Always start the scwArrWeekInits array with your string for
  275. // Sunday whatever scwWeekStart (below) is set to.
  276. // scwWeekStart determines the start of the week in the display
  277. // Set it to: 0 (Zero) for Sunday, 1 (One) for Monday etc..
  278. var scwWeekStart = 1;
  279. // The week start day for the display is taken as the week start
  280. // for week numbering. This ensures that only one week number
  281. // applies to one line of the calendar table.
  282. // [ISO 8601 begins the week with Day 1 = Monday.]
  283. // If you want to see week numbering on the calendar, set
  284. // this to true. If not, false.
  285. var scwWeekNumberDisplay = false;
  286. // Week numbering rules are generally based on a day in the week
  287. // that determines the first week of the year. ISO 8601 uses
  288. // Thursday (day four when Sunday is day zero). You can alter
  289. // the base day here.
  290. // See http://www.cl.cam.ac.uk/~mgk25/iso-time.html for more information
  291. var scwWeekNumberBaseDay = 4;
  292. // Each of the calendar's alert message types can be disabled
  293. // independently here.
  294. var scwShowInvalidDateMsg = true,
  295. scwShowOutOfRangeMsg = true,
  296. scwShowDoesNotExistMsg = true,
  297. scwShowInvalidAlert = true,
  298. scwShowDateDisablingError = true,
  299. scwShowRangeDisablingError = true;
  300. // Set the allowed input date delimiters here...
  301. // E.g. To set the rising slash, hyphen, full-stop (aka stop or point),
  302. // comma and space as delimiters use
  303. // var scwArrDelimiters = ['/','-','.',',',' '];
  304. var scwArrDelimiters = ['/','-','.',',',' '];
  305. // Set the format for the displayed 'Today' date and for the output
  306. // date here.
  307. //
  308. // The format is described using delimiters of your choice (as set
  309. // in scwArrDelimiters above) and case insensitive letters D, M and Y.
  310. //
  311. // NOTE: If no delimiters are input then the date output format is used
  312. // to parse the value. This allows less flexiblility in the input
  313. // value than using delimiters but an accurately entered date
  314. // remains parsable.
  315. //
  316. // Definition Returns
  317. // ---------- -------
  318. // D date in the month without zero filling
  319. // DD date in the month left zero filled
  320. // M month number without zero filling
  321. // MM month number left zero filled
  322. // MMM month string from scwArrMonthNames
  323. // YY year number in two digits
  324. // YYYY year number in four digits
  325. // Displayed "Today" date format
  326. var scwDateDisplayFormat = 'dd-mm-yy'; // e.g. 'MMM-DD-YYYY' for the US
  327. // Output date format
  328. //var scwDateOutputFormat = 'DD MMM YYYY'; // e.g. 'MMM-DD-YYYY' for the US
  329. var scwDateOutputFormat = 'dd/mm/yyyy'; // e.g. 'MMM-DD-YYYY' for the US
  330. // Note: The delimiters used should be in scwArrDelimiters.
  331. // scwZindex controls how the pop-up calendar interacts with the rest
  332. // of the page. It is usually adequate to leave it as 1 (One) but I
  333. // have made it available here to help anyone who needs to alter the
  334. // level in order to ensure that the calendar displays correctly in
  335. // relation to all other elements on the page.
  336. var scwZindex = 1000;
  337. // Personally I like the fact that entering 31-Sep-2005 displays
  338. // 1-Oct-2005, however you may want that to be an error. If so,
  339. // set scwBlnStrict = true. That will cause an error message to
  340. // display and the selected month is displayed without a selected
  341. // day. Thanks to Brad Allan for his feedback prompting this feature.
  342. var scwBlnStrict = false;
  343. // If you are using ReadOnly or Disabled fields to return the date
  344. // value into, it can be useful to show a button on the calendar
  345. // that allows the value to be cleared. If you want to do that,
  346. // set scwClearButton = true;
  347. var scwClearButton = true;
  348. // The calendar will position itself aligned with the bottom left
  349. // corner of the target element. If automatic positioning is turned
  350. // on with scwAutoPosition = true then if that would cause the
  351. // calendar to display off the visible screen, it is shifted to
  352. // a position that is visible.
  353. var scwAutoPosition = true;
  354. // If you wish to disable any displayed day, e.g. Every Monday,
  355. // you can do it by setting the following array. The array elements
  356. // match the displayed cells.
  357. //
  358. // You could put something like the following in your calling page
  359. // to disable all weekend days;
  360. //
  361. // for (var i=0;i<scwEnabledDay.length;i++)
  362. // {if (i%7%6==0) scwEnabledDay[i] = false;}
  363. //
  364. // The above approach will allow you to disable days of the week
  365. // for the whole of your page easily. If you need to set different
  366. // disabled days for a number of date input fields on your page
  367. // there is an easier way: You can pass additional arguments to
  368. // scwShow. The syntax is described at the top of this script in
  369. // the section:
  370. // "How to use the Calendar once it is defined for your page:"
  371. //
  372. // It is possible to use these two approaches in combination.
  373. var scwEnabledDay = [true, true, true, true, true, true, true,
  374. true, true, true, true, true, true, true,
  375. true, true, true, true, true, true, true,
  376. true, true, true, true, true, true, true,
  377. true, true, true, true, true, true, true,
  378. true, true, true, true, true, true, true];
  379. // You can disable any specific date (e.g. 24-Jan-2006 or Today) by
  380. // creating an element of the array scwDisabledDates as a date object
  381. // with the value you want to disable. Date ranges can be disabled
  382. // by placing an array of two values (Start and End) into an element
  383. // of this array.
  384. var scwDisabledDates = new Array();
  385. // e.g. To disable 10-Dec-2005:
  386. // scwDisabledDates[0] = new Date(2005,11,10);
  387. //
  388. // or a range from 2004-Dec-25 to 2005-Jan-01:
  389. // scwDisabledDates[1] = [new Date(2004,11,25),new Date(2005,0,1)];
  390. //
  391. // Remember that Javascript months are Zero-based.
  392. // The disabling by date and date range does prevent the current day
  393. // from being selected. Disabling days of the week does not so you can set
  394. // the scwActiveToday value to false to prevent selection.
  395. var scwActiveToday = true;
  396. // Dates that are out of the displayed month are shown at the start
  397. // (unless the month starts on the first day of the week) and end of each
  398. // month.
  399. //
  400. // Set scwOutOfMonthDisable to true to disable these dates (or false
  401. // to allow their selection).
  402. //
  403. // Set scwOutOfMonthHide to true to hide these dates (or false
  404. // to make them visible).
  405. var scwOutOfMonthDisable = false;
  406. var scwOutOfMonthHide = false;
  407. // Dates that are out of the specified range can be displayed at the start
  408. // of the very first month and end of the very last. Set
  409. // scwOutOfRangeDisable to true to disable these dates (or false to
  410. // allow their selection).
  411. var scwOutOfRangeDisable = true;
  412. // If you want a special format for the cell that contains the current day
  413. // set this to true. This sets a thin border around the cell in the colour
  414. // set by scwTodayCellBorderColour.
  415. var scwFormatTodayCell = true;
  416. var scwTodayCellBorderColour = 'red';
  417. // You can allow the calendar to be dragged around the screen by
  418. // using the setting scwAllowDrag to true.
  419. // I can't say I recommend it because of the danger of the user
  420. // forgetting which date field the calendar will update when there
  421. // are multiple date fields on a page.
  422. var scwAllowDrag = false;
  423. // Closing the calendar by clicking on it (rather than elsewhere on the
  424. // main page) can be inconvenient. The scwClickToHide boolean value
  425. // controls this feature.
  426. var scwClickToHide = false;
  427. // I have made every effort to isolate the pop-up script from any
  428. // CSS defined on the main page but if you have anything set that
  429. // affects the pop-up (or you may want to change the way it looks)
  430. // then you can address it in the following style sheets.
  431. document.writeln(
  432. '<style type="text/css">' +
  433. '.scw {padding:1px;vertical-align:middle;}' +
  434. 'iframe.scw {position:absolute;z-index:' + scwZindex +
  435. ';top:0px;left:0px;visibility:hidden;' +
  436. 'width:1px;height:1px;}' +
  437. 'table.scw {padding:0px;visibility:hidden;' +
  438. 'position:absolute;cursor:default;' +
  439. 'width:200px;top:0px;left:0px;' +
  440. 'z-index:' + (scwZindex+1) +
  441. ';text-align:center;}' +
  442. '</style>' );
  443. // This style sheet can be extracted from the script and edited into regular
  444. // CSS (by removing all occurrences of + and '). That can be used as the
  445. // basis for themes. Classes are described in comments within the style
  446. // sheet.
  447. document.writeln(
  448. '<style type="text/css">' +
  449. '/* IMPORTANT: The SCW calendar script requires all ' +
  450. ' the classes defined here.' +
  451. '*/' +
  452. 'table.scw {padding: 1px;' +
  453. 'vertical-align:middle;' +
  454. 'border: ridge 2px;' +
  455. 'font-size: 8pt;' +
  456. 'font-family: ' +
  457. 'Verdana,Arial,Helvetica,Sans-Serif;'+
  458. 'font-weight: bold;}' +
  459. 'td.scwDrag,' +
  460. 'td.scwHead {padding: 0px 0px;' +
  461. 'text-align: center;}' +
  462. 'td.scwDrag {font-size: 8pt;}' +
  463. 'select.scwHead {margin: 3px 1px;' +
  464. 'text-align: center;}' +
  465. 'input.scwHead {height: 22px;' +
  466. 'width: 22px;' +
  467. 'vertical-align:middle;' +
  468. 'text-align: center;' +
  469. 'margin: 2px 1px;' +
  470. 'font-weight: bold;' +
  471. 'font-size: 8pt;' +
  472. 'font-family: fixedSys;}' +
  473. 'td.scwWeekNumberHead,' +
  474. 'td.scwWeek {padding: 0px;' +
  475. 'text-align: center;' +
  476. 'font-weight: bold;}' +
  477. 'td.scwNow,' +
  478. 'td.scwNowHover,' +
  479. 'td.scwNow:hover,' +
  480. 'td.scwNowDisabled {padding: 0px;' +
  481. 'text-align: center;' +
  482. 'vertical-align:middle;' +
  483. 'font-size: 7pt;' +
  484. 'font-weight: normal;}' +
  485. 'table.scwCells {text-align: center;' +
  486. 'font-size: 6pt;' +
  487. 'width: 96%;}' +
  488. 'td.scwCells,' +
  489. 'td.scwCellsHover,' +
  490. 'td.scwCells:hover,' +
  491. 'td.scwCellsDisabled,' +
  492. 'td.scwCellsExMonth,' +
  493. 'td.scwCellsExMonthHover,' +
  494. 'td.scwCellsExMonth:hover,' +
  495. 'td.scwCellsExMonthDisabled,' +
  496. 'td.scwCellsWeekend,' +
  497. 'td.scwCellsWeekendHover,' +
  498. 'td.scwCellsWeekend:hover,' +
  499. 'td.scwCellsWeekendDisabled,' +
  500. 'td.scwInputDate,' +
  501. 'td.scwInputDateHover,' +
  502. 'td.scwInputDate:hover,' +
  503. 'td.scwInputDateDisabled,' +
  504. 'td.scwWeekNo,' +
  505. 'td.scwWeeks {padding: 3px;' +
  506. 'width: 16px;' +
  507. 'height: 16px;' +
  508. 'border-width: 1px;' +
  509. 'border-style: solid;' +
  510. 'font-weight: bold;' +
  511. 'vertical-align: middle;}' +
  512. '/* Blend the colours into your page here... */' +
  513. '/* Calendar background */' +
  514. 'table.scw {background-color: white;}' +
  515. '/* Drag Handle */' +
  516. 'td.scwDrag {background-color: #9999CC;' +
  517. 'color: #CCCCFF;}' +
  518. '/* Week number heading */' +
  519. 'td.scwWeekNumberHead {color: navy;}' +
  520. '/* Week day headings */' +
  521. 'td.scwWeek {color: navy;}' +
  522. '/* Week numbers */' +
  523. 'td.scwWeekNo {background-color: #776677;' +
  524. 'color: #CCCCCC;}' +
  525. '/* Enabled Days */' +
  526. '/* Week Day */' +
  527. 'td.scwCells {background-color: #F3F3F3;' +
  528. 'color: #000000;}' +
  529. '/* Day matching the input date */' +
  530. 'td.scwInputDate {background-color: #CC9999;' +
  531. 'color: #FF0000;}' +
  532. '/* Weekend Day */' +
  533. 'td.scwCellsWeekend {background-color: #F3F3F3;' +
  534. 'color: #CC6666;}' +
  535. '/* Day outside the current month */' +
  536. 'td.scwCellsExMonth {background-color: #CCCCCC;' +
  537. 'color: #666666;}' +
  538. '/* Today selector */' +
  539. 'td.scwNow {background-color: #6666CC;' +
  540. 'color: #FFFFFF;}' +
  541. '/* Clear Button */' +
  542. 'td.scwClear {padding: 0px;}' +
  543. 'input.scwClear {padding: 0px;' +
  544. 'text-align: center;' +
  545. 'font-size: 6pt;}' +
  546. '/* MouseOver/Hover formatting ' +
  547. ' If you want to "turn off" any of the formatting ' +
  548. ' then just set to the same as the standard format' +
  549. ' above.' +
  550. ' ' +
  551. ' Note: The reason that the following are' +
  552. ' implemented using both a class and a :hover' +
  553. ' pseudoclass is because Opera handles the rendering' +
  554. ' involved in the class swap very poorly and IE6 ' +
  555. ' (and below) only implements pseudoclasses on the' +
  556. ' anchor tag.' +
  557. '*/' +
  558. '/* Active cells */' +
  559. 'td.scwCells:hover,' +
  560. 'td.scwCellsHover {background-color: #FFFF00;' +
  561. 'cursor: pointer;' +
  562. 'color: #000000;}' +
  563. '/* Day matching the input date */' +
  564. 'td.scwInputDate:hover,' +
  565. 'td.scwInputDateHover {background-color: #FFFF00;' +
  566. 'cursor: pointer;' +
  567. 'color: #000000;}' +
  568. '/* Weekend cells */' +
  569. 'td.scwCellsWeekend:hover,' +
  570. 'td.scwCellsWeekendHover {background-color: #FFFF00;' +
  571. 'cursor: pointer;' +
  572. 'color: #000000;}' +
  573. '/* Day outside the current month */' +
  574. 'td.scwCellsExMonth:hover,' +
  575. 'td.scwCellsExMonthHover {background-color: #FFFF00;' +
  576. 'cursor: pointer;' +
  577. 'color: #000000;}' +
  578. '/* Today selector */' +
  579. 'td.scwNow:hover,' +
  580. 'td.scwNowHover {color: #FFFF00;' +
  581. 'cursor: pointer;' +
  582. 'font-weight: bold;}' +
  583. '/* Disabled cells */' +
  584. '/* Week Day */' +
  585. '/* Day matching the input date */' +
  586. 'td.scwInputDateDisabled {background-color: #999999;' +
  587. 'color: #000000;}' +
  588. 'td.scwCellsDisabled {background-color: #999999;' +
  589. 'color: #000000;}' +
  590. '/* Weekend Day */' +
  591. 'td.scwCellsWeekendDisabled {background-color: #999999;' +
  592. 'color: #CC6666;}' +
  593. '/* Day outside the current month */' +
  594. 'td.scwCellsExMonthDisabled {background-color: #999999;' +
  595. 'color: #666666;}' +
  596. 'td.scwNowDisabled {background-color: #6666CC;' +
  597. 'color: #FFFFFF;}' +
  598. '</style>'
  599. );
  600. //******************************************************************************
  601. //------------------------------------------------------------------------------
  602. // End of customisation section
  603. //------------------------------------------------------------------------------
  604. //******************************************************************************
  605. // Variables required by both scwShow and scwShowMonth
  606. var scwTargetEle,
  607. scwTriggerEle,
  608. scwMonthSum = 0,
  609. scwBlnFullInputDate = false,
  610. scwPassEnabledDay = new Array(),
  611. scwSeedDate = new Date(),
  612. scwParmActiveToday = true,
  613. scwWeekStart = scwWeekStart%7,
  614. scwToday,
  615. scwClear,
  616. scwDrag,
  617. scwArrMonthNames,
  618. scwArrWeekInits,
  619. scwInvalidDateMsg,
  620. scwOutOfRangeMsg,
  621. scwDoesNotExistMsg,
  622. scwInvalidAlert,
  623. scwDateDisablingError,
  624. scwRangeDisablingError;
  625. // Add a method to format a date into the required pattern
  626. Date.prototype.scwFormat =
  627. function(scwFormat)
  628. {var charCount = 0,
  629. codeChar = '',
  630. result = '';
  631. for (var i=0;i<=scwFormat.length;i++)
  632. {if (i<scwFormat.length && scwFormat.charAt(i)==codeChar)
  633. {// If we haven't hit the end of the string and
  634. // the format string character is the same as
  635. // the previous one, just clock up one to the
  636. // length of the current element definition
  637. charCount++;
  638. }
  639. else {switch (codeChar)
  640. {case 'y': case 'Y':
  641. result += (this.getFullYear()%Math.
  642. pow(10,charCount)).toString().
  643. scwPadLeft(charCount);
  644. break;
  645. case 'm': case 'M':
  646. // If we find an M, check the number of them to
  647. // determine whether to get the month number or
  648. // the month name.
  649. result += (charCount<3)
  650. ?(this.getMonth()+1).
  651. toString().scwPadLeft(charCount)
  652. :scwArrMonthNames[this.getMonth()];
  653. break;
  654. case 'd': case 'D':
  655. // If we find a D, get the date and format it
  656. result += this.getDate().toString().
  657. scwPadLeft(charCount);
  658. break;
  659. default:
  660. // Copy any unrecognised characters across
  661. while (charCount-- > 0) {result += codeChar;}
  662. }
  663. if (i<scwFormat.length)
  664. {// Store the character we have just worked on
  665. codeChar = scwFormat.charAt(i);
  666. charCount = 1;
  667. }
  668. }
  669. }
  670. return result;
  671. };
  672. // Add a method to left pad zeroes
  673. String.prototype.scwPadLeft =
  674. function(padToLength)
  675. {var result = '';
  676. for (var i=0;i<(padToLength - this.length);i++) {result += '0';}
  677. return (result + this);
  678. };
  679. // Set up a closure so that any next function can be triggered
  680. // after the calendar has been closed AND that function can take
  681. // arguments.
  682. Function.prototype.runsAfterSCW =
  683. function() {var func = this,
  684. args = new Array(arguments.length);
  685. for (var i=0;i<args.length;++i) {args[i] = arguments[i];}
  686. return function()
  687. {// concat/join the two argument arrays
  688. for (var i=0;i<arguments.length;++i) {args[args.length] = arguments[i];}
  689. return (args.shift()==scwTriggerEle)?func.apply(this, args):null;
  690. };
  691. };
  692. // Set up some shortcuts
  693. function scwID(id)
  694. {if (document.getElementById(id) || (!document.getElementById(id) && document.getElementsByName(id).length==0))
  695. // IF An ID attribute is assigned
  696. // OR No ID attribute is assigned but using IE and Opera
  697. // (which will find the NAME attribute value using getElementById)
  698. // OR No element has this ID or NAME attribute value
  699. // (used internally by the script)
  700. // THEN Return the required element.
  701. {return document.getElementById(id);}
  702. else {if (document.getElementsByName(id).length==1)
  703. // IF No ID attribute is assigned
  704. // AND Using a standards-based browser
  705. // AND Only one element has the NAME attribute set to the value
  706. // THEN Return the required element (using the NAME attribute value).
  707. {return document.getElementsByName(id)[0];}
  708. else {if (document.getElementsByName(id).length>1)
  709. { // IF No ID attribute is assigned
  710. // AND using a standards-based browser
  711. // AND more than one element has the NAME attribute set to the value
  712. // THEN alert developer to fix the fault.
  713. alert( 'SCW' +
  714. ' \nCannot uniquely identify element named: ' + id +
  715. '.\nMore than one identical NAME attribute defined' +
  716. '.\nSolution: Assign the required element a unique ID attribute value.');
  717. }
  718. }
  719. }
  720. };
  721. // Use a global variable for the return value from the next action
  722. // IE fails to pass the function through if the target element is in
  723. // a form and scwNextAction is not defined.
  724. var scwNextActionReturn, scwNextAction;
  725. // ****************************************************************************
  726. // Start of Function Library
  727. //
  728. // Exposed functions:
  729. //
  730. // scwShow Entry point for display of calendar,
  731. // called in main page.
  732. // showCal Legacy name of scwShow:
  733. // Passes only legacy arguments,
  734. // not the optional day disabling arguments.
  735. //
  736. // scwShowMonth Displays a month on the calendar,
  737. // Called when a month is set or changed.
  738. //
  739. // scwBeginDrag Controls calendar dragging.
  740. //
  741. // scwCancel Called when the calendar background is clicked:
  742. // Calls scwStopPropagation and may call scwHide.
  743. // scwHide Hides the calendar, called on various events.
  744. // scwStopPropagation Stops the propagation of an event.
  745. //
  746. // ****************************************************************************
  747. function showCal(scwEle,scwSource) {scwShow(scwEle,scwSource);};
  748. function scwShow(scwEle,scwSource)
  749. {if (!scwSource) {scwSource = window.event;}
  750. if (scwSource.tagName) // Second parameter isn't an event it's an element
  751. {var scwSourceEle = scwSource;
  752. if (scwID('scwIE')) {window.event.cancelBubble = true;}
  753. else {scwSourceEle.parentNode.addEventListener('click',scwStopPropagation,false);}
  754. }
  755. else // Second parameter is an event
  756. {var scwSourceEle = (scwSource.target)
  757. ?scwSource.target
  758. :scwSource.srcElement;
  759. // Stop the click event that opens the calendar from bubbling up to
  760. // the document-level event handler that hides it!
  761. if (scwSource.stopPropagation) {scwSource.stopPropagation();}
  762. else {scwSource.cancelBubble = true;}
  763. }
  764. scwTriggerEle = scwSourceEle;
  765. // Take any parameters that there might be from the third onwards as
  766. // day numbers to be disabled 0 = Sunday through to 6 = Saturday.
  767. scwParmActiveToday = true;
  768. for (var i=0;i<7;i++)
  769. {scwPassEnabledDay[(i+7-scwWeekStart)%7] = true;
  770. for (var j=2;j<arguments.length;j++)
  771. {if (arguments[j]==i)
  772. {scwPassEnabledDay[(i+7-scwWeekStart)%7] = false;
  773. if (scwDateNow.getDay()==i) {scwParmActiveToday = false;}
  774. }
  775. }
  776. }
  777. // If no value is preset then the seed date is
  778. // Today (when today is in range) OR
  779. // The middle of the date range.
  780. scwSeedDate = scwDateNow;
  781. // Find the date and Strip space characters from start and
  782. // end of date input.
  783. var scwDateValue = '';
  784. if (scwEle.value) {scwDateValue = scwEle.value.replace(/^\s+/,'').replace(/\s+$/,'');}
  785. else {if (typeof scwEle.value == 'undefined')
  786. {var scwChildNodes = scwEle.childNodes;
  787. for (var i=0;i<scwChildNodes.length;i++)
  788. {if (scwChildNodes[i].nodeType == 3)
  789. {scwDateValue = scwChildNodes[i].nodeValue.replace(/^\s+/,'').replace(/\s+$/,'');
  790. if (scwDateValue.length > 0)
  791. {scwTriggerEle.scwTextNode = scwChildNodes[i];
  792. scwTriggerEle.scwLength = scwChildNodes[i].nodeValue.length;
  793. break;
  794. }
  795. }
  796. }
  797. }
  798. }
  799. // Set the language-dependent elements
  800. scwSetDefaultLanguage();
  801. scwID('scwDragText').innerHTML = scwDrag;
  802. scwID('scwMonths').options.length = 0;
  803. for (var i=0;i<scwArrMonthNames.length;i++)
  804. {scwID('scwMonths').options[i] = new Option(scwArrMonthNames[i],scwArrMonthNames[i]);}
  805. scwID('scwYears').options.length = 0;
  806. for (var i=0;i<scwDropDownYears;i++)
  807. {scwID('scwYears').options[i] = new Option((scwBaseYear+i),(scwBaseYear+i));}
  808. for (var i=0;i<scwArrWeekInits.length;i++)
  809. {scwID('scwWeekInit' + i).innerHTML = scwArrWeekInits[(i+scwWeekStart)%scwArrWeekInits.length];}
  810. if (((new Date(scwBaseYear + scwDropDownYears, 0, 0)) > scwDateNow &&
  811. (new Date(scwBaseYear, 0, 0)) < scwDateNow) ||
  812. (scwClearButton && (scwEle.readOnly || scwEle.disabled))
  813. ) {scwID('scwFoot').style.display = '';
  814. scwID('scwNow').innerHTML = scwToday + ' ' + scwDateNow.scwFormat(scwDateDisplayFormat);
  815. scwID('scwClearButton').value = scwClear;
  816. if ((new Date(scwBaseYear + scwDropDownYears, 0, 0)) > scwDateNow &&
  817. (new Date(scwBaseYear, 0, 0)) < scwDateNow
  818. ) {scwID('scwNow').style.display = '';
  819. if (scwClearButton && (scwEle.readOnly || scwEle.disabled))
  820. {scwID('scwClear').style.display = '';
  821. scwID('scwClear').style.textAlign = 'left';
  822. scwID('scwNow').style.textAlign = 'right';
  823. }
  824. else {scwID('scwClear').style.display = 'none';
  825. scwID('scwNow').style.textAlign = 'center';
  826. }
  827. }
  828. else {scwID('scwClear').style.textAlign = 'center';
  829. scwID('scwClear').style.display = '';
  830. scwID('scwNow').style.display = 'none';
  831. }
  832. }
  833. else {scwID('scwFoot').style.display = 'none';}
  834. if (scwDateValue.length==0)
  835. {// If no value is entered and today is within the range,
  836. // use today's date, otherwise use the middle of the valid range.
  837. scwBlnFullInputDate=false;
  838. if ((new Date(scwBaseYear+scwDropDownYears,0,0))<scwSeedDate ||
  839. (new Date(scwBaseYear,0,1)) >scwSeedDate
  840. )
  841. {scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears / 2), 5, 1);}
  842. }
  843. else
  844. {function scwInputFormat()
  845. {var scwArrSeed = new Array(),
  846. scwArrInput = scwDateValue.split(new RegExp('[\\'+scwArrDelimiters.join('\\')+']+','g'));
  847. // "Escape" all the user defined date delimiters above -
  848. // several delimiters will need it and it does no harm for
  849. // the others.
  850. // Strip any empty array elements (caused by delimiters)
  851. // from the beginning or end of the array. They will
  852. // still appear in the output string if in the output
  853. // format.
  854. if (scwArrInput[0]!=null)
  855. {if (scwArrInput[0].length==0) {scwArrInput.splice(0,1);}
  856. if (scwArrInput[scwArrInput.length-1].length==0) {scwArrInput.splice(scwArrInput.length-1,1);}
  857. }
  858. scwBlnFullInputDate = false;
  859. scwDateOutputFormat = scwDateOutputFormat.toUpperCase();
  860. // List all the allowed letters in the date format
  861. var template = ['D','M','Y'];
  862. // Prepare the sequence of date input elements
  863. var result = new Array();
  864. for (var i=0;i<template.length;i++)
  865. {if (scwDateOutputFormat.search(template[i])>-1)
  866. {result[scwDateOutputFormat.search(template[i])] = template[i];}
  867. }
  868. var scwDateSequence = result.join('');
  869. // Separate the elements of the date input
  870. switch (scwArrInput.length)
  871. {case 1:
  872. {if (scwDateOutputFormat.indexOf('Y')>-1 &&
  873. scwArrInput[0].length>scwDateOutputFormat.lastIndexOf('Y'))
  874. {scwArrSeed[0] = parseInt(scwArrInput[0].substring(scwDateOutputFormat.indexOf('Y'),
  875. scwDateOutputFormat.lastIndexOf('Y')+1),10);
  876. }
  877. else {scwArrSeed[0] = 0;}
  878. if (scwDateOutputFormat.indexOf('M')>-1 &&
  879. scwArrInput[0].length>scwDateOutputFormat.lastIndexOf('M'))
  880. {scwArrSeed[1] = scwArrInput[0].substring(scwDateOutputFormat.indexOf('M'),
  881. scwDateOutputFormat.lastIndexOf('M')+1);
  882. }
  883. else {scwArrSeed[1] = '6';}
  884. if (scwDateOutputFormat.indexOf('D')>-1 &&
  885. scwArrInput[0].length>scwDateOutputFormat.lastIndexOf('D'))
  886. {scwArrSeed[2] = parseInt(scwArrInput[0].substring(scwDateOutputFormat.indexOf('D'),
  887. scwDateOutputFormat.lastIndexOf('D')+1),10);
  888. }
  889. else {scwArrSeed[2] = 1;}
  890. if (scwArrInput[0].length==scwDateOutputFormat.length) {scwBlnFullInputDate = true;}
  891. break;
  892. }
  893. case 2:
  894. {// Year and Month entry
  895. scwArrSeed[0] =
  896. parseInt(scwArrInput[scwDateSequence.
  897. replace(/D/i,'').
  898. search(/Y/i)],10); // Year
  899. scwArrSeed[1] = scwArrInput[scwDateSequence.
  900. replace(/D/i,'').
  901. search(/M/i)]; // Month
  902. scwArrSeed[2] = 1; // Day
  903. break;
  904. }
  905. case 3:
  906. {// Day Month and Year entry
  907. scwArrSeed[0] =
  908. parseInt(scwArrInput[scwDateSequence.
  909. search(/Y/i)],10); // Year
  910. scwArrSeed[1] = scwArrInput[scwDateSequence.
  911. search(/M/i)]; // Month
  912. scwArrSeed[2] =
  913. parseInt(scwArrInput[scwDateSequence.
  914. search(/D/i)],10); // Day
  915. scwBlnFullInputDate = true;
  916. break;
  917. }
  918. default:
  919. {// A stuff-up has led to more than three elements in
  920. // the date.
  921. scwArrSeed[0] = 0; // Year
  922. scwArrSeed[1] = 0; // Month
  923. scwArrSeed[2] = 0; // Day
  924. }
  925. }
  926. // These regular expressions validate the input date format
  927. // to the following rules;
  928. // Day 1-31 (optional zero on single digits)
  929. // Month 1-12 (optional zero on single digits)
  930. // or case insensitive name
  931. // Year One, Two or four digits
  932. // Months names are as set in the language-dependent
  933. // definitions and delimiters are set just below there
  934. var scwExpValDay = new RegExp('^(0?[1-9]|[1-2][0-9]|3[0-1])$'),
  935. scwExpValMonth = new RegExp('^(0?[1-9]|1[0-2]|' +
  936. scwArrMonthNames.join('|') +
  937. ')$','i'),
  938. scwExpValYear = new RegExp('^([0-9]{1,2}|[0-9]{4})$');
  939. // Apply validation and report failures
  940. if (scwExpValYear.exec(scwArrSeed[0]) == null ||
  941. scwExpValMonth.exec(scwArrSeed[1]) == null ||
  942. scwExpValDay.exec(scwArrSeed[2]) == null
  943. )
  944. {if (scwShowInvalidDateMsg)
  945. {alert(scwInvalidDateMsg +
  946. scwInvalidAlert[0] + scwDateValue +
  947. scwInvalidAlert[1]);}
  948. scwBlnFullInputDate = false;
  949. scwArrSeed[0] = scwBaseYear +
  950. Math.floor(scwDropDownYears/2); // Year
  951. scwArrSeed[1] = '6'; // Month
  952. scwArrSeed[2] = 1; // Day
  953. }
  954. // Return the Year in scwArrSeed[0]
  955. // Month in scwArrSeed[1]
  956. // Day in scwArrSeed[2]
  957. return scwArrSeed;
  958. };
  959. // Parse the string into an array using the allowed delimiters
  960. scwArrSeedDate = scwInputFormat();
  961. // So now we have the Year, Month and Day in an array.
  962. // If the year is one or two digits then the routine assumes a
  963. // year belongs in the 21st Century unless it is less than 50
  964. // in which case it assumes the 20th Century is intended.
  965. if (scwArrSeedDate[0]<100) {scwArrSeedDate[0] += (scwArrSeedDate[0]>50)?1900:2000;}
  966. // Check whether the month is in digits or an abbreviation
  967. if (scwArrSeedDate[1].search(/\d+/)<0)
  968. {for (i=0;i<scwArrMonthNames.length;i++)
  969. {if (scwArrSeedDate[1].toUpperCase()==scwArrMonthNames[i].toUpperCase())
  970. {scwArrSeedDate[1]=i+1;
  971. break;
  972. }
  973. }
  974. }
  975. scwSeedDate = new Date(scwArrSeedDate[0],scwArrSeedDate[1]-1,scwArrSeedDate[2]);
  976. }
  977. // Test that we have arrived at a valid date
  978. if (isNaN(scwSeedDate))
  979. {if (scwShowInvalidDateMsg) {alert(scwInvalidDateMsg + scwInvalidAlert[0] + scwDateValue + scwInvalidAlert[1]);}
  980. scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears/2),5,1);
  981. scwBlnFullInputDate=false;
  982. }
  983. else
  984. {// Test that the date is within range,
  985. // if not then set date to a sensible date in range.
  986. if ((new Date(scwBaseYear,0,1)) > scwSeedDate)
  987. {if (scwBlnStrict && scwShowOutOfRangeMsg) {alert(scwOutOfRangeMsg);}
  988. scwSeedDate = new Date(scwBaseYear,0,1);
  989. scwBlnFullInputDate=false;
  990. }
  991. else
  992. {if ((new Date(scwBaseYear+scwDropDownYears,0,0))<scwSeedDate)
  993. {if (scwBlnStrict && scwShowOutOfRangeMsg) {alert(scwOutOfRangeMsg);}
  994. scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears)-1,11,1);
  995. scwBlnFullInputDate=false;
  996. }
  997. else
  998. {if (scwBlnStrict && scwBlnFullInputDate &&
  999. (scwSeedDate.getDate() != scwArrSeedDate[2] ||
  1000. (scwSeedDate.getMonth()+1) != scwArrSeedDate[1] ||
  1001. scwSeedDate.getFullYear() != scwArrSeedDate[0]
  1002. )
  1003. )
  1004. {if (scwShowDoesNotExistMsg) alert(scwDoesNotExistMsg);
  1005. scwSeedDate = new Date(scwSeedDate.getFullYear(),scwSeedDate.getMonth()-1,1);
  1006. scwBlnFullInputDate=false;
  1007. }
  1008. }
  1009. }
  1010. }
  1011. // Test the disabled dates for validity
  1012. // Give error message if not valid.
  1013. for (var i=0;i<scwDisabledDates.length;i++)
  1014. {if (!((typeof scwDisabledDates[i] == 'object') && (scwDisabledDates[i].constructor == Date)))
  1015. {if ((typeof scwDisabledDates[i] == 'object') && (scwDisabledDates[i].constructor == Array))
  1016. {var scwPass = true;
  1017. if (scwDisabledDates[i].length !=2)
  1018. {if (scwShowRangeDisablingError)
  1019. {alert(scwRangeDisablingError[0] + scwDisabledDates[i] + scwRangeDisablingError[1]);}
  1020. scwPass = false;
  1021. }
  1022. else
  1023. {for (var j=0;j<scwDisabledDates[i].length;j++)
  1024. {if (!((typeof scwDisabledDates[i][j] == 'object') && (scwDisabledDates[i][j].constructor == Date)))
  1025. {if (scwShowRangeDisablingError)
  1026. {alert( scwDateDisablingError[0] + scwDisabledDates[i][j] + scwDateDisablingError[1]);}
  1027. scwPass = false;
  1028. }
  1029. }
  1030. }
  1031. if (scwPass && (scwDisabledDates[i][0] > scwDisabledDates[i][1])) {scwDisabledDates[i].reverse();}
  1032. }
  1033. else
  1034. {if (scwShowRangeDisablingError) {alert(scwDateDisablingError[0] + scwDisabledDates[i] + scwDateDisablingError[1]);}}
  1035. }
  1036. }
  1037. // Calculate the number of months that the entered (or
  1038. // defaulted) month is after the start of the allowed
  1039. // date range.
  1040. scwMonthSum = 12*(scwSeedDate.getFullYear()-scwBaseYear)+scwSeedDate.getMonth();
  1041. scwID('scwYears' ).options.selectedIndex = Math.floor(scwMonthSum/12);
  1042. scwID('scwMonths').options.selectedIndex = (scwMonthSum%12);
  1043. // Check whether or not dragging is allowed and display drag handle if necessary
  1044. scwID('scwDrag').style.display=(scwAllowDrag)?'':'none';
  1045. // Display the month
  1046. scwShowMonth(0);
  1047. // Position the calendar box
  1048. // The object sniffing for Opera allows for the fact that Opera
  1049. // is the only major browser that correctly reports the position
  1050. // of an element in a scrollable DIV. This is because IE and
  1051. // Firefox omit the DIV from the offsetParent tree.
  1052. scwTargetEle=scwEle;
  1053. var offsetTop =parseInt(scwEle.offsetTop ,10) + parseInt(scwEle.offsetHeight,10),
  1054. offsetLeft=parseInt(scwEle.offsetLeft,10);
  1055. if (!window.opera)
  1056. {while (scwEle.tagName!='BODY' && scwEle.tagName!='HTML')
  1057. {offsetTop -=parseInt(scwEle.scrollTop, 10);
  1058. offsetLeft-=parseInt(scwEle.scrollLeft,10);
  1059. scwEle=scwEle.parentNode;
  1060. }
  1061. scwEle=scwTargetEle;
  1062. }
  1063. do {scwEle=scwEle.offsetParent;
  1064. offsetTop +=parseInt(scwEle.offsetTop, 10);
  1065. offsetLeft+=parseInt(scwEle.offsetLeft,10);
  1066. }
  1067. while (scwEle.tagName!='BODY' && scwEle.tagName!='HTML');
  1068. if (scwAutoPosition)
  1069. {var scwWidth = parseInt(scwID('scw').offsetWidth, 10),
  1070. scwHeight = parseInt(scwID('scw').offsetHeight,10),
  1071. scwWindowLeft =
  1072. (document.body && document.body.scrollLeft)
  1073. ?document.body.scrollLeft //DOM compliant
  1074. :(document.documentElement && document.documentElement.scrollLeft)
  1075. ?document.documentElement.scrollLeft //IE6+ standards compliant
  1076. :0, //Failed
  1077. scwWindowWidth =
  1078. (typeof(innerWidth) == 'number')
  1079. ?innerWidth //DOM compliant
  1080. :(document.documentElement && document.documentElement.clientWidth)
  1081. ?document.documentElement.clientWidth //IE6+ standards compliant
  1082. :(document.body && document.body.clientWidth)
  1083. ?document.body.clientWidth //IE non-compliant
  1084. :0, //Failed
  1085. scwWindowTop =
  1086. (document.body && document.body.scrollTop)
  1087. ?document.body.scrollTop //DOM compliant
  1088. :(document.documentElement && document.documentElement.scrollTop)
  1089. ?document.documentElement.scrollTop //IE6+ standards compliant
  1090. :0, //Failed
  1091. scwWindowHeight =
  1092. (typeof(innerHeight) == 'number')
  1093. ?innerHeight //DOM compliant
  1094. :(document.documentElement && document.documentElement.clientHeight)
  1095. ?document.documentElement.clientHeight //IE6+ standards compliant
  1096. :(document.body && document.body.clientHeight)
  1097. ?document.body.clientHeight //IE non-compliant
  1098. :0; //Failed
  1099. offsetLeft -= (offsetLeft - scwWidth + parseInt(scwTargetEle.offsetWidth,10) >= scwWindowLeft &&
  1100. offsetLeft + scwWidth > scwWindowLeft + scwWindowWidth
  1101. )?(scwWidth - parseInt(scwTargetEle.offsetWidth,10)):0;
  1102. offsetTop -= (offsetTop - scwHeight - parseInt(scwTargetEle.offsetHeight,10) >= scwWindowTop &&
  1103. offsetTop + scwHeight > scwWindowTop + scwWindowHeight
  1104. )?(scwHeight + parseInt(scwTargetEle.offsetHeight,10)):0;
  1105. }
  1106. scwID('scw').style.top = offsetTop+'px';
  1107. scwID('scw').style.left = offsetLeft+'px';
  1108. scwID('scwIframe').style.top = offsetTop+'px';
  1109. scwID('scwIframe').style.left = offsetLeft+'px';
  1110. scwID('scwIframe').style.width =(scwID('scw').offsetWidth-(scwID('scwIE')?2:4))+'px';
  1111. scwID('scwIframe').style.height=(scwID('scw').offsetHeight-(scwID('scwIE')?2:4))+'px';
  1112. scwID('scwIframe').style.visibility='inherit';
  1113. // Show it on the page
  1114. scwID('scw').style.visibility='inherit';
  1115. };
  1116. function scwHide()
  1117. {scwID('scw').style.visibility='hidden';
  1118. scwID('scwIframe').style.visibility='hidden';
  1119. if (typeof scwNextAction!='undefined' && scwNextAction!=null)
  1120. {scwNextActionReturn = scwNextAction();
  1121. // Explicit null set to prevent closure causing memory leak
  1122. scwNextAction = null;
  1123. }
  1124. };
  1125. function scwCancel(scwEvt)
  1126. {if (scwClickToHide) {scwHide();}
  1127. scwStopPropagation(scwEvt);
  1128. };
  1129. function scwStopPropagation(scwEvt)
  1130. {if (scwEvt.stopPropagation)
  1131. {scwEvt.stopPropagation();} // Capture phase
  1132. else {scwEvt.cancelBubble = true;} // Bubbling phase
  1133. };
  1134. function scwBeginDrag(event)
  1135. {var elementToDrag = scwID('scw');
  1136. var deltaX = event.clientX,
  1137. deltaY = event.clientY,
  1138. offsetEle = elementToDrag;
  1139. do {deltaX -= parseInt(offsetEle.offsetLeft,10);
  1140. deltaY -= parseInt(offsetEle.offsetTop ,10);
  1141. offsetEle = offsetEle.offsetParent;
  1142. }
  1143. while (offsetEle.tagName!='BODY' &&
  1144. offsetEle.tagName!='HTML');
  1145. if (document.addEventListener)
  1146. {document.addEventListener('mousemove',moveHandler,true); // Capture phase
  1147. document.addEventListener('mouseup', upHandler, true); // Capture phase
  1148. }
  1149. else {elementToDrag.attachEvent('onmousemove',moveHandler); // Bubbling phase
  1150. elementToDrag.attachEvent('onmouseup', upHandler); // Bubbling phase
  1151. elementToDrag.setCapture();
  1152. }
  1153. scwStopPropagation(event);
  1154. function moveHandler(scwEvt)
  1155. {if (!scwEvt) scwEvt = window.event;
  1156. elementToDrag.style.left = (scwEvt.clientX - deltaX) + 'px';
  1157. elementToDrag.style.top = (scwEvt.clientY - deltaY) + 'px';
  1158. scwID('scwIframe').style.left = (scwEvt.clientX - deltaX) + 'px';
  1159. scwID('scwIframe').style.top = (scwEvt.clientY - deltaY) + 'px';
  1160. scwStopPropagation(scwEvt);
  1161. };
  1162. function upHandler(scwEvt)
  1163. {if (!scwEvt) scwEvt = window.event;
  1164. if (document.removeEventListener)
  1165. {document.removeEventListener('mousemove',moveHandler,true); // Capture phase
  1166. document.removeEventListener('mouseup', upHandler, true); // Capture phase
  1167. }
  1168. else {elementToDrag.detachEvent('onmouseup', upHandler); // Bubbling phase
  1169. elementToDrag.detachEvent('onmousemove',moveHandler); // Bubbling phase
  1170. elementToDrag.releaseCapture();
  1171. }
  1172. scwStopPropagation(scwEvt);
  1173. };
  1174. };
  1175. function scwShowMonth(scwBias)
  1176. {// Set the selectable Month and Year
  1177. // May be called: from the left and right arrows
  1178. // (shift month -1 and +1 respectively)
  1179. // from the month selection list
  1180. // from the year selection list
  1181. // from the showCal routine
  1182. // (which initiates the display).
  1183. var scwShowDate = new Date(Date.parse(new Date().toDateString())),
  1184. scwStartDate = new Date();
  1185. // Set the time to the middle of the day so that the handful of
  1186. // regions that have daylight saving shifts that change the day
  1187. // of the month (i.e. turn the clock back at midnight or forward
  1188. // at 23:00) do not mess up the date display in the calendar.
  1189. scwShowDate.setHours(12);
  1190. scwSelYears = scwID('scwYears');
  1191. scwSelMonths = scwID('scwMonths');
  1192. if (scwSelYears.options.selectedIndex>-1)
  1193. {scwMonthSum=12*(scwSelYears.options.selectedIndex)+scwBias;
  1194. if (scwSelMonths.options.selectedIndex>-1) {scwMonthSum+=scwSelMonths.options.selectedIndex;}
  1195. }
  1196. else
  1197. {if (scwSelMonths.options.selectedIndex>-1) {scwMonthSum+=scwSelMonths.options.selectedIndex;}}
  1198. scwShowDate.setFullYear(scwBaseYear + Math.floor(scwMonthSum/12),(scwMonthSum%12),1);
  1199. // If the Week numbers are displayed, shift the week day names to the right.
  1200. scwID('scwWeek_').style.display=(scwWeekNumberDisplay)?'':'none';
  1201. // Opera has a bug with setting the selected index.
  1202. // It requires the following work-around to force SELECTs to display correctly.
  1203. if (window.opera)
  1204. {scwID('scwMonths').style.display = 'inherit';
  1205. scwID('scwYears' ).style.display = 'inherit';
  1206. }
  1207. // Set the drop down boxes.
  1208. scwTemp = (12*parseInt((scwShowDate.getFullYear()-scwBaseYear),10)) + parseInt(scwShowDate.getMonth(),10);
  1209. if (scwTemp > -1 && scwTemp < (12*scwDropDownYears))
  1210. {scwSelYears.options.selectedIndex=Math.floor(scwMonthSum/12);
  1211. scwSelMonths.options.selectedIndex=(scwMonthSum%12);
  1212. scwCurMonth = scwShowDate.getMonth();
  1213. scwShowDate.setDate((((scwShowDate.
  1214. getDay()-scwWeekStart)<0)?-6:1)+
  1215. scwWeekStart-scwShowDate.getDay());
  1216. // This statement moved by Michael Cerveny to make version 3.55
  1217. var scwCompareDateValue = new Date(scwShowDate.getFullYear(),
  1218. scwShowDate.getMonth(),
  1219. scwShowDate.getDate()).valueOf();
  1220. scwStartDate = new Date(scwShowDate);
  1221. if ((new Date(scwBaseYear + scwDropDownYears, 0, 0)) > scwDateNow &&
  1222. (new Date(scwBaseYear, 0, 0)) < scwDateNow)
  1223. {var scwNow = scwID('scwNow');
  1224. function scwNowOutput() {scwSetOutput(scwDateNow);};
  1225. if (scwDisabledDates.length==0)
  1226. {if (scwActiveToday && scwParmActiveToday)
  1227. {scwNow.onclick = scwNowOutput;
  1228. scwNow.className = 'scwNow';
  1229. if (scwID('scwIE'))
  1230. {scwNow.onmouseover = scwChangeClass;
  1231. scwNow.onmouseout = scwChangeClass;
  1232. }
  1233. }
  1234. else
  1235. {scwNow.onclick = null;
  1236. scwNow.className = 'scwNowDisabled';
  1237. if (scwID('scwIE'))
  1238. {scwNow.onmouseover = null;
  1239. scwNow.onmouseout = null;
  1240. }
  1241. if (document.addEventListener)
  1242. {scwNow.addEventListener('click',scwStopPropagation,false);}
  1243. else {scwNow.attachEvent('onclick',scwStopPropagation);}
  1244. }
  1245. }
  1246. else
  1247. {for (var k=0;k<scwDisabledDates.length;k++)
  1248. {if (!scwActiveToday || !scwParmActiveToday ||
  1249. ((typeof scwDisabledDates[k] == 'object') &&
  1250. (((scwDisabledDates[k].constructor == Date) &&
  1251. scwDateNow.valueOf() == scwDisabledDates[k].valueOf()
  1252. ) ||
  1253. ((scwDisabledDates[k].constructor == Array) &&
  1254. scwDateNow.valueOf() >= scwDisabledDates[k][0].valueOf() &&
  1255. scwDateNow.valueOf() <= scwDisabledDates[k][1].valueOf()
  1256. )
  1257. )
  1258. )
  1259. )
  1260. {scwNow.onclick = null;
  1261. scwNow.className = 'scwNowDisabled';
  1262. if (scwID('scwIE'))
  1263. {scwNow.onmouseover = null;
  1264. scwNow.onmouseout = null;
  1265. }
  1266. if (document.addEventListener)
  1267. {scwNow.addEventListener('click',scwStopPropagation,false);}
  1268. else {scwNow.attachEvent('onclick',scwStopPropagation);}
  1269. break;
  1270. }
  1271. else
  1272. {scwNow.onclick=scwNowOutput;
  1273. scwNow.className='scwNow';
  1274. if (scwID('scwIE'))
  1275. {scwNow.onmouseover = scwChangeClass;
  1276. scwNow.onmouseout = scwChangeClass;
  1277. }
  1278. }
  1279. }
  1280. }
  1281. }
  1282. function scwSetOutput(scwOutputDate)
  1283. {if (typeof scwTargetEle.value == 'undefined')
  1284. {scwTriggerEle.scwTextNode.replaceData(0,scwTriggerEle.scwLength,scwOutputDate.scwFormat(scwDateOutputFormat));}
  1285. else {scwTargetEle.value = scwOutputDate.scwFormat(scwDateOutputFormat);}
  1286. scwHide();
  1287. //alert("in scwSetOutut");
  1288. //CloseUpd();
  1289. };
  1290. function scwCellOutput(scwEvt)
  1291. {var scwEle = scwEventTrigger(scwEvt),
  1292. scwOutputDate = new Date(scwStartDate);
  1293. if (scwEle.nodeType==3) scwEle=scwEle.parentNode;
  1294. scwOutputDate.setDate(scwStartDate.getDate() + parseInt(scwEle.id.substr(8),10));
  1295. scwSetOutput(scwOutputDate);
  1296. };
  1297. function scwChangeClass(scwEvt)
  1298. {var scwEle = scwEventTrigger(scwEvt);
  1299. if (scwEle.nodeType==3) {scwEle=scwEle.parentNode;}
  1300. switch (scwEle.className)
  1301. {case 'scwCells':
  1302. scwEle.className = 'scwCellsHover';
  1303. break;
  1304. case 'scwCellsHover':
  1305. scwEle.className = 'scwCells';
  1306. break;
  1307. case 'scwCellsExMonth':
  1308. scwEle.className = 'scwCellsExMonthHover';
  1309. break;
  1310. case 'scwCellsExMonthHover':
  1311. scwEle.className = 'scwCellsExMonth';
  1312. break;
  1313. case 'scwCellsWeekend':
  1314. scwEle.className = 'scwCellsWeekendHover';
  1315. break;
  1316. case 'scwCellsWeekendHover':
  1317. scwEle.className = 'scwCellsWeekend';
  1318. break;
  1319. case 'scwNow':
  1320. scwEle.className = 'scwNowHover';
  1321. break;
  1322. case 'scwNowHover':
  1323. scwEle.className = 'scwNow';
  1324. break;
  1325. case 'scwInputDate':
  1326. scwEle.className = 'scwInputDateHover';
  1327. break;
  1328. case 'scwInputDateHover':
  1329. scwEle.className = 'scwInputDate';
  1330. }
  1331. return true;
  1332. }
  1333. function scwEventTrigger(scwEvt)
  1334. {if (!scwEvt) {scwEvt = event;}
  1335. return scwEvt.target||scwEvt.srcElement;
  1336. };
  1337. function scwWeekNumber(scwInDate)
  1338. {// The base day in the week of the input date
  1339. var scwInDateWeekBase = new Date(scwInDate);
  1340. scwInDateWeekBase.setDate(scwInDateWeekBase.getDate()
  1341. - scwInDateWeekBase.getDay()
  1342. + scwWeekNumberBaseDay
  1343. + ((scwInDate.getDay()>
  1344. scwWeekNumberBaseDay)?7:0));
  1345. // The first Base Day in the year
  1346. var scwFirstBaseDay = new Date(scwInDateWeekBase.getFullYear(),0,1);
  1347. scwFirstBaseDay.setDate(scwFirstBaseDay.getDate()
  1348. - scwFirstBaseDay.getDay()
  1349. + scwWeekNumberBaseDay
  1350. );
  1351. if (scwFirstBaseDay < new Date(scwInDateWeekBase.getFullYear(),0,1))
  1352. {scwFirstBaseDay.setDate(scwFirstBaseDay.getDate()+7);}
  1353. // Start of Week 01
  1354. var scwStartWeekOne = new Date(scwFirstBaseDay
  1355. - scwWeekNumberBaseDay
  1356. + scwInDate.getDay());
  1357. if (scwStartWeekOne > scwFirstBaseDay)
  1358. {scwStartWeekOne.setDate(scwStartWeekOne.getDate()-7);}
  1359. // Subtract the date of the current week from the date of the
  1360. // first week of the year to get the number of weeks in
  1361. // milliseconds. Divide by the number of milliseconds
  1362. // in a week then round to no decimals in order to remove
  1363. // the effect of daylight saving. Add one to make the first
  1364. // week, week 1. Place a string zero on the front so that
  1365. // week numbers are zero filled.
  1366. var scwWeekNo = '0' + (Math.round((scwInDateWeekBase - scwFirstBaseDay)/604800000,0) + 1);
  1367. // Return the last two characters in the week number string
  1368. return scwWeekNo.substring(scwWeekNo.length-2, scwWeekNo.length);
  1369. };
  1370. // Treewalk to display the dates.
  1371. // I tried to use getElementsByName but IE refused to cooperate
  1372. // so I resorted to this method which works for all tested
  1373. // browsers.
  1374. var scwCells = scwID('scwCells');
  1375. for (i=0;i<scwCells.childNodes.length;i++)
  1376. {var scwRows = scwCells.childNodes[i];
  1377. if (scwRows.nodeType==1 && scwRows.tagName=='TR')
  1378. {if (scwWeekNumberDisplay)
  1379. {//Calculate the week number using scwShowDate
  1380. scwTmpEl = scwRows.childNodes[0];
  1381. scwTmpEl.innerHTML = scwWeekNumber(scwShowDate);
  1382. scwTmpEl.style.borderColor =
  1383. (scwTmpEl.currentStyle)
  1384. ?scwTmpEl.currentStyle['backgroundColor']
  1385. :(window.getComputedStyle)
  1386. ?document.defaultView.getComputedStyle(scwTmpEl,null).getPropertyValue('background-color')
  1387. :'';
  1388. scwTmpEl.style.display='';
  1389. }
  1390. else
  1391. {scwRows.childNodes[0].style.display='none';}
  1392. for (j=1;j<scwRows.childNodes.length;j++)
  1393. {var scwCols = scwRows.childNodes[j];
  1394. if (scwCols.nodeType==1 && scwCols.tagName=='TD')
  1395. {scwRows.childNodes[j].innerHTML=
  1396. scwShowDate.getDate();
  1397. var scwCell=scwRows.childNodes[j],
  1398. scwDisabled =
  1399. ((scwOutOfRangeDisable &&
  1400. (scwShowDate <
  1401. (new Date(scwBaseYear,0,1,
  1402. scwShowDate.getHours()))
  1403. ||
  1404. scwShowDate >
  1405. (new Date(scwBaseYear+
  1406. scwDropDownYears,0,0,
  1407. scwShowDate.getHours()))
  1408. )
  1409. ) ||
  1410. (scwOutOfMonthDisable &&
  1411. (scwShowDate <
  1412. (new Date(scwShowDate.getFullYear(),
  1413. scwCurMonth,1,
  1414. scwShowDate.getHours()))
  1415. ||
  1416. scwShowDate >
  1417. (new Date(scwShowDate.getFullYear(),
  1418. scwCurMonth+1,0,
  1419. scwShowDate.getHours()))
  1420. )
  1421. )
  1422. )?true:false;
  1423. scwCell.style.visibility =
  1424. (scwOutOfMonthHide &&
  1425. (scwShowDate <
  1426. (new Date(scwShowDate.getFullYear(),
  1427. scwCurMonth,1,
  1428. scwShowDate.getHours()))
  1429. ||
  1430. scwShowDate >
  1431. (new Date(scwShowDate.getFullYear(),
  1432. scwCurMonth+1,0,
  1433. scwShowDate.getHours()))
  1434. )
  1435. )?'hidden':'inherit';
  1436. for (var k=0;k<scwDisabledDates.length;k++)
  1437. {if ((typeof scwDisabledDates[k]=='object') &&
  1438. (scwDisabledDates[k].constructor == Date) &&
  1439. scwCompareDateValue == scwDisabledDates[k].valueOf()
  1440. )
  1441. {scwDisabled = true;}
  1442. else
  1443. {if ((typeof scwDisabledDates[k]=='object') &&
  1444. (scwDisabledDates[k].constructor == Array) &&
  1445. scwCompareDateValue >= scwDisabledDates[k][0].valueOf() &&
  1446. scwCompareDateValue <= scwDisabledDates[k][1].valueOf()
  1447. )
  1448. {scwDisabled = true;}
  1449. }
  1450. }
  1451. if (scwDisabled ||
  1452. !scwEnabledDay[j-1+(7*((i*scwCells.childNodes.length)/6))] ||
  1453. !scwPassEnabledDay[(j-1+(7*(i*scwCells.childNodes.length/6)))%7]
  1454. )
  1455. {scwRows.childNodes[j].onclick = null;
  1456. if (scwID('scwIE'))
  1457. {scwRows.childNodes[j].onmouseover = null;
  1458. scwRows.childNodes[j].onmouseout = null;
  1459. }
  1460. scwCell.className=
  1461. (scwShowDate.getMonth()!=scwCurMonth)
  1462. ?'scwCellsExMonthDisabled'
  1463. :(scwBlnFullInputDate &&
  1464. scwShowDate.toDateString()==
  1465. scwSeedDate.toDateString())
  1466. ?'scwInputDateDisabled'
  1467. :(scwShowDate.getDay()%6==0)
  1468. ?'scwCellsWeekendDisabled'
  1469. :'scwCellsDisabled';
  1470. scwCell.style.borderColor =
  1471. (scwFormatTodayCell && scwShowDate.toDateString()==scwDateNow.toDateString())
  1472. ?scwTodayCellBorderColour
  1473. :(scwCell.currentStyle)
  1474. ?scwCell.currentStyle['backgroundColor']
  1475. :(window.getComputedStyle)
  1476. ?document.defaultView.getComputedStyle(scwCell,null).getPropertyValue('background-color')
  1477. :'';
  1478. }
  1479. else
  1480. {scwRows.childNodes[j].onclick=scwCellOutput;
  1481. if (scwID('scwIE'))
  1482. {scwRows.childNodes[j].onmouseover = scwChangeClass;
  1483. scwRows.childNodes[j].onmouseout = scwChangeClass;
  1484. }
  1485. scwCell.className=
  1486. (scwShowDate.getMonth()!=scwCurMonth)
  1487. ?'scwCellsExMonth'
  1488. :(scwBlnFullInputDate &&
  1489. scwShowDate.toDateString()==
  1490. scwSeedDate.toDateString())
  1491. ?'scwInputDate'
  1492. :(scwShowDate.getDay()%6==0)
  1493. ?'scwCellsWeekend'
  1494. :'scwCells';
  1495. scwCell.style.borderColor =
  1496. (scwFormatTodayCell && scwShowDate.toDateString() == scwDateNow.toDateString())
  1497. ?scwTodayCellBorderColour
  1498. :(scwCell.currentStyle)
  1499. ?scwCell.currentStyle['backgroundColor']
  1500. :(window.getComputedStyle)
  1501. ?document.defaultView.getComputedStyle(scwCell,null).getPropertyValue('background-color')
  1502. :'';
  1503. }
  1504. scwShowDate.setDate(scwShowDate.getDate()+1);
  1505. scwCompareDateValue = new Date(scwShowDate.getFullYear(),scwShowDate.getMonth(),scwShowDate.getDate()).valueOf();
  1506. }
  1507. }
  1508. }
  1509. }
  1510. }
  1511. // Opera has a bug with setting the selected index.
  1512. // It requires the following work-around to force SELECTs to display correctly.
  1513. // Also Opera's poor dynamic rendering prior to 9.5 requires
  1514. // the visibility to be reset to prevent garbage in the calendar
  1515. // when the displayed month is changed.
  1516. if (window.opera)
  1517. {scwID('scwMonths').style.display = 'inline';
  1518. scwID('scwYears' ).style.display = 'inline';
  1519. scwID('scw').style.visibility='hidden';
  1520. scwID('scw').style.visibility='inherit';
  1521. }
  1522. };
  1523. // *************************
  1524. // End of Function Library
  1525. // *************************
  1526. // ***************************
  1527. // Start of Calendar structure
  1528. // ***************************
  1529. document.writeln("<!--[if IE]><div id='scwIE'></div><![endif]-->");
  1530. document.writeln("<!--[if lt IE 7]><div id='scwIElt7'></div><![endif]-->");
  1531. document.write(
  1532. "<iframe class='scw' " + (scwID('scwIElt7')?"src='/scwblank.html '":'') +
  1533. "id='scwIframe' name='scwIframe' frameborder='0'>" +
  1534. "</iframe>" +
  1535. "<table id='scw' class='scw'>" +
  1536. "<tr class='scw'>" +
  1537. "<td class='scw'>" +
  1538. "<table class='scwHead' id='scwHead' width='100%' " +
  1539. "cellspacing='0' cellpadding='0'>" +
  1540. "<tr id='scwDrag' style='display:none;'>" +
  1541. "<td colspan='4' class='scwDrag' " +
  1542. "onmousedown='scwBeginDrag(event);'>" +
  1543. "<span id='scwDragText'></span>" +
  1544. "</td>" +
  1545. "</tr>" +
  1546. "<tr class='scwHead' >" +
  1547. "<td class='scwHead'>" +
  1548. "<input class='scwHead' id='scwHeadLeft' type='button' value='<' " +
  1549. "onclick='scwShowMonth(-1);' /></td>" +
  1550. "<td class='scwHead'>" +
  1551. "<select id='scwMonths' class='scwHead' " +
  1552. "onchange='scwShowMonth(0);'>" +
  1553. "</select>" +
  1554. "</td>" +
  1555. "<td class='scwHead'>" +
  1556. "<select id='scwYears' class='scwHead' " +
  1557. "onchange='scwShowMonth(0);'>" +
  1558. "</select>" +
  1559. "</td>" +
  1560. "<td class='scwHead'>" +
  1561. "<input class='scwHead' id='scwHeadRight' type='button' value='>' " +
  1562. "onclick='scwShowMonth(1);' /></td>" +
  1563. "</tr>" +
  1564. "</table>" +
  1565. "</td>" +
  1566. "</tr>" +
  1567. "<tr class='scw'>" +
  1568. "<td class='scw'>" +
  1569. "<table class='scwCells' align='center'>" +
  1570. "<thead>" +
  1571. "<tr><td class='scwWeekNumberHead' id='scwWeek_' ></td>");
  1572. for (i=0;i<7;i++)
  1573. {document.write(
  1574. "<td class='scwWeek' id='scwWeekInit" + i + "'></td>");
  1575. }
  1576. document.write("</tr>" +
  1577. "</thead>" +
  1578. "<tbody id='scwCells' onClick='scwStopPropagation(event);'>");
  1579. for (i=0;i<6;i++)
  1580. {document.write(
  1581. "<tr>" +
  1582. "<td class='scwWeekNo' id='scwWeek_" + i + "'></td>");
  1583. for (j=0;j<7;j++)
  1584. {document.write(
  1585. "<td class='scwCells' id='scwCell_" + (j+(i*7)) +
  1586. "'></td>");
  1587. }
  1588. document.write(
  1589. "</tr>");
  1590. }
  1591. document.write(
  1592. "</tbody>" +
  1593. "<tfoot>" +
  1594. "<tr id='scwFoot'>" +
  1595. "<td colspan='8' style='padding:0px;'>" +
  1596. "<table border='0' width='100%'>" +
  1597. "<tr>" +
  1598. "<td id='scwClear' class='scwClear'>" +
  1599. "<input type='button' id='scwClearButton' class='scwClear' " +
  1600. "onclick='scwTargetEle.value = \"\";scwHide();' />" +
  1601. "</td>" +
  1602. "<td class='scwNow' id='scwNow'></td>" +
  1603. "</tr>" +
  1604. "</table>" +
  1605. "</td>" +
  1606. "</tr>" +
  1607. "</tfoot>" +
  1608. "</table>" +
  1609. "</td>" +
  1610. "</tr>" +
  1611. "</table>");
  1612. if (document.addEventListener)
  1613. {scwID('scw' ).addEventListener('click',scwCancel,false);
  1614. scwID('scwHeadLeft' ).addEventListener('click',scwStopPropagation,false);
  1615. scwID('scwMonths' ).addEventListener('click',scwStopPropagation,false);
  1616. scwID('scwMonths' ).addEventListener('change',scwStopPropagation,false);
  1617. scwID('scwYears' ).addEventListener('click',scwStopPropagation,false);
  1618. scwID('scwYears' ).addEventListener('change',scwStopPropagation,false);
  1619. scwID('scwHeadRight').addEventListener('click',scwStopPropagation,false);
  1620. }
  1621. else {scwID('scw' ).attachEvent('onclick',scwCancel);
  1622. scwID('scwHeadLeft' ).attachEvent('onclick',scwStopPropagation);
  1623. scwID('scwMonths' ).attachEvent('onclick',scwStopPropagation);
  1624. scwID('scwMonths' ).attachEvent('onchange',scwStopPropagation);
  1625. scwID('scwYears' ).attachEvent('onclick',scwStopPropagation);
  1626. scwID('scwYears' ).attachEvent('onchange',scwStopPropagation);
  1627. scwID('scwHeadRight').attachEvent('onclick',scwStopPropagation);
  1628. }
  1629. // ***************************
  1630. // End of Calendar structure
  1631. // ***************************
  1632. // ****************************************
  1633. // Start of document level event definition
  1634. // ****************************************
  1635. if (document.addEventListener)
  1636. {document.addEventListener('click',scwHide, false);}
  1637. else {document.attachEvent('onclick',scwHide);}
  1638. // ****************************************
  1639. // End of document level event definition
  1640. // ****************************************
  1641. // ************************************
  1642. // End of Simple Calendar Widget Code
  1643. // ************************************