You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

calendar.js 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. // Tigra Calendar v4.0.2 (12-01-2009) European (dd.mm.yyyy)
  2. // http://www.softcomplex.com/products/tigra_calendar/
  3. // Public Domain Software... You're welcome.
  4. // default settins
  5. var A_TCALDEF = {
  6. 'months' : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
  7. 'weekdays' : ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
  8. 'yearscroll': true, // show year scroller
  9. 'weekstart': 1, // first day of week: 0-Su or 1-Mo
  10. 'centyear' : 70, // 2 digit years less than 'centyear' are in 20xx, othewise in 19xx.
  11. 'imgpath' : 'images/calendar/' // directory with calendar images
  12. }
  13. // date parsing function
  14. function f_tcalParseDate (s_date) {
  15. var re_date = /^\s*(\d{1,2})\.(\d{1,2})\.(\d{2,4})\s*$/;
  16. if (!re_date.exec(s_date))
  17. return alert ("Invalid date: '" + s_date + "'.\nAccepted format is dd.mm.yyyy.")
  18. var n_day = Number(RegExp.$1),
  19. n_month = Number(RegExp.$2),
  20. n_year = Number(RegExp.$3);
  21. if (n_year < 100)
  22. n_year += (n_year < this.a_tpl.centyear ? 2000 : 1900);
  23. if (n_month < 1 || n_month > 12)
  24. return alert ("Invalid month value: '" + n_month + "'.\nAllowed range is 01-12.");
  25. var d_numdays = new Date(n_year, n_month, 0);
  26. if (n_day > d_numdays.getDate())
  27. return alert("Invalid day of month value: '" + n_day + "'.\nAllowed range for selected month is 01 - " + d_numdays.getDate() + ".");
  28. return new Date (n_year, n_month - 1, n_day);
  29. }
  30. // date generating function
  31. function f_tcalGenerDate (d_date) {
  32. return (
  33. (d_date.getDate() < 10 ? '0' : '') + d_date.getDate() + "."
  34. + (d_date.getMonth() < 9 ? '0' : '') + (d_date.getMonth() + 1) + "."
  35. + d_date.getFullYear()
  36. );
  37. }
  38. // implementation
  39. function tcal (a_cfg, a_tpl) {
  40. // apply default template if not specified
  41. if (!a_tpl)
  42. a_tpl = A_TCALDEF;
  43. // register in global collections
  44. if (!window.A_TCALS)
  45. window.A_TCALS = [];
  46. if (!window.A_TCALSIDX)
  47. window.A_TCALSIDX = [];
  48. this.s_id = a_cfg.id ? a_cfg.id : A_TCALS.length;
  49. window.A_TCALS[this.s_id] = this;
  50. window.A_TCALSIDX[window.A_TCALSIDX.length] = this;
  51. // assign methods
  52. this.f_show = f_tcalShow;
  53. this.f_hide = f_tcalHide;
  54. this.f_toggle = f_tcalToggle;
  55. this.f_update = f_tcalUpdate;
  56. this.f_relDate = f_tcalRelDate;
  57. this.f_parseDate = f_tcalParseDate;
  58. this.f_generDate = f_tcalGenerDate;
  59. // create calendar icon
  60. this.s_iconId = 'tcalico_' + this.s_id;
  61. this.e_icon = f_getElement(this.s_iconId);
  62. if (!this.e_icon) {
  63. document.write('<img src="' + a_tpl.imgpath + 'cal.gif" id="' + this.s_iconId + '" onclick="A_TCALS[\'' + this.s_id + '\'].f_toggle()" class="tcalIcon" alt="Open Calendar" />');
  64. this.e_icon = f_getElement(this.s_iconId);
  65. }
  66. // save received parameters
  67. this.a_cfg = a_cfg;
  68. this.a_tpl = a_tpl;
  69. }
  70. function f_tcalShow (d_date) {
  71. // find input field
  72. if (!this.a_cfg.controlname)
  73. throw("TC: control name is not specified");
  74. if (this.a_cfg.formname) {
  75. var e_form = document.forms[this.a_cfg.formname];
  76. if (!e_form)
  77. throw("TC: form '" + this.a_cfg.formname + "' can not be found");
  78. this.e_input = e_form.elements[this.a_cfg.controlname];
  79. }
  80. else
  81. this.e_input = f_getElement(this.a_cfg.controlname);
  82. if (!this.e_input || !this.e_input.tagName || this.e_input.tagName != 'INPUT')
  83. throw("TC: element '" + this.a_cfg.controlname + "' does not exist in "
  84. + (this.a_cfg.formname ? "form '" + this.a_cfg.controlname + "'" : 'this document'));
  85. // dynamically create HTML elements if needed
  86. this.e_div = f_getElement('tcal');
  87. if (!this.e_div) {
  88. this.e_div = document.createElement("DIV");
  89. this.e_div.id = 'tcal';
  90. document.body.appendChild(this.e_div);
  91. }
  92. this.e_shade = f_getElement('tcalShade');
  93. if (!this.e_shade) {
  94. this.e_shade = document.createElement("DIV");
  95. this.e_shade.id = 'tcalShade';
  96. document.body.appendChild(this.e_shade);
  97. }
  98. this.e_iframe = f_getElement('tcalIF')
  99. if (b_ieFix && !this.e_iframe) {
  100. this.e_iframe = document.createElement("IFRAME");
  101. this.e_iframe.style.filter = 'alpha(opacity=0)';
  102. this.e_iframe.id = 'tcalIF';
  103. this.e_iframe.src = this.a_tpl.imgpath + 'pixel.gif';
  104. document.body.appendChild(this.e_iframe);
  105. }
  106. // hide all calendars
  107. f_tcalHideAll();
  108. // generate HTML and show calendar
  109. this.e_icon = f_getElement(this.s_iconId);
  110. if (!this.f_update())
  111. return;
  112. this.e_div.style.visibility = 'visible';
  113. this.e_shade.style.visibility = 'visible';
  114. if (this.e_iframe)
  115. this.e_iframe.style.visibility = 'visible';
  116. // change icon and status
  117. this.e_icon.src = this.a_tpl.imgpath + 'no_cal.gif';
  118. this.e_icon.title = 'Close Calendar';
  119. this.b_visible = true;
  120. }
  121. function f_tcalHide (n_date) {
  122. if (n_date)
  123. this.e_input.value = this.f_generDate(new Date(n_date));
  124. // no action if not visible
  125. if (!this.b_visible)
  126. return;
  127. // hide elements
  128. if (this.e_iframe)
  129. this.e_iframe.style.visibility = 'hidden';
  130. if (this.e_shade)
  131. this.e_shade.style.visibility = 'hidden';
  132. this.e_div.style.visibility = 'hidden';
  133. // change icon and status
  134. this.e_icon = f_getElement(this.s_iconId);
  135. this.e_icon.src = this.a_tpl.imgpath + 'cal.gif';
  136. this.e_icon.title = 'Open Calendar';
  137. this.b_visible = false;
  138. }
  139. function f_tcalToggle () {
  140. return this.b_visible ? this.f_hide() : this.f_show();
  141. }
  142. function f_tcalUpdate (d_date) {
  143. var d_today = this.a_cfg.today ? this.f_parseDate(this.a_cfg.today) : f_tcalResetTime(new Date());
  144. var d_selected = this.e_input.value == ''
  145. ? (this.a_cfg.selected ? this.f_parseDate(this.a_cfg.selected) : d_today)
  146. : this.f_parseDate(this.e_input.value);
  147. // figure out date to display
  148. if (!d_date)
  149. // selected by default
  150. d_date = d_selected;
  151. else if (typeof(d_date) == 'number')
  152. // get from number
  153. d_date = f_tcalResetTime(new Date(d_date));
  154. else if (typeof(d_date) == 'string')
  155. // parse from string
  156. this.f_parseDate(d_date);
  157. if (!d_date) return false;
  158. // first date to display
  159. var d_firstday = new Date(d_date);
  160. d_firstday.setDate(1);
  161. d_firstday.setDate(1 - (7 + d_firstday.getDay() - this.a_tpl.weekstart) % 7);
  162. var a_class, s_html = '<table class="ctrl"><tbody><tr>'
  163. + (this.a_tpl.yearscroll ? '<td' + this.f_relDate(d_date, -1, 'y') + ' title="Previous Year"><img src="' + this.a_tpl.imgpath + 'prev_year.gif" /></td>' : '')
  164. + '<td' + this.f_relDate(d_date, -1) + ' title="Previous Month"><img src="' + this.a_tpl.imgpath + 'prev_mon.gif" /></td><th>'
  165. + this.a_tpl.months[d_date.getMonth()] + ' ' + d_date.getFullYear()
  166. + '</th><td' + this.f_relDate(d_date, 1) + ' title="Next Month"><img src="' + this.a_tpl.imgpath + 'next_mon.gif" /></td>'
  167. + (this.a_tpl.yearscroll ? '<td' + this.f_relDate(d_date, 1, 'y') + ' title="Next Year"><img src="' + this.a_tpl.imgpath + 'next_year.gif" /></td></td>' : '')
  168. + '</tr></tbody></table><table><tbody><tr class="wd">';
  169. // print weekdays titles
  170. for (var i = 0; i < 7; i++)
  171. s_html += '<th>' + this.a_tpl.weekdays[(this.a_tpl.weekstart + i) % 7] + '</th>';
  172. s_html += '</tr>' ;
  173. // print calendar table
  174. var n_date, n_month, d_current = new Date(d_firstday);
  175. while (d_current.getMonth() == d_date.getMonth() ||
  176. d_current.getMonth() == d_firstday.getMonth()) {
  177. // print row heder
  178. s_html +='<tr>';
  179. for (var n_wday = 0; n_wday < 7; n_wday++) {
  180. a_class = [];
  181. n_date = d_current.getDate();
  182. n_month = d_current.getMonth();
  183. // other month
  184. if (d_current.getMonth() != d_date.getMonth())
  185. a_class[a_class.length] = 'othermonth';
  186. // weekend
  187. if (d_current.getDay() == 0 || d_current.getDay() == 6)
  188. a_class[a_class.length] = 'weekend';
  189. // today
  190. if (d_current.valueOf() == d_today.valueOf())
  191. a_class[a_class.length] = 'today';
  192. // selected
  193. if (d_current.valueOf() == d_selected.valueOf())
  194. a_class[a_class.length] = 'selected';
  195. s_html += '<td onclick="A_TCALS[\'' + this.s_id + '\'].f_hide(' + d_current.valueOf() + ')"' + (a_class.length ? ' class="' + a_class.join(' ') + '">' : '>') + n_date + '</td>'
  196. d_current.setDate(++n_date);
  197. while (d_current.getDate() != n_date && d_current.getMonth() == n_month) {
  198. alert(n_date + "\n" + d_current + "\n" + new Date());
  199. d_current.setHours(d_current.getHours + 1);
  200. d_current = f_tcalResetTime(d_current);
  201. }
  202. }
  203. // print row footer
  204. s_html +='</tr>';
  205. }
  206. s_html +='</tbody></table>';
  207. // update HTML, positions and sizes
  208. this.e_div.innerHTML = s_html;
  209. var n_width = this.e_div.offsetWidth;
  210. var n_height = this.e_div.offsetHeight;
  211. var n_top = f_getPosition (this.e_icon, 'Top') + this.e_icon.offsetHeight;
  212. var n_left = f_getPosition (this.e_icon, 'Left') - n_width + this.e_icon.offsetWidth;
  213. if (n_left < 0) n_left = 0;
  214. this.e_div.style.left = n_left + 'px';
  215. this.e_div.style.top = n_top + 'px';
  216. this.e_shade.style.width = (n_width + 8) + 'px';
  217. this.e_shade.style.left = (n_left - 1) + 'px';
  218. this.e_shade.style.top = (n_top - 1) + 'px';
  219. this.e_shade.innerHTML = b_ieFix
  220. ? '<table><tbody><tr><td rowspan="2" colspan="2" width="6"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td width="7" height="7" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + this.a_tpl.imgpath + 'shade_tr.png\', sizingMethod=\'scale\');"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td></tr><tr><td height="' + (n_height - 7) + '" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + this.a_tpl.imgpath + 'shade_mr.png\', sizingMethod=\'scale\');"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td></tr><tr><td width="7" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + this.a_tpl.imgpath + 'shade_bl.png\', sizingMethod=\'scale\');"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + this.a_tpl.imgpath + 'shade_bm.png\', sizingMethod=\'scale\');" height="7" align="left"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + this.a_tpl.imgpath + 'shade_br.png\', sizingMethod=\'scale\');"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td></tr><tbody></table>'
  221. : '<table><tbody><tr><td rowspan="2" width="6"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td rowspan="2"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td width="7" height="7"><img src="' + this.a_tpl.imgpath + 'shade_tr.png"></td></tr><tr><td background="' + this.a_tpl.imgpath + 'shade_mr.png" height="' + (n_height - 7) + '"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td></tr><tr><td><img src="' + this.a_tpl.imgpath + 'shade_bl.png"></td><td background="' + this.a_tpl.imgpath + 'shade_bm.png" height="7" align="left"><img src="' + this.a_tpl.imgpath + 'pixel.gif"></td><td><img src="' + this.a_tpl.imgpath + 'shade_br.png"></td></tr><tbody></table>';
  222. if (this.e_iframe) {
  223. this.e_iframe.style.left = n_left + 'px';
  224. this.e_iframe.style.top = n_top + 'px';
  225. this.e_iframe.style.width = (n_width + 6) + 'px';
  226. this.e_iframe.style.height = (n_height + 6) +'px';
  227. }
  228. return true;
  229. }
  230. function f_getPosition (e_elemRef, s_coord) {
  231. var n_pos = 0, n_offset,
  232. e_elem = e_elemRef;
  233. while (e_elem) {
  234. n_offset = e_elem["offset" + s_coord];
  235. n_pos += n_offset;
  236. e_elem = e_elem.offsetParent;
  237. }
  238. // margin correction in some browsers
  239. if (b_ieMac)
  240. n_pos += parseInt(document.body[s_coord.toLowerCase() + 'Margin']);
  241. else if (b_safari)
  242. n_pos -= n_offset;
  243. e_elem = e_elemRef;
  244. while (e_elem != document.body) {
  245. n_offset = e_elem["scroll" + s_coord];
  246. if (n_offset && e_elem.style.overflow == 'scroll')
  247. n_pos -= n_offset;
  248. e_elem = e_elem.parentNode;
  249. }
  250. return n_pos;
  251. }
  252. function f_tcalRelDate (d_date, d_diff, s_units) {
  253. var s_units = (s_units == 'y' ? 'FullYear' : 'Month');
  254. var d_result = new Date(d_date);
  255. d_result['set' + s_units](d_date['get' + s_units]() + d_diff);
  256. if (d_result.getDate() != d_date.getDate())
  257. d_result.setDate(0);
  258. return ' onclick="A_TCALS[\'' + this.s_id + '\'].f_update(' + d_result.valueOf() + ')"';
  259. }
  260. function f_tcalHideAll () {
  261. for (var i = 0; i < window.A_TCALSIDX.length; i++)
  262. window.A_TCALSIDX[i].f_hide();
  263. }
  264. function f_tcalResetTime (d_date) {
  265. d_date.setHours(0);
  266. d_date.setMinutes(0);
  267. d_date.setSeconds(0);
  268. d_date.setMilliseconds(0);
  269. return d_date;
  270. }
  271. f_getElement = document.all ?
  272. function (s_id) { return document.all[s_id] } :
  273. function (s_id) { return document.getElementById(s_id) };
  274. if (document.addEventListener)
  275. window.addEventListener('scroll', f_tcalHideAll, false);
  276. if (window.attachEvent)
  277. window.attachEvent('onscroll', f_tcalHideAll);
  278. // global variables
  279. var s_userAgent = navigator.userAgent.toLowerCase(),
  280. re_webkit = /WebKit\/(\d+)/i;
  281. var b_mac = s_userAgent.indexOf('mac') != -1,
  282. b_ie5 = s_userAgent.indexOf('msie 5') != -1,
  283. b_ie6 = s_userAgent.indexOf('msie 6') != -1 && s_userAgent.indexOf('opera') == -1;
  284. var b_ieFix = b_ie5 || b_ie6,
  285. b_ieMac = b_mac && b_ie5,
  286. b_safari = b_mac && re_webkit.exec(s_userAgent) && Number(RegExp.$1) < 500;