diff --git a/phpgwapi/inc/jscalendar-setup.php b/phpgwapi/inc/jscalendar-setup.php index 7f37938ad1..20267421d3 100644 --- a/phpgwapi/inc/jscalendar-setup.php +++ b/phpgwapi/inc/jscalendar-setup.php @@ -1,8 +1,10 @@ * +* This file is derived from jscalendar's calendar-setup.js file and the * +* english translation in lang/calendar-en.js. * * -------------------------------------------- * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the * @@ -25,26 +27,33 @@ $GLOBALS['phpgw_info']['flags'] = Array( include('../../header.inc.php'); $dateformat = $GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat']; -$jsDateFormat = str_replace(array('Y','d','m'),array('y','dd','mm'),$dateformat); +$jsDateFormat = str_replace(array('Y','d','m','M'),array('%Y','%d','%m','%b'),$dateformat); $dayFirst = strpos($dateformat,'d') < strpos($dateformat,'m'); -$jsLongDateFormat = 'DD, '.($dayFirst ? 'd' : 'MM').($dateformat[1] == '.' ? '. ' : ' ').($dayFirst ? 'MM' : 'd'); +$jsLongDateFormat = '%a, '.($dayFirst ? '%e' : '%b').($dateformat[1] == '.' ? '. ' : ' ').($dayFirst ? '%b' : '%e'); -/* Copyright Mihai Bazon, 2002, 2003 | http://students.infoiasi.ro/~mishoo +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ * --------------------------------------------------------------------------- * * The DHTML Calendar * * Details and latest version at: - * http://students.infoiasi.ro/~mishoo/site/calendar.epl + * http://dynarch.com/mishoo/calendar.epl * - * Feel free to use this script under the terms of the GNU Lesser General - * Public License, as long as you do not remove or alter this notice. + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html * * This file defines helper functions for setting up the calendar. They are * intended to help non-programmers get a working calendar on their site - * quickly. + * quickly. This script should not be seen as part of the calendar. It just + * shows you what one can do with the calendar, while in the same time + * providing a quick and simple method for setting it up. If you need + * exhaustive customization of the calendar creation process feel free to + * modify this code to suit your needs (this is recommended and much better + * than modifying calendar.js itself). */ +// $Id$ + /** * This function "patches" an input field (or other element) to use a calendar * widget for date selection. @@ -60,37 +69,53 @@ $jsLongDateFormat = 'DD, '.($dayFirst ? 'd' : 'MM').($dateformat[1] == '.' ? '. * ifFormat | date format that will be stored in the input field * daFormat | the date format that will be used to display the date in displayArea * singleClick | (true/false) wether the calendar is in single click mode or not (default: true) - * mondayFirst | (true/false) if true Monday is the first day of week, Sunday otherwise (default: false) + * mondayFirst | (true/false) if true Monday is the first day of week, Sunday otherwise (default: true) * align | alignment (default: "Bl"); if you don't know what's this see the calendar documentation * range | array with 2 elements. Default: [1900, 2999] -- the range of years available * weekNumbers | (true/false) if it's true (default) the calendar will display week numbers * flat | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID * flatCallback | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar) * disableFunc | function that receives a JS Date object and should return true if that date has to be disabled in the calendar + * onSelect | function that gets called when a date is selected. You don't _have_ to supply this (the default is generally okay) + * onClose | function that gets called when the calendar is closed. [default] + * onUpdate | function that gets called after the date is updated in the input field. Receives a reference to the calendar. + * date | the date that the calendar will be initially displayed to + * showsTime | default: false; if true the calendar will include a time selector + * timeFormat | the time format; can be "12" or "24", default is "12" * * None of them is required, they all have default values. However, if you * pass none of "inputField", "displayArea" or "button" you'll get a warning * saying "nothing to setup". */ - ?> Calendar.setup = function (params) { function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } }; - param_default("inputField", null); - param_default("displayArea", null); - param_default("button", null); - param_default("eventName", "click"); + param_default("inputField", null); + param_default("displayArea", null); + param_default("button", null); + param_default("eventName", "click"); +// param_default("ifFormat", "%Y/%m/%d"); param_default("ifFormat", ""); +// param_default("daFormat", "%Y/%m/%d"); param_default("daFormat", ""); - param_default("singleClick", true); - param_default("disableFunc", null); + param_default("singleClick", true); + param_default("disableFunc", null); + param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined +// param_default("mondayFirst", true); param_default("mondayFirst", ); - param_default("align", "Bl"); - param_default("range", [1900, 2999]); - param_default("weekNumbers", true); - param_default("flat", null); - param_default("flatCallback", null); + param_default("align", "Bl"); + param_default("range", [1900, 2999]); + param_default("weekNumbers", true); + param_default("flat", null); + param_default("flatCallback", null); + param_default("onSelect", null); + param_default("onClose", null); + param_default("onUpdate", null); + param_default("date", null); + param_default("showsTime", false); +// param_default("timeFormat", "24"); + param_default("timeFormat", ""); var tmp = ["inputField", "displayArea", "button"]; for (var i in tmp) { @@ -121,6 +146,9 @@ Calendar.setup = function (params) { if (cal.params.singleClick && cal.dateClicked) { cal.callCloseHandler(); } + if (typeof cal.params.onUpdate == "function") { + cal.params.onUpdate(cal); + } }; if (params.flat != null) { @@ -129,11 +157,13 @@ Calendar.setup = function (params) { alert("Calendar.setup:\n Flat specified but can't find parent."); return false; } - var cal = new Calendar(params.mondayFirst, null, onSelect); + var cal = new Calendar(params.mondayFirst, params.date, params.onSelect || onSelect); + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); cal.params = params; cal.weekNumbers = params.weekNumbers; cal.setRange(params.range[0], params.range[1]); - cal.setDisabledHandler(params.disableFunc); + cal.setDateStatusHandler(params.dateStatusFunc); cal.create(params.flat); cal.show(); return false; @@ -144,29 +174,42 @@ Calendar.setup = function (params) { var dateEl = params.inputField || params.displayArea; var dateFmt = params.inputField ? params.ifFormat : params.daFormat; var mustCreate = false; + var cal = window.calendar; if (!window.calendar) { - window.calendar = new Calendar(params.mondayFirst, null, onSelect, function(cal) { cal.hide(); }); - window.calendar.weekNumbers = params.weekNumbers; + window.calendar = cal = new Calendar(params.mondayFirst, + params.date, + params.onSelect || onSelect, + params.onClose || function(cal) { cal.hide(); }); + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); + cal.weekNumbers = params.weekNumbers; mustCreate = true; } else { - window.calendar.hide(); + cal.hide(); } - window.calendar.setRange(params.range[0], params.range[1]); - window.calendar.params = params; - window.calendar.setDisabledHandler(params.disableFunc); - window.calendar.setDateFormat(dateFmt); - if (mustCreate) { - window.calendar.create(); - } - window.calendar.parseDate(dateEl.value || dateEl.innerHTML); - window.calendar.refresh(); - window.calendar.showAtElement(params.displayArea || params.inputField, params.align); + cal.setRange(params.range[0], params.range[1]); + cal.params = params; + cal.setDateStatusHandler(params.dateStatusFunc); + cal.setDateFormat(dateFmt); + if (mustCreate) + cal.create(); + cal.parseDate(dateEl.value || dateEl.innerHTML); + cal.refresh(); + cal.showAtElement(params.displayArea || params.inputField, params.align); return false; }; }; -// translations +// eGroupWare translations, are read from the database + // ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// full day names Calendar._DN = new Array ("", "", @@ -176,6 +219,10 @@ Calendar._DN = new Array "", "", ""); + +// please note eGW does NOT use the short month-names atm. + +// full month names Calendar._MN = new Array ("", "", @@ -192,6 +239,24 @@ Calendar._MN = new Array // tooltips Calendar._TT = {}; +Calendar._TT["INFO"] = ""; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2003\n" + // don't translate this this ;-) +"For latest version visit: http://dynarch.com/mishoo/calendar.epl\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"\n" + +"\n" + +"\n" + +""; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"\n" + +"\n" + +"\n" + +""; + Calendar._TT["TOGGLE"] = ""; Calendar._TT["PREV_YEAR"] = ""; Calendar._TT["PREV_MONTH"] = ""; @@ -205,9 +270,12 @@ Calendar._TT["MON_FIRST"] = ""; Calendar._TT["SUN_FIRST"] = ""; Calendar._TT["CLOSE"] = ""; Calendar._TT["TODAY"] = ""; +Calendar._TT["TIME_PART"] = ""; // date formats +//Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; Calendar._TT["DEF_DATE_FORMAT"] = ""; +//Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; Calendar._TT["TT_DATE_FORMAT"] = ""; Calendar._TT["WK"] = ""; diff --git a/phpgwapi/js/jscalendar/README b/phpgwapi/js/jscalendar/README index c0af3edd1e..d558f80517 100644 --- a/phpgwapi/js/jscalendar/README +++ b/phpgwapi/js/jscalendar/README @@ -2,17 +2,13 @@ The DHTML Calendar ------------------- Author: Mihai Bazon, - http://students.infoiasi.ro/~mishoo + http://dynarch.com/mishoo/ This program is free software published under the - GNU Lesser General Public License. + terms of the GNU Lesser General Public License. For the entire license text please refer to - http://www.gnu.org/licenses/lgpl - - An additional restriction is that you are not allowed - to remove the comment note present at the beginning of - the script. + http://www.gnu.org/licenses/lgpl.html Contents --------- @@ -31,5 +27,5 @@ Homepage For details and latest versions please refer to calendar homepage, located on my website: - http://students.infoiasi.ro/~mishoo/site/calendar.epl + http://dynarch.com/mishoo/calendar.epl diff --git a/phpgwapi/js/jscalendar/README-phpGW b/phpgwapi/js/jscalendar/README-eGW similarity index 69% rename from phpgwapi/js/jscalendar/README-phpGW rename to phpgwapi/js/jscalendar/README-eGW index e2e03973fa..a893f44721 100644 --- a/phpgwapi/js/jscalendar/README-phpGW +++ b/phpgwapi/js/jscalendar/README-eGW @@ -1,4 +1,4 @@ -This directory contains the (unchanged) Version 0.9.3 of jsCalendar +This directory contains the (unchanged) Version 0.9.5 of jsCalendar jsCalendar is called by the jscalendar wrapper-class in the phpGW API @@ -7,3 +7,7 @@ which sets all jscalendar preferences (partly from the users prefs) and read the translations from the database for the language the user has spec. in his prefs. RalfBecker@outdoor-training.de + +History: +11-Nov-2003 updated to version 0.9.5 +17-Aug-2003 inital import of version 0.9.3 diff --git a/phpgwapi/js/jscalendar/calendar-blue.css b/phpgwapi/js/jscalendar/calendar-blue.css index 502e19b219..b8ec504187 100644 --- a/phpgwapi/js/jscalendar/calendar-blue.css +++ b/phpgwapi/js/jscalendar/calendar-blue.css @@ -18,6 +18,10 @@ div.calendar { position: relative; } padding: 2px; /* Make the buttons seem like they're pressing */ } +.calendar .nav { + background: #778 url(menuarrow.gif) no-repeat 100% 100%; +} + .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; /* Pressing it will take you to the current date */ text-align: center; @@ -47,14 +51,14 @@ div.calendar { position: relative; } } .calendar thead .hilite { /* How do the buttons in header appear when hover */ - background: #aaf; + background-color: #aaf; color: #000; border: 1px solid #04f; padding: 1px; } .calendar thead .active { /* Active (pressed) buttons in header */ - background: #77c; + background-color: #77c; padding: 2px 0px 0px 2px; } @@ -161,9 +165,14 @@ div.calendar { position: relative; } font-size: smaller; } -.combo .label { - width: 100%; +.combo .label, +.combo .label-IEfix { text-align: center; + padding: 1px; +} + +.combo .label-IEfix { + width: 4em; } .combo .hilite { @@ -176,3 +185,40 @@ div.calendar { position: relative; } background: #eef; font-weight: bold; } + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #f4f0e8; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #667; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/phpgwapi/js/jscalendar/calendar-brown.css b/phpgwapi/js/jscalendar/calendar-brown.css index e1e8457df9..4ecc36d918 100644 --- a/phpgwapi/js/jscalendar/calendar-brown.css +++ b/phpgwapi/js/jscalendar/calendar-brown.css @@ -18,6 +18,10 @@ div.calendar { position: relative; } padding: 2px; /* Make the buttons seem like they're pressing */ } +.calendar .nav { + background: #edc url(menuarrow.gif) no-repeat 100% 100%; +} + .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; /* Pressing it will take you to the current date */ text-align: center; @@ -43,14 +47,14 @@ div.calendar { position: relative; } } .calendar thead .hilite { /* How do the buttons in header appear when hover */ - background: #faa; + background-color: #faa; color: #000; border: 1px solid #f40; padding: 1px; } .calendar thead .active { /* Active (pressed) buttons in header */ - background: #c77; + background-color: #c77; padding: 2px 0px 0px 2px; } @@ -154,9 +158,14 @@ div.calendar { position: relative; } font-size: smaller; } -.combo .label { - width: 100%; +.combo .label, +.combo .label-IEfix { text-align: center; + padding: 1px; +} + +.combo .label-IEfix { + width: 4em; } .combo .hilite { @@ -169,3 +178,40 @@ div.calendar { position: relative; } background: #fee; font-weight: bold; } + +.calendar td.time { + border-top: 1px solid #a88; + padding: 1px 0px; + text-align: center; + background-color: #fed; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #988; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #866; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/phpgwapi/js/jscalendar/calendar-green.css b/phpgwapi/js/jscalendar/calendar-green.css index c59aaa5aa7..55bb8aed50 100644 --- a/phpgwapi/js/jscalendar/calendar-green.css +++ b/phpgwapi/js/jscalendar/calendar-green.css @@ -21,6 +21,10 @@ div.calendar { position: relative; } font-size: 90%; } +.calendar .nav { + background: #676 url(menuarrow.gif) no-repeat 100% 100%; +} + .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; /* Pressing it will take you to the current date */ text-align: center; @@ -44,14 +48,14 @@ div.calendar { position: relative; } } .calendar thead .hilite { /* How do the buttons in header appear when hover */ - background: #afa; + background-color: #afa; color: #000; border: 1px solid #084; padding: 1px; } .calendar thead .active { /* Active (pressed) buttons in header */ - background: #7c7; + background-color: #7c7; padding: 2px 0px 0px 2px; } @@ -70,7 +74,7 @@ div.calendar { position: relative; } .calendar table .wn { padding: 2px 3px 2px 2px; - border-right: 1px solid #000; + border-right: 1px solid #8a8; background: #dfb; } @@ -158,9 +162,14 @@ div.calendar { position: relative; } font-size: smaller; } -.combo .label { - width: 100%; +.combo .label, +.combo .label-IEfix { text-align: center; + padding: 1px; +} + +.combo .label-IEfix { + width: 4em; } .combo .hilite { @@ -173,3 +182,40 @@ div.calendar { position: relative; } background: #efe; font-weight: bold; } + +.calendar td.time { + border-top: 1px solid #8a8; + padding: 1px 0px; + text-align: center; + background-color: #dfb; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #898; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #686; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/phpgwapi/js/jscalendar/calendar-setup.js b/phpgwapi/js/jscalendar/calendar-setup.js index 4c3ace149e..856f4834fe 100644 --- a/phpgwapi/js/jscalendar/calendar-setup.js +++ b/phpgwapi/js/jscalendar/calendar-setup.js @@ -1,17 +1,22 @@ -/* Copyright Mihai Bazon, 2002, 2003 | http://students.infoiasi.ro/~mishoo +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ * --------------------------------------------------------------------------- * * The DHTML Calendar * * Details and latest version at: - * http://students.infoiasi.ro/~mishoo/site/calendar.epl + * http://dynarch.com/mishoo/calendar.epl * - * Feel free to use this script under the terms of the GNU Lesser General - * Public License, as long as you do not remove or alter this notice. + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html * * This file defines helper functions for setting up the calendar. They are * intended to help non-programmers get a working calendar on their site - * quickly. + * quickly. This script should not be seen as part of the calendar. It just + * shows you what one can do with the calendar, while in the same time + * providing a quick and simple method for setting it up. If you need + * exhaustive customization of the calendar creation process feel free to + * modify this code to suit your needs (this is recommended and much better + * than modifying calendar.js itself). */ // $Id$ @@ -31,13 +36,19 @@ * ifFormat | date format that will be stored in the input field * daFormat | the date format that will be used to display the date in displayArea * singleClick | (true/false) wether the calendar is in single click mode or not (default: true) - * mondayFirst | (true/false) if true Monday is the first day of week, Sunday otherwise (default: false) + * mondayFirst | (true/false) if true Monday is the first day of week, Sunday otherwise (default: true) * align | alignment (default: "Bl"); if you don't know what's this see the calendar documentation * range | array with 2 elements. Default: [1900, 2999] -- the range of years available * weekNumbers | (true/false) if it's true (default) the calendar will display week numbers * flat | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID * flatCallback | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar) * disableFunc | function that receives a JS Date object and should return true if that date has to be disabled in the calendar + * onSelect | function that gets called when a date is selected. You don't _have_ to supply this (the default is generally okay) + * onClose | function that gets called when the calendar is closed. [default] + * onUpdate | function that gets called after the date is updated in the input field. Receives a reference to the calendar. + * date | the date that the calendar will be initially displayed to + * showsTime | default: false; if true the calendar will include a time selector + * timeFormat | the time format; can be "12" or "24", default is "12" * * None of them is required, they all have default values. However, if you * pass none of "inputField", "displayArea" or "button" you'll get a warning @@ -46,20 +57,27 @@ Calendar.setup = function (params) { function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } }; - param_default("inputField", null); - param_default("displayArea", null); - param_default("button", null); - param_default("eventName", "click"); - param_default("ifFormat", "y/mm/dd"); - param_default("daFormat", "y/mm/dd"); - param_default("singleClick", true); - param_default("disableFunc", null); - param_default("mondayFirst", false); - param_default("align", "Bl"); - param_default("range", [1900, 2999]); - param_default("weekNumbers", true); - param_default("flat", null); - param_default("flatCallback", null); + param_default("inputField", null); + param_default("displayArea", null); + param_default("button", null); + param_default("eventName", "click"); + param_default("ifFormat", "%Y/%m/%d"); + param_default("daFormat", "%Y/%m/%d"); + param_default("singleClick", true); + param_default("disableFunc", null); + param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined + param_default("mondayFirst", true); + param_default("align", "Bl"); + param_default("range", [1900, 2999]); + param_default("weekNumbers", true); + param_default("flat", null); + param_default("flatCallback", null); + param_default("onSelect", null); + param_default("onClose", null); + param_default("onUpdate", null); + param_default("date", null); + param_default("showsTime", false); + param_default("timeFormat", "24"); var tmp = ["inputField", "displayArea", "button"]; for (var i in tmp) { @@ -90,6 +108,9 @@ Calendar.setup = function (params) { if (cal.params.singleClick && cal.dateClicked) { cal.callCloseHandler(); } + if (typeof cal.params.onUpdate == "function") { + cal.params.onUpdate(cal); + } }; if (params.flat != null) { @@ -98,11 +119,13 @@ Calendar.setup = function (params) { alert("Calendar.setup:\n Flat specified but can't find parent."); return false; } - var cal = new Calendar(params.mondayFirst, null, onSelect); + var cal = new Calendar(params.mondayFirst, params.date, params.onSelect || onSelect); + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); cal.params = params; cal.weekNumbers = params.weekNumbers; cal.setRange(params.range[0], params.range[1]); - cal.setDisabledHandler(params.disableFunc); + cal.setDateStatusHandler(params.dateStatusFunc); cal.create(params.flat); cal.show(); return false; @@ -113,23 +136,28 @@ Calendar.setup = function (params) { var dateEl = params.inputField || params.displayArea; var dateFmt = params.inputField ? params.ifFormat : params.daFormat; var mustCreate = false; + var cal = window.calendar; if (!window.calendar) { - window.calendar = new Calendar(params.mondayFirst, null, onSelect, function(cal) { cal.hide(); }); - window.calendar.weekNumbers = params.weekNumbers; + window.calendar = cal = new Calendar(params.mondayFirst, + params.date, + params.onSelect || onSelect, + params.onClose || function(cal) { cal.hide(); }); + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); + cal.weekNumbers = params.weekNumbers; mustCreate = true; } else { - window.calendar.hide(); + cal.hide(); } - window.calendar.setRange(params.range[0], params.range[1]); - window.calendar.params = params; - window.calendar.setDisabledHandler(params.disableFunc); - window.calendar.setDateFormat(dateFmt); - if (mustCreate) { - window.calendar.create(); - } - window.calendar.parseDate(dateEl.value || dateEl.innerHTML); - window.calendar.refresh(); - window.calendar.showAtElement(params.displayArea || params.inputField, params.align); + cal.setRange(params.range[0], params.range[1]); + cal.params = params; + cal.setDateStatusHandler(params.dateStatusFunc); + cal.setDateFormat(dateFmt); + if (mustCreate) + cal.create(); + cal.parseDate(dateEl.value || dateEl.innerHTML); + cal.refresh(); + cal.showAtElement(params.displayArea || params.inputField, params.align); return false; }; }; diff --git a/phpgwapi/js/jscalendar/calendar-setup_stripped.js b/phpgwapi/js/jscalendar/calendar-setup_stripped.js index 7a89ddd3e8..8d3aabe6d4 100644 --- a/phpgwapi/js/jscalendar/calendar-setup_stripped.js +++ b/phpgwapi/js/jscalendar/calendar-setup_stripped.js @@ -1,16 +1,21 @@ -/* Copyright Mihai Bazon, 2002, 2003 | http://students.infoiasi.ro/~mishoo +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ * --------------------------------------------------------------------------- * * The DHTML Calendar * * Details and latest version at: - * http://students.infoiasi.ro/~mishoo/site/calendar.epl + * http://dynarch.com/mishoo/calendar.epl * - * Feel free to use this script under the terms of the GNU Lesser General - * Public License, as long as you do not remove or alter this notice. + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html * * This file defines helper functions for setting up the calendar. They are * intended to help non-programmers get a working calendar on their site - * quickly. + * quickly. This script should not be seen as part of the calendar. It just + * shows you what one can do with the calendar, while in the same time + * providing a quick and simple method for setting it up. If you need + * exhaustive customization of the calendar creation process feel free to + * modify this code to suit your needs (this is recommended and much better + * than modifying calendar.js itself). */ -Calendar.setup=function(params){function param_default(pname,def){if(typeof params[pname]=="undefined"){params[pname]=def;}};param_default("inputField",null);param_default("displayArea",null);param_default("button",null);param_default("eventName","click");param_default("ifFormat","y/mm/dd");param_default("daFormat","y/mm/dd");param_default("singleClick",true);param_default("disableFunc",null);param_default("mondayFirst",false);param_default("align","Bl");param_default("range",[1900,2999]);param_default("weekNumbers",true);param_default("flat",null);param_default("flatCallback",null);var tmp=["inputField","displayArea","button"];for(var i in tmp){if(typeof params[tmp[i]]=="string"){params[tmp[i]]=document.getElementById(params[tmp[i]]);}}if(!(params.flat||params.inputField||params.displayArea||params.button)){alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code");return false;}function onSelect(cal){if(cal.params.flat){if(typeof cal.params.flatCallback=="function"){cal.params.flatCallback(cal);}else{alert("No flatCallback given -- doing nothing.");}return false;}if(cal.params.inputField){cal.params.inputField.value=cal.date.print(cal.params.ifFormat);}if(cal.params.displayArea){cal.params.displayArea.innerHTML=cal.date.print(cal.params.daFormat);}if(cal.params.singleClick&&cal.dateClicked){cal.callCloseHandler();}};if(params.flat!=null){params.flat=document.getElementById(params.flat);if(!params.flat){alert("Calendar.setup:\n Flat specified but can't find parent.");return false;}var cal=new Calendar(params.mondayFirst,null,onSelect);cal.params=params;cal.weekNumbers=params.weekNumbers;cal.setRange(params.range[0],params.range[1]);cal.setDisabledHandler(params.disableFunc);cal.create(params.flat);cal.show();return false;}var triggerEl=params.button||params.displayArea||params.inputField;triggerEl["on"+params.eventName]=function(){var dateEl=params.inputField||params.displayArea;var dateFmt=params.inputField?params.ifFormat:params.daFormat;var mustCreate=false;if(!window.calendar){window.calendar=new Calendar(params.mondayFirst,null,onSelect,function(cal){cal.hide();});window.calendar.weekNumbers=params.weekNumbers;mustCreate=true;}else{window.calendar.hide();}window.calendar.setRange(params.range[0],params.range[1]);window.calendar.params=params;window.calendar.setDisabledHandler(params.disableFunc);window.calendar.setDateFormat(dateFmt);if(mustCreate){window.calendar.create();}window.calendar.parseDate(dateEl.value||dateEl.innerHTML);window.calendar.refresh();window.calendar.showAtElement(params.displayArea||params.inputField,params.align);return false;};}; \ No newline at end of file + Calendar.setup=function(params){function param_default(pname,def){if(typeof params[pname]=="undefined"){params[pname]=def;}};param_default("inputField",null);param_default("displayArea",null);param_default("button",null);param_default("eventName","click");param_default("ifFormat","%Y/%m/%d");param_default("daFormat","%Y/%m/%d");param_default("singleClick",true);param_default("disableFunc",null);param_default("dateStatusFunc",params["disableFunc"]);param_default("mondayFirst",true);param_default("align","Bl");param_default("range",[1900,2999]);param_default("weekNumbers",true);param_default("flat",null);param_default("flatCallback",null);param_default("onSelect",null);param_default("onClose",null);param_default("onUpdate",null);param_default("date",null);param_default("showsTime",false);param_default("timeFormat","24");var tmp=["inputField","displayArea","button"];for(var i in tmp){if(typeof params[tmp[i]]=="string"){params[tmp[i]]=document.getElementById(params[tmp[i]]);}}if(!(params.flat||params.inputField||params.displayArea||params.button)){alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code");return false;}function onSelect(cal){if(cal.params.flat){if(typeof cal.params.flatCallback=="function"){cal.params.flatCallback(cal);}else{alert("No flatCallback given -- doing nothing.");}return false;}if(cal.params.inputField){cal.params.inputField.value=cal.date.print(cal.params.ifFormat);}if(cal.params.displayArea){cal.params.displayArea.innerHTML=cal.date.print(cal.params.daFormat);}if(cal.params.singleClick&&cal.dateClicked){cal.callCloseHandler();}if(typeof cal.params.onUpdate=="function"){cal.params.onUpdate(cal);}};if(params.flat!=null){params.flat=document.getElementById(params.flat);if(!params.flat){alert("Calendar.setup:\n Flat specified but can't find parent.");return false;}var cal=new Calendar(params.mondayFirst,params.date,params.onSelect||onSelect);cal.showsTime=params.showsTime;cal.time24=(params.timeFormat=="24");cal.params=params;cal.weekNumbers=params.weekNumbers;cal.setRange(params.range[0],params.range[1]);cal.setDateStatusHandler(params.dateStatusFunc);cal.create(params.flat);cal.show();return false;}var triggerEl=params.button||params.displayArea||params.inputField;triggerEl["on"+params.eventName]=function(){var dateEl=params.inputField||params.displayArea;var dateFmt=params.inputField?params.ifFormat:params.daFormat;var mustCreate=false;var cal=window.calendar;if(!window.calendar){window.calendar=cal=new Calendar(params.mondayFirst,params.date,params.onSelect||onSelect,params.onClose||function(cal){cal.hide();});cal.showsTime=params.showsTime;cal.time24=(params.timeFormat=="24");cal.weekNumbers=params.weekNumbers;mustCreate=true;}else{cal.hide();}cal.setRange(params.range[0],params.range[1]);cal.params=params;cal.setDateStatusHandler(params.dateStatusFunc);cal.setDateFormat(dateFmt);if(mustCreate)cal.create();cal.parseDate(dateEl.value||dateEl.innerHTML);cal.refresh();cal.showAtElement(params.displayArea||params.inputField,params.align);return false;};}; \ No newline at end of file diff --git a/phpgwapi/js/jscalendar/calendar-system.css b/phpgwapi/js/jscalendar/calendar-system.css index 34db1f62af..3bc1b1c983 100644 --- a/phpgwapi/js/jscalendar/calendar-system.css +++ b/phpgwapi/js/jscalendar/calendar-system.css @@ -32,6 +32,10 @@ background: ButtonFace; } +.calendar .nav { + background: ButtonFace url(menuarrow.gif) no-repeat 100% 100%; +} + .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; padding: 1px; @@ -60,8 +64,9 @@ } .calendar thead .hilite { /* How do the buttons in header appear when hover */ - border-width: 2px; + border: 2px solid; padding: 0px; + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; } .calendar thead .active { /* Active (pressed) buttons in header */ @@ -86,8 +91,8 @@ } .calendar tbody .rowhilite td { - background: #eee; - color: #000; + background: Highlight; + color: HighlightText; } .calendar tbody td.hilite { /* Hovered cells */ @@ -109,6 +114,8 @@ border: 1px solid; border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; padding: 2px 2px 0px 2px; + background: ButtonFace; + color: ButtonText; } .calendar tbody td.weekend { /* Cells showing weekend days */ @@ -178,11 +185,16 @@ padding: 1px; } -.combo .label { +.combo .label, +.combo .label-IEfix { text-align: center; padding: 1px; } +.combo .label-IEfix { + width: 4em; +} + .combo .active { padding: 0px; border: 1px solid #000; @@ -192,3 +204,40 @@ background: Highlight; color: HighlightText; } + +.calendar td.time { + border-top: 1px solid ButtonShadow; + padding: 1px 0px; + text-align: center; + background-color: ButtonFace; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: Menu; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: Highlight; + color: HighlightText; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/phpgwapi/js/jscalendar/calendar-win2k-1.css b/phpgwapi/js/jscalendar/calendar-win2k-1.css index 7521c66534..bbc98c85f0 100644 --- a/phpgwapi/js/jscalendar/calendar-win2k-1.css +++ b/phpgwapi/js/jscalendar/calendar-win2k-1.css @@ -37,6 +37,10 @@ border-left: 1px solid #fff; } +.calendar .nav { + background: transparent url(menuarrow.gif) no-repeat 100% 100%; +} + .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; padding: 1px; @@ -69,7 +73,7 @@ border-bottom: 2px solid #000; border-left: 2px solid #fff; padding: 0px; - background: #e4e0d8; + background-color: #e4e0d8; } .calendar thead .active { /* Active (pressed) buttons in header */ @@ -78,7 +82,7 @@ border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; - background: #c4c0b8; + background-color: #c4c0b8; } /* The body part -- contains all the days in month. */ @@ -197,11 +201,16 @@ padding: 1px; } -.combo .label { +.combo .label, +.combo .label-IEfix { text-align: center; padding: 1px; } +.combo .label-IEfix { + width: 4em; +} + .combo .active { background: #c4c0b8; padding: 0px; @@ -215,3 +224,40 @@ background: #048; color: #fea; } + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #f4f0e8; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #766; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/phpgwapi/js/jscalendar/calendar-win2k-2.css b/phpgwapi/js/jscalendar/calendar-win2k-2.css index 398e78efec..9727d1b9a9 100644 --- a/phpgwapi/js/jscalendar/calendar-win2k-2.css +++ b/phpgwapi/js/jscalendar/calendar-win2k-2.css @@ -37,6 +37,10 @@ border-left: 1px solid #fff; } +.calendar .nav { + background: transparent url(menuarrow.gif) no-repeat 100% 100%; +} + .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; padding: 1px; @@ -69,7 +73,7 @@ border-bottom: 2px solid #000; border-left: 2px solid #fff; padding: 0px; - background: #e4d8e0; + background-color: #e4d8e0; } .calendar thead .active { /* Active (pressed) buttons in header */ @@ -78,7 +82,7 @@ border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; - background: #c4b8c0; + background-color: #c4b8c0; } /* The body part -- contains all the days in month. */ @@ -197,11 +201,16 @@ padding: 1px; } -.combo .label { +.combo .label, +.combo .label-IEfix { text-align: center; padding: 1px; } +.combo .label-IEfix { + width: 4em; +} + .combo .active { background: #d4c8d0; padding: 0px; @@ -215,3 +224,40 @@ background: #408; color: #fea; } + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #f4f0e8; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #766; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/phpgwapi/js/jscalendar/calendar-win2k-cold-1.css b/phpgwapi/js/jscalendar/calendar-win2k-cold-1.css index f12852e8ec..f3ca5e0d52 100644 --- a/phpgwapi/js/jscalendar/calendar-win2k-cold-1.css +++ b/phpgwapi/js/jscalendar/calendar-win2k-cold-1.css @@ -37,6 +37,10 @@ border-left: 1px solid #fff; } +.calendar .nav { + background: transparent url(menuarrow.gif) no-repeat 100% 100%; +} + .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; padding: 1px; @@ -69,7 +73,7 @@ border-bottom: 2px solid #000; border-left: 2px solid #fff; padding: 0px; - background: #d8e0e4; + background-color: #d8e0e4; } .calendar thead .active { /* Active (pressed) buttons in header */ @@ -78,7 +82,7 @@ border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; - background: #b8c0c4; + background-color: #b8c0c4; } /* The body part -- contains all the days in month. */ @@ -191,11 +195,16 @@ padding: 1px; } -.combo .label { +.combo .label, +.combo .label-IEfix { text-align: center; padding: 1px; } +.combo .label-IEfix { + width: 4em; +} + .combo .active { background: #c8d0d4; padding: 0px; @@ -209,3 +218,40 @@ background: #048; color: #aef; } + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #e8f0f4; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #667; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/phpgwapi/js/jscalendar/calendar-win2k-cold-2.css b/phpgwapi/js/jscalendar/calendar-win2k-cold-2.css index a8ca89e3bb..b757ea66e1 100644 --- a/phpgwapi/js/jscalendar/calendar-win2k-cold-2.css +++ b/phpgwapi/js/jscalendar/calendar-win2k-cold-2.css @@ -37,6 +37,10 @@ border-left: 1px solid #fff; } +.calendar .nav { + background: transparent url(menuarrow.gif) no-repeat 100% 100%; +} + .calendar thead .title { /* This holds the current "month, year" */ font-weight: bold; padding: 1px; @@ -69,7 +73,7 @@ border-bottom: 2px solid #000; border-left: 2px solid #fff; padding: 0px; - background: #d8e4e0; + background-color: #d8e4e0; } .calendar thead .active { /* Active (pressed) buttons in header */ @@ -78,7 +82,7 @@ border-right: 1px solid #fff; border-bottom: 1px solid #fff; border-left: 1px solid #000; - background: #b8c4c0; + background-color: #b8c4c0; } /* The body part -- contains all the days in month. */ @@ -197,11 +201,16 @@ padding: 1px; } -.combo .label { +.combo .label, +.combo .label-IEfix { text-align: center; padding: 1px; } +.combo .label-IEfix { + width: 4em; +} + .combo .active { background: #c8d4d0; padding: 0px; @@ -215,3 +224,40 @@ background: #048; color: #aef; } + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #e8f0f4; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #667; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/phpgwapi/js/jscalendar/calendar.js b/phpgwapi/js/jscalendar/calendar.js index ceaf185f61..dde8b00caa 100644 --- a/phpgwapi/js/jscalendar/calendar.js +++ b/phpgwapi/js/jscalendar/calendar.js @@ -1,13 +1,13 @@ -/* Copyright Mihai Bazon, 2002, 2003 | http://students.infoiasi.ro/~mishoo - * --------------------------------------------------------------------------- +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ + * ------------------------------------------------------------------ * - * The DHTML Calendar, version 0.9.3 "It's still alive & keeps rocking" + * The DHTML Calendar, version 0.9.5 "Your favorite time, bis" * * Details and latest version at: - * http://students.infoiasi.ro/~mishoo/site/calendar.epl + * http://dynarch.com/mishoo/calendar.epl * - * Feel free to use this script under the terms of the GNU Lesser General - * Public License, as long as you do not remove or alter this notice. + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html */ // $Id$ @@ -17,7 +17,7 @@ Calendar = function (mondayFirst, dateStr, onSelected, onClose) { // member variables this.activeDiv = null; this.currentDateEl = null; - this.checkDisabled = null; + this.getDateStatus = null; this.timeout = null; this.onSelected = onSelected || null; this.onClose = onClose || null; @@ -32,6 +32,8 @@ Calendar = function (mondayFirst, dateStr, onSelected, onClose) { this.mondayFirst = mondayFirst; this.dateStr = dateStr; this.ar_days = null; + this.showsTime = false; + this.time24 = true; // HTML elements this.table = null; this.element = null; @@ -48,19 +50,23 @@ Calendar = function (mondayFirst, dateStr, onSelected, onClose) { this.dateClicked = false; // one-time initializations - if (!Calendar._DN3) { + if (typeof Calendar._SDN == "undefined") { // table of short day names + if (typeof Calendar._SDN_len == "undefined") + Calendar._SDN_len = 3; var ar = new Array(); for (var i = 8; i > 0;) { - ar[--i] = Calendar._DN[i].substr(0, 3); + ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len); } - Calendar._DN3 = ar; + Calendar._SDN = ar; // table of short month names + if (typeof Calendar._SMN_len == "undefined") + Calendar._SMN_len = 3; ar = new Array(); for (var i = 12; i > 0;) { - ar[--i] = Calendar._MN[i].substr(0, 3); + ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len); } - Calendar._MN3 = ar; + Calendar._SMN = ar; } }; @@ -73,17 +79,23 @@ Calendar._C = null; Calendar.is_ie = ( /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent) ); -// short day names array (initialized at first constructor call) -Calendar._DN3 = null; +/// detect Opera browser +Calendar.is_opera = /opera/i.test(navigator.userAgent); -// short month names array (initialized at first constructor call) -Calendar._MN3 = null; +/// detect KHTML-based browsers +Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent); // BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate // library, at some point. Calendar.getAbsolutePos = function(el) { - var r = { x: el.offsetLeft, y: el.offsetTop }; + var SL = 0, ST = 0; + var is_div = /^div$/i.test(el.tagName); + if (is_div && el.scrollLeft) + SL = el.scrollLeft; + if (is_div && el.scrollTop) + ST = el.scrollTop; + var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST }; if (el.offsetParent) { var tmp = Calendar.getAbsolutePos(el.offsetParent); r.x += tmp.x; @@ -147,9 +159,10 @@ Calendar.getTargetElement = function(ev) { }; Calendar.stopEvent = function(ev) { + ev || (ev = window.event); if (Calendar.is_ie) { - window.event.cancelBubble = true; - window.event.returnValue = false; + ev.cancelBubble = true; + ev.returnValue = false; } else { ev.preventDefault(); ev.stopPropagation(); @@ -162,7 +175,7 @@ Calendar.addEvent = function(el, evname, func) { el.attachEvent("on" + evname, func); } else if (el.addEventListener) { // Gecko / W3C el.addEventListener(evname, func, true); - } else { // Opera (or old browsers) + } else { el["on" + evname] = func; } }; @@ -172,7 +185,7 @@ Calendar.removeEvent = function(el, evname, func) { el.detachEvent("on" + evname, func); } else if (el.removeEventListener) { // Gecko / W3C el.removeEventListener(evname, func, true); - } else { // Opera (or old browsers) + } else { el["on" + evname] = null; } }; @@ -244,9 +257,13 @@ Calendar.showMonthsCombo = function () { var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()]; Calendar.addClass(mon, "active"); cal.activeMonth = mon; - mc.style.left = cd.offsetLeft + "px"; - mc.style.top = (cd.offsetTop + cd.offsetHeight) + "px"; - mc.style.display = "block"; + var s = mc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else + s.left = (cd.offsetLeft + cd.offsetWidth - mc.offsetWidth) + "px"; + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; }; Calendar.showYearsCombo = function (fwd) { @@ -280,9 +297,13 @@ Calendar.showYearsCombo = function (fwd) { Y += fwd ? 2 : -2; } if (show) { - yc.style.left = cd.offsetLeft + "px"; - yc.style.top = (cd.offsetTop + cd.offsetHeight) + "px"; - yc.style.display = "block"; + var s = yc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else + s.left = (cd.offsetLeft + cd.offsetWidth - yc.offsetWidth) + "px"; + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; } }; @@ -301,9 +322,10 @@ Calendar.tableMouseUp = function(ev) { return false; } var target = Calendar.getTargetElement(ev); + ev || (ev = window.event); Calendar.removeClass(el, "active"); if (target == el || target.parentNode == el) { - Calendar.cellClick(el); + Calendar.cellClick(el, ev); } var mon = Calendar.findMonth(target); var date = null; @@ -348,10 +370,42 @@ Calendar.tableMouseOver = function (ev) { Calendar.addClass(el, "hilite active"); Calendar.addClass(el.parentNode, "rowhilite"); } else { - Calendar.removeClass(el, "active"); + if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2))) + Calendar.removeClass(el, "active"); Calendar.removeClass(el, "hilite"); Calendar.removeClass(el.parentNode, "rowhilite"); } + ev || (ev = window.event); + if (el.navtype == 50 && target != el) { + var pos = Calendar.getAbsolutePos(el); + var w = el.offsetWidth; + var x = ev.clientX; + var dx; + var decrease = true; + if (x > pos.x + w) { + dx = x - pos.x - w; + decrease = false; + } else + dx = pos.x - x; + + if (dx < 0) dx = 0; + var range = el._range; + var current = el._current; + var count = Math.floor(dx / 10) % range.length; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + while (count-- > 0) + if (decrease) { + if (!(--i in range)) + i = range.length - 1; + } else if (!(++i in range)) + i = 0; + var newval = range[i]; + el.firstChild.data = newval; + + cal.onUpdateTime(); + } var mon = Calendar.findMonth(target); if (mon) { if (mon.month != cal.date.getMonth()) { @@ -364,6 +418,9 @@ Calendar.tableMouseOver = function (ev) { Calendar.removeClass(cal.hilitedMonth, "hilite"); } } else { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } var year = Calendar.findYear(target); if (year) { if (year.year != cal.date.getFullYear()) { @@ -375,6 +432,8 @@ Calendar.tableMouseOver = function (ev) { } else if (cal.hilitedYear) { Calendar.removeClass(cal.hilitedYear, "hilite"); } + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); } } return Calendar.stopEvent(ev); @@ -431,6 +490,8 @@ Calendar.dayMouseDown = function(ev) { cal.activeDiv = el; Calendar._C = cal; if (el.navtype != 300) with (Calendar) { + if (el.navtype == 50) + el._current = el.firstChild.data; addClass(el, "hilite active"); addEvent(document, "mouseover", tableMouseOver); addEvent(document, "mousemove", tableMouseOver); @@ -439,8 +500,10 @@ Calendar.dayMouseDown = function(ev) { cal._dragStart(ev); } if (el.navtype == -1 || el.navtype == 1) { + if (cal.timeout) clearTimeout(cal.timeout); cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250); } else if (el.navtype == -2 || el.navtype == 2) { + if (cal.timeout) clearTimeout(cal.timeout); cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250); } else { cal.timeout = null; @@ -449,7 +512,7 @@ Calendar.dayMouseDown = function(ev) { }; Calendar.dayMouseDblClick = function(ev) { - Calendar.cellClick(Calendar.getElement(ev)); + Calendar.cellClick(Calendar.getElement(ev), ev || window.event); if (Calendar.is_ie) { document.selection.empty(); } @@ -498,7 +561,7 @@ Calendar.dayMouseOut = function(ev) { * A generic "click" handler :) handles all types of buttons defined in this * calendar. */ -Calendar.cellClick = function(el) { +Calendar.cellClick = function(el, ev) { var cal = el.calendar; var closing = false; var newdate = false; @@ -525,7 +588,8 @@ Calendar.cellClick = function(el) { // unless "today" was clicked, we assume no date was clicked so // the selected handler will know not to close the calenar when // in single-click mode. - cal.dateClicked = (el.navtype == 0); + // cal.dateClicked = (el.navtype == 0); + cal.dateClicked = false; var year = date.getFullYear(); var mon = date.getMonth(); function setMonth(m) { @@ -537,6 +601,22 @@ Calendar.cellClick = function(el) { date.setMonth(m); }; switch (el.navtype) { + case 400: + Calendar.removeClass(el, "hilite"); + var text = Calendar._TT["ABOUT"]; + if (typeof text != "undefined") { + text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : ""; + } else { + // FIXME: this should be removed as soon as lang files get updated! + text = "Help and about box text is not translated into this language.\n" + + "If you know this language and you feel generous please update\n" + + "the corresponding file in \"lang\" subdir to match calendar-en.js\n" + + "and send it back to to get it into the distribution ;-)\n\n" + + "Thank you!\n" + + "http://dynarch.com/mishoo/calendar.epl\n"; + } + alert(text); + return; case -2: if (year > cal.minYear) { date.setFullYear(year - 1); @@ -566,9 +646,24 @@ Calendar.cellClick = function(el) { case 100: cal.setMondayFirst(!cal.mondayFirst); return; + case 50: + var range = el._range; + var current = el.firstChild.data; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + if (ev && ev.shiftKey) { + if (!(--i in range)) + i = range.length - 1; + } else if (!(++i in range)) + i = 0; + var newval = range[i]; + el.firstChild.data = newval; + cal.onUpdateTime(); + return; case 0: // TODAY will bring us here - if ((typeof cal.checkDisabled == "function") && cal.checkDisabled(date)) { + if ((typeof cal.getDateStatus == "function") && cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) { // remember, "date" was previously set to new // Date() if TODAY was clicked; thus, it // contains today date. @@ -638,6 +733,8 @@ Calendar.prototype.create = function (_par) { cell = Calendar.createElement("td", row); cell.colSpan = cs; cell.className = "button"; + if (navtype != 0 && Math.abs(navtype) <= 2) + cell.className += " nav"; Calendar._add_evs(cell); cell.calendar = cal; cell.navtype = navtype; @@ -656,7 +753,7 @@ Calendar.prototype.create = function (_par) { (this.isPopup) && --title_length; (this.weekNumbers) && ++title_length; - hh("-", 1, 100).ttip = Calendar._TT["TOGGLE"]; + hh("?", 1, 400).ttip = Calendar._TT["INFO"]; this.title = hh("", title_length, 300); this.title.className = "title"; if (this.isPopup) { @@ -720,6 +817,96 @@ Calendar.prototype.create = function (_par) { } } + if (this.showsTime) { + row = Calendar.createElement("tr", tbody); + row.className = "time"; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + cell.innerHTML = " "; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = this.weekNumbers ? 4 : 3; + + (function(){ + function makeTimePart(className, init, range_start, range_end) { + var part = Calendar.createElement("span", cell); + part.className = className; + part.appendChild(document.createTextNode(init)); + part.calendar = cal; + part.ttip = Calendar._TT["TIME_PART"]; + part.navtype = 50; + part._range = []; + if (typeof range_start != "number") + part._range = range_start; + else { + for (var i = range_start; i <= range_end; ++i) { + var txt; + if (i < 10 && range_end >= 10) txt = '0' + i; + else txt = '' + i; + part._range[part._range.length] = txt; + } + } + Calendar._add_evs(part); + return part; + }; + var hrs = cal.date.getHours(); + var mins = cal.date.getMinutes(); + var t12 = !cal.time24; + var pm = (hrs > 12); + if (t12 && pm) hrs -= 12; + var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23); + var span = Calendar.createElement("span", cell); + span.appendChild(document.createTextNode(":")); + span.className = "colon"; + var M = makeTimePart("minute", mins, 0, 59); + var AP = null; + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + if (t12) + AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]); + else + cell.innerHTML = " "; + + cal.onSetTime = function() { + var hrs = this.date.getHours(); + var mins = this.date.getMinutes(); + var pm = (hrs > 12); + if (pm && t12) hrs -= 12; + H.firstChild.data = (hrs < 10) ? ("0" + hrs) : hrs; + M.firstChild.data = (mins < 10) ? ("0" + mins) : mins; + if (t12) + AP.firstChild.data = pm ? "pm" : "am"; + }; + + cal.onUpdateTime = function() { + var date = this.date; + var h = parseInt(H.firstChild.data, 10); + if (t12) { + if (/pm/i.test(AP.firstChild.data) && h < 12) + h += 12; + else if (/am/i.test(AP.firstChild.data) && h == 12) + h = 0; + } + var d = date.getDate(); + var m = date.getMonth(); + var y = date.getFullYear(); + date.setHours(h); + date.setMinutes(parseInt(M.firstChild.data, 10)); + date.setFullYear(y); + date.setMonth(m); + date.setDate(d); + this.dateClicked = false; + this.callHandler(); + }; + })(); + } else { + this.onSetTime = this.onUpdateTime = function() {}; + } + var tfoot = Calendar.createElement("tfoot", table); row = Calendar.createElement("tr", tfoot); @@ -738,9 +925,9 @@ Calendar.prototype.create = function (_par) { div.className = "combo"; for (i = 0; i < Calendar._MN.length; ++i) { var mn = Calendar.createElement("div"); - mn.className = "label"; + mn.className = Calendar.is_ie ? "label-IEfix" : "label"; mn.month = i; - mn.appendChild(document.createTextNode(Calendar._MN3[i])); + mn.appendChild(document.createTextNode(Calendar._SMN[i])); div.appendChild(mn); } @@ -749,7 +936,7 @@ Calendar.prototype.create = function (_par) { div.className = "combo"; for (i = 12; i > 0; --i) { var yr = Calendar.createElement("div"); - yr.className = "label"; + yr.className = Calendar.is_ie ? "label-IEfix" : "label"; yr.appendChild(document.createTextNode("")); div.appendChild(yr); } @@ -874,7 +1061,7 @@ Calendar.prototype._init = function (mondayFirst, date) { } var iday = 1; var row = this.tbody.firstChild; - var MN = Calendar._MN3[month]; + var MN = Calendar._SMN[month]; var hasToday = ((today.getFullYear() == year) && (today.getMonth() == month)); var todayDate = today.getDate(); var week_number = date.getWeekNumber(); @@ -904,11 +1091,16 @@ Calendar.prototype._init = function (mondayFirst, date) { } cell.disabled = false; cell.firstChild.data = iday; - if (typeof this.checkDisabled == "function") { + if (typeof this.getDateStatus == "function") { date.setDate(iday); - if (this.checkDisabled(date)) { + var status = this.getDateStatus(date, year, month, iday); + if (status === true) { cell.className += " disabled"; cell.disabled = true; + } else { + if (/disabled/i.test(status)) + cell.disabled = true; + cell.className += " " + status; } } if (!cell.disabled) { @@ -935,6 +1127,7 @@ Calendar.prototype._init = function (mondayFirst, date) { } this.ar_days = ar_days; this.title.firstChild.data = Calendar._MN[month] + ", " + year; + this.onSetTime(); // PROFILE // this.tooltips.firstChild.data = "Generated in " + ((new Date()) - today) + " ms"; }; @@ -971,8 +1164,8 @@ Calendar.prototype.setMondayFirst = function (mondayFirst) { * object) and returns a boolean value. If the returned value is true then * the passed date will be marked as disabled. */ -Calendar.prototype.setDisabledHandler = function (unaryFunction) { - this.checkDisabled = unaryFunction; +Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) { + this.getDateStatus = unaryFunction; }; /** Customization of allowed year range for the calendar. */ @@ -1001,6 +1194,7 @@ Calendar.prototype.destroy = function () { var el = this.element.parentNode; el.removeChild(this.element); Calendar._C = null; + window.calendar = null; }; /** @@ -1082,37 +1276,44 @@ Calendar.prototype.showAt = function (x, y) { /** Shows the calendar near a given element. */ Calendar.prototype.showAtElement = function (el, opts) { + var self = this; var p = Calendar.getAbsolutePos(el); if (!opts || typeof opts != "string") { this.showAt(p.x, p.y + el.offsetHeight); return true; } - this.show(); - var w = this.element.offsetWidth; - var h = this.element.offsetHeight; - this.hide(); - var valign = opts.substr(0, 1); - var halign = "l"; - if (opts.length > 1) { - halign = opts.substr(1, 1); - } - // vertical alignment - switch (valign) { - case "T": p.y -= h; break; - case "B": p.y += el.offsetHeight; break; - case "C": p.y += (el.offsetHeight - h) / 2; break; - case "t": p.y += el.offsetHeight - h; break; - case "b": break; // already there - } - // horizontal alignment - switch (halign) { - case "L": p.x -= w; break; - case "R": p.x += el.offsetWidth; break; - case "C": p.x += (el.offsetWidth - w) / 2; break; - case "r": p.x += el.offsetWidth - w; break; - case "l": break; // already there - } - this.showAt(p.x, p.y); + this.element.style.display = "block"; + Calendar.continuation_for_the_fucking_khtml_browser = function() { + var w = self.element.offsetWidth; + var h = self.element.offsetHeight; + self.element.style.display = "none"; + var valign = opts.substr(0, 1); + var halign = "l"; + if (opts.length > 1) { + halign = opts.substr(1, 1); + } + // vertical alignment + switch (valign) { + case "T": p.y -= h; break; + case "B": p.y += el.offsetHeight; break; + case "C": p.y += (el.offsetHeight - h) / 2; break; + case "t": p.y += el.offsetHeight - h; break; + case "b": break; // already there + } + // horizontal alignment + switch (halign) { + case "L": p.x -= w; break; + case "R": p.x += el.offsetWidth; break; + case "C": p.x += (el.offsetWidth - w) / 2; break; + case "r": p.x += el.offsetWidth - w; break; + case "l": break; // already there + } + self.showAt(p.x, p.y); + }; + if (Calendar.is_khtml) + setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10); + else + Calendar.continuation_for_the_fucking_khtml_browser(); }; /** Customizes the date format. */ @@ -1137,30 +1338,42 @@ Calendar.prototype.parseDate = function (str, fmt) { if (!fmt) { fmt = this.dateFormat; } - var b = fmt.split(/\W+/); + var b = []; + fmt.replace(/(%.)/g, function(str, par) { + return b[b.length] = par; + }); var i = 0, j = 0; + var hr = 0; + var min = 0; for (i = 0; i < a.length; ++i) { - if (b[i] == "D" || b[i] == "DD") { + if (b[i] == "%a" || b[i] == "%A") { continue; } - if (b[i] == "d" || b[i] == "dd") { + if (b[i] == "%d" || b[i] == "%e") { d = parseInt(a[i], 10); } - if (b[i] == "m" || b[i] == "mm") { + if (b[i] == "%m") { m = parseInt(a[i], 10) - 1; } - if ((b[i] == "y") || (b[i] == "yy")) { + if (b[i] == "%Y" || b[i] == "%y") { y = parseInt(a[i], 10); (y < 100) && (y += (y > 29) ? 1900 : 2000); } - if (b[i] == "M" || b[i] == "MM") { + if (b[i] == "%b" || b[i] == "%B") { for (j = 0; j < 12; ++j) { if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; } } + } else if (/%[HIkl]/.test(b[i])) { + hr = parseInt(a[i], 10); + } else if (/%[pP]/.test(b[i])) { + if (/pm/i.test(a[i]) && hr < 12) + hr += 12; + } else if (b[i] == "%M") { + min = parseInt(a[i], 10); } } if (y != 0 && m != -1 && d != 0) { - this.setDate(new Date(y, m, d)); + this.setDate(new Date(y, m, d, hr, min, 0)); return; } y = 0; m = -1; d = 0; @@ -1190,61 +1403,70 @@ Calendar.prototype.parseDate = function (str, fmt) { y = today.getFullYear(); } if (m != -1 && d != 0) { - this.setDate(new Date(y, m, d)); + this.setDate(new Date(y, m, d, hr, min, 0)); } }; Calendar.prototype.hideShowCovered = function () { - function getStyleProp(obj, style){ - var value = obj.style[style]; - if (!value) { - if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C - value = document.defaultView. - getComputedStyle(obj, "").getPropertyValue(style); - } else if (obj.currentStyle) { // IE - value = obj.currentStyle[style]; - } else { - value = obj.style[style]; + var self = this; + Calendar.continuation_for_the_fucking_khtml_browser = function() { + function getVisib(obj){ + var value = obj.style.visibility; + if (!value) { + if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C + if (!Calendar.is_khtml) + value = document.defaultView. + getComputedStyle(obj, "").getPropertyValue("visibility"); + else + value = ''; + } else if (obj.currentStyle) { // IE + value = obj.currentStyle.visibility; + } else + value = ''; + } + return value; + }; + + var tags = new Array("applet", "iframe", "select"); + var el = self.element; + + var p = Calendar.getAbsolutePos(el); + var EX1 = p.x; + var EX2 = el.offsetWidth + EX1; + var EY1 = p.y; + var EY2 = el.offsetHeight + EY1; + + for (var k = tags.length; k > 0; ) { + var ar = document.getElementsByTagName(tags[--k]); + var cc = null; + + for (var i = ar.length; i > 0;) { + cc = ar[--i]; + + p = Calendar.getAbsolutePos(cc); + var CX1 = p.x; + var CX2 = cc.offsetWidth + CX1; + var CY1 = p.y; + var CY2 = cc.offsetHeight + CY1; + + if (self.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = cc.__msh_save_visibility; + } else { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = "hidden"; + } } } - return value; }; - - var tags = new Array("applet", "iframe", "select"); - var el = this.element; - - var p = Calendar.getAbsolutePos(el); - var EX1 = p.x; - var EX2 = el.offsetWidth + EX1; - var EY1 = p.y; - var EY2 = el.offsetHeight + EY1; - - for (var k = tags.length; k > 0; ) { - var ar = document.getElementsByTagName(tags[--k]); - var cc = null; - - for (var i = ar.length; i > 0;) { - cc = ar[--i]; - - p = Calendar.getAbsolutePos(cc); - var CX1 = p.x; - var CX2 = cc.offsetWidth + CX1; - var CY1 = p.y; - var CY2 = cc.offsetHeight + CY1; - - if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) { - if (!cc.__msh_save_visibility) { - cc.__msh_save_visibility = getStyleProp(cc, "visibility"); - } - cc.style.visibility = cc.__msh_save_visibility; - } else { - if (!cc.__msh_save_visibility) { - cc.__msh_save_visibility = getStyleProp(cc, "visibility"); - } - cc.style.visibility = "hidden"; - } - } - } + if (Calendar.is_khtml) + setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10); + else + Calendar.continuation_for_the_fucking_khtml_browser(); }; /** Internal function; it displays the bar with the names of the weekday. */ @@ -1264,7 +1486,7 @@ Calendar.prototype._displayWeekdays = function () { if (i == SUN || i == SAT) { Calendar.addClass(cell, "weekend"); } - cell.firstChild.data = Calendar._DN3[i + 1 - MON]; + cell.firstChild.data = Calendar._SDN[i + 1 - MON]; cell = cell.nextSibling; } }; @@ -1325,14 +1547,22 @@ Date.prototype.getMonthDays = function(month) { } }; -/** Returns the number of the week. The algorithm was "stolen" from PPK's - * website, hope it's correct :) http://www.xs4all.nl/~ppk/js/week.html */ +/** Returns the number of day in the year. */ +Date.prototype.getDayOfYear = function() { + var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var then = new Date(this.getFullYear(), 0, 1, 0, 0, 0); + var time = now - then; + return Math.floor(time / Date.DAY); +}; + +/** Returns the number of the week in year, as defined in ISO 8601. */ Date.prototype.getWeekNumber = function() { var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); var then = new Date(this.getFullYear(), 0, 1, 0, 0, 0); var time = now - then; - var day = then.getDay(); - (day > 3) && (day -= 4) || (day += 3); + var day = then.getDay(); // 0 means Sunday + if (day == 0) day = 7; + (day > 4) && (day -= 4) || (day += 3); return Math.round(((time / Date.DAY) + day) / 7); }; @@ -1340,37 +1570,69 @@ Date.prototype.getWeekNumber = function() { Date.prototype.equalsTo = function(date) { return ((this.getFullYear() == date.getFullYear()) && (this.getMonth() == date.getMonth()) && - (this.getDate() == date.getDate())); + (this.getDate() == date.getDate()) && + (this.getHours() == date.getHours()) && + (this.getMinutes() == date.getMinutes())); }; /** Prints the date in a string according to the given format. */ -Date.prototype.print = function (frm) { - var str = new String(frm); +Date.prototype.print = function (str) { var m = this.getMonth(); var d = this.getDate(); var y = this.getFullYear(); var wn = this.getWeekNumber(); var w = this.getDay(); - var s = new Array(); - s["d"] = d; - s["dd"] = (d < 10) ? ("0" + d) : d; - s["m"] = 1+m; - s["mm"] = (m < 9) ? ("0" + (1+m)) : (1+m); - s["y"] = y; - s["yy"] = new String(y).substr(2, 2); - s["w"] = wn; - s["ww"] = (wn < 10) ? ("0" + wn) : wn; - with (Calendar) { - s["D"] = _DN3[w]; - s["DD"] = _DN[w]; - s["M"] = _MN3[m]; - s["MM"] = _MN[m]; + var s = {}; + var hr = this.getHours(); + var pm = (hr >= 12); + var ir = (pm) ? (hr - 12) : hr; + var dy = this.getDayOfYear(); + if (ir == 0) + ir = 12; + var min = this.getMinutes(); + var sec = this.getSeconds(); + s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N] + s["%A"] = Calendar._DN[w]; // full weekday name + s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N] + s["%B"] = Calendar._MN[m]; // full month name + // FIXME: %c : preferred date and time representation for the current locale + s["%C"] = 1 + Math.floor(y / 100); // the century number + s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31) + s["%e"] = d; // the day of the month (range 1 to 31) + // FIXME: %D : american date style: %m/%d/%y + // FIXME: %E, %F, %G, %g, %h (man strftime) + s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format) + s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format) + s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366) + s["%k"] = hr; // hour, range 0 to 23 (24h format) + s["%l"] = ir; // hour, range 1 to 12 (12h format) + s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12 + s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59 + s["%n"] = "\n"; // a newline character + s["%p"] = pm ? "PM" : "AM"; + s["%P"] = pm ? "pm" : "am"; + // FIXME: %r : the time in am/pm notation %I:%M:%S %p + // FIXME: %R : the time in 24-hour notation %H:%M + s["%s"] = Math.floor(this.getTime() / 1000); + s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59 + s["%t"] = "\t"; // a tab character + // FIXME: %T : the time in 24-hour notation (%H:%M:%S) + s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn; + s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON) + s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN) + // FIXME: %x : preferred date representation for the current locale without the time + // FIXME: %X : preferred time representation for the current locale without the date + s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99) + s["%Y"] = y; // year with the century + s["%%"] = "%"; // a literal '%' character + var re = Date._msh_formatRegexp; + if (typeof re == "undefined") { + var tmp = ""; + for (var i in s) + tmp += tmp ? ("|" + i) : i; + Date._msh_formatRegexp = re = new RegExp("(" + tmp + ")", 'g'); } - var re = /(.*)(\W|^)(d|dd|m|mm|y|yy|MM|M|DD|D|w|ww)(\W|$)(.*)/; - while (re.exec(str) != null) { - str = RegExp.$1 + RegExp.$2 + s[RegExp.$3] + RegExp.$4 + RegExp.$5; - } - return str; + return str.replace(re, function(match, par) { return s[par]; }); }; // END: DATE OBJECT PATCHES diff --git a/phpgwapi/js/jscalendar/calendar_stripped.js b/phpgwapi/js/jscalendar/calendar_stripped.js index 38b9b9aad7..029496a749 100644 --- a/phpgwapi/js/jscalendar/calendar_stripped.js +++ b/phpgwapi/js/jscalendar/calendar_stripped.js @@ -1,12 +1,12 @@ -/* Copyright Mihai Bazon, 2002, 2003 | http://students.infoiasi.ro/~mishoo - * --------------------------------------------------------------------------- +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ + * ------------------------------------------------------------------ * - * The DHTML Calendar, version 0.9.3 "It's still alive & keeps rocking" + * The DHTML Calendar, version 0.9.5 "Your favorite time, bis" * * Details and latest version at: - * http://students.infoiasi.ro/~mishoo/site/calendar.epl + * http://dynarch.com/mishoo/calendar.epl * - * Feel free to use this script under the terms of the GNU Lesser General - * Public License, as long as you do not remove or alter this notice. + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html */ -Calendar=function(mondayFirst,dateStr,onSelected,onClose){this.activeDiv=null;this.currentDateEl=null;this.checkDisabled=null;this.timeout=null;this.onSelected=onSelected||null;this.onClose=onClose||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT["DEF_DATE_FORMAT"];this.ttDateFormat=Calendar._TT["TT_DATE_FORMAT"];this.isPopup=true;this.weekNumbers=true;this.mondayFirst=mondayFirst;this.dateStr=dateStr;this.ar_days=null;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(!Calendar._DN3){var ar=new Array();for(var i=8;i>0;){ar[--i]=Calendar._DN[i].substr(0,3);}Calendar._DN3=ar;ar=new Array();for(var i=12;i>0;){ar[--i]=Calendar._MN[i].substr(0,3);}Calendar._MN3=ar;}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar._DN3=null;Calendar._MN3=null;Calendar.getAbsolutePos=function(el){var r={x:el.offsetLeft,y:el.offsetTop};if(el.offsetParent){var tmp=Calendar.getAbsolutePos(el.offsetParent);r.x+=tmp.x;r.y+=tmp.y;}return r;};Calendar.isRelated=function(el,evt){var related=evt.relatedTarget;if(!related){var type=evt.type;if(type=="mouseover"){related=evt.fromElement;}else if(type=="mouseout"){related=evt.toElement;}}while(related){if(related==el){return true;}related=related.parentNode;}return false;};Calendar.removeClass=function(el,className){if(!(el&&el.className)){return;}var cls=el.className.split(" ");var ar=new Array();for(var i=cls.length;i>0;){if(cls[--i]!=className){ar[ar.length]=cls[i];}}el.className=ar.join(" ");};Calendar.addClass=function(el,className){Calendar.removeClass(el,className);el.className+=" "+className;};Calendar.getElement=function(ev){if(Calendar.is_ie){return window.event.srcElement;}else{return ev.currentTarget;}};Calendar.getTargetElement=function(ev){if(Calendar.is_ie){return window.event.srcElement;}else{return ev.target;}};Calendar.stopEvent=function(ev){if(Calendar.is_ie){window.event.cancelBubble=true;window.event.returnValue=false;}else{ev.preventDefault();ev.stopPropagation();}return false;};Calendar.addEvent=function(el,evname,func){if(el.attachEvent){el.attachEvent("on"+evname,func);}else if(el.addEventListener){el.addEventListener(evname,func,true);}else{el["on"+evname]=func;}};Calendar.removeEvent=function(el,evname,func){if(el.detachEvent){el.detachEvent("on"+evname,func);}else if(el.removeEventListener){el.removeEventListener(evname,func,true);}else{el["on"+evname]=null;}};Calendar.createElement=function(type,parent){var el=null;if(document.createElementNS){el=document.createElementNS("http://www.w3.org/1999/xhtml",type);}else{el=document.createElement(type);}if(typeof parent!="undefined"){parent.appendChild(el);}return el;};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true);}}};Calendar.findMonth=function(el){if(typeof el.month!="undefined"){return el;}else if(typeof el.parentNode.month!="undefined"){return el.parentNode;}return null;};Calendar.findYear=function(el){if(typeof el.year!="undefined"){return el;}else if(typeof el.parentNode.year!="undefined"){return el.parentNode;}return null;};Calendar.showMonthsCombo=function(){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var mc=cal.monthsCombo;if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}if(cal.activeMonth){Calendar.removeClass(cal.activeMonth,"active");}var mon=cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];Calendar.addClass(mon,"active");cal.activeMonth=mon;mc.style.left=cd.offsetLeft+"px";mc.style.top=(cd.offsetTop+cd.offsetHeight)+"px";mc.style.display="block";};Calendar.showYearsCombo=function(fwd){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var yc=cal.yearsCombo;if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}if(cal.activeYear){Calendar.removeClass(cal.activeYear,"active");}cal.activeYear=null;var Y=cal.date.getFullYear()+(fwd?1:-1);var yr=yc.firstChild;var show=false;for(var i=12;i>0;--i){if(Y>=cal.minYear&&Y<=cal.maxYear){yr.firstChild.data=Y;yr.year=Y;yr.style.display="block";show=true;}else{yr.style.display="none";}yr=yr.nextSibling;Y+=fwd?2:-2;}if(show){yc.style.left=cd.offsetLeft+"px";yc.style.top=(cd.offsetTop+cd.offsetHeight)+"px";yc.style.display="block";}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false;}if(cal.timeout){clearTimeout(cal.timeout);}var el=cal.activeDiv;if(!el){return false;}var target=Calendar.getTargetElement(ev);Calendar.removeClass(el,"active");if(target==el||target.parentNode==el){Calendar.cellClick(el);}var mon=Calendar.findMonth(target);var date=null;if(mon){date=new Date(cal.date);if(mon.month!=date.getMonth()){date.setMonth(mon.month);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}else{var year=Calendar.findYear(target);if(year){date=new Date(cal.date);if(year.year!=date.getFullYear()){date.setFullYear(year.year);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev);}};Calendar.tableMouseOver=function(ev){var cal=Calendar._C;if(!cal){return;}var el=cal.activeDiv;var target=Calendar.getTargetElement(ev);if(target==el||target.parentNode==el){Calendar.addClass(el,"hilite active");Calendar.addClass(el.parentNode,"rowhilite");}else{Calendar.removeClass(el,"active");Calendar.removeClass(el,"hilite");Calendar.removeClass(el.parentNode,"rowhilite");}var mon=Calendar.findMonth(target);if(mon){if(mon.month!=cal.date.getMonth()){if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}Calendar.addClass(mon,"hilite");cal.hilitedMonth=mon;}else if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}}else{var year=Calendar.findYear(target);if(year){if(year.year!=cal.date.getFullYear()){if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}Calendar.addClass(year,"hilite");cal.hilitedYear=year;}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}}return Calendar.stopEvent(ev);};Calendar.tableMouseDown=function(ev){if(Calendar.getTargetElement(ev)==Calendar.getElement(ev)){return Calendar.stopEvent(ev);}};Calendar.calDragIt=function(ev){var cal=Calendar._C;if(!(cal&&cal.dragging)){return false;}var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posX=ev.pageX;posY=ev.pageY;}cal.hideShowCovered();var st=cal.element.style;st.left=(posX-cal.xOffs)+"px";st.top=(posY-cal.yOffs)+"px";return Calendar.stopEvent(ev);};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false;}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseover",stopEvent);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev);}cal.hideShowCovered();};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false;}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300)with(Calendar){addClass(el,"hilite active");addEvent(document,"mouseover",tableMouseOver);addEvent(document,"mousemove",tableMouseOver);addEvent(document,"mouseup",tableMouseUp);}else if(cal.isPopup){cal._dragStart(ev);}if(el.navtype==-1||el.navtype==1){cal.timeout=setTimeout("Calendar.showMonthsCombo()",250);}else if(el.navtype==-2||el.navtype==2){cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250);}else{cal.timeout=null;}return Calendar.stopEvent(ev);};Calendar.dayMouseDblClick=function(ev){Calendar.cellClick(Calendar.getElement(ev));if(Calendar.is_ie){document.selection.empty();}};Calendar.dayMouseOver=function(ev){var el=Calendar.getElement(ev);if(Calendar.isRelated(el,ev)||Calendar._C||el.disabled){return false;}if(el.ttip){if(el.ttip.substr(0,1)=="_"){var date=null;with(el.calendar.date){date=new Date(getFullYear(),getMonth(),el.caldate);}el.ttip=date.print(el.calendar.ttDateFormat)+el.ttip.substr(1);}el.calendar.tooltips.firstChild.data=el.ttip;}if(el.navtype!=300){Calendar.addClass(el,"hilite");if(el.caldate){Calendar.addClass(el.parentNode,"rowhilite");}}return Calendar.stopEvent(ev);};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled){return false;}removeClass(el,"hilite");if(el.caldate){removeClass(el.parentNode,"rowhilite");}el.calendar.tooltips.firstChild.data=_TT["SEL_DATE"];return stopEvent(ev);}};Calendar.cellClick=function(el){var cal=el.calendar;var closing=false;var newdate=false;var date=null;if(typeof el.navtype=="undefined"){Calendar.removeClass(cal.currentDateEl,"selected");Calendar.addClass(el,"selected");closing=(cal.currentDateEl==el);if(!closing){cal.currentDateEl=el;}cal.date.setDate(el.caldate);date=cal.date;newdate=true;cal.dateClicked=true;}else{if(el.navtype==200){Calendar.removeClass(el,"hilite");cal.callCloseHandler();return;}date=(el.navtype==0)?new Date():new Date(cal.date);cal.dateClicked=(el.navtype==0);var year=date.getFullYear();var mon=date.getMonth();function setMonth(m){var day=date.getDate();var max=date.getMonthDays(m);if(day>max){date.setDate(max);}date.setMonth(m);};switch(el.navtype){case-2:if(year>cal.minYear){date.setFullYear(year-1);}break;case-1:if(mon>0){setMonth(mon-1);}else if(year-->cal.minYear){date.setFullYear(year);setMonth(11);}break;case 1:if(mon<11){setMonth(mon+1);}else if(year0;--i){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));if(!i){cell.navtype=100;cell.calendar=this;Calendar._add_evs(cell);}}this.firstdayname=(this.weekNumbers)?row.firstChild.nextSibling:row.firstChild;this._displayWeekdays();var tbody=Calendar.createElement("tbody",table);this.tbody=tbody;for(i=6;i>0;--i){row=Calendar.createElement("tr",tbody);if(this.weekNumbers){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));}for(var j=7;j>0;--j){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));cell.calendar=this;Calendar._add_evs(cell);}}var tfoot=Calendar.createElement("tfoot",table);row=Calendar.createElement("tr",tfoot);row.className="footrow";cell=hh(Calendar._TT["SEL_DATE"],this.weekNumbers?8:7,300);cell.className="ttip";if(this.isPopup){cell.ttip=Calendar._TT["DRAG_TO_MOVE"];cell.style.cursor="move";}this.tooltips=cell;div=Calendar.createElement("div",this.element);this.monthsCombo=div;div.className="combo";for(i=0;i0;--i){var yr=Calendar.createElement("div");yr.className="label";yr.appendChild(document.createTextNode(""));div.appendChild(yr);}this._init(this.mondayFirst,this.date);parent.appendChild(this.element);};Calendar._keyEvent=function(ev){if(!window.calendar){return false;}(Calendar.is_ie)&&(ev=window.event);var cal=window.calendar;var act=(Calendar.is_ie||ev.type=="keypress");if(ev.ctrlKey){switch(ev.keyCode){case 37:act&&Calendar.cellClick(cal._nav_pm);break;case 38:act&&Calendar.cellClick(cal._nav_py);break;case 39:act&&Calendar.cellClick(cal._nav_nm);break;case 40:act&&Calendar.cellClick(cal._nav_ny);break;default:return false;}}else switch(ev.keyCode){case 32:Calendar.cellClick(cal._nav_now);break;case 27:act&&cal.hide();break;case 37:case 38:case 39:case 40:if(act){var date=cal.date.getDate()-1;var el=cal.currentDateEl;var ne=null;var prev=(ev.keyCode==37)||(ev.keyCode==38);switch(ev.keyCode){case 37:(--date>=0)&&(ne=cal.ar_days[date]);break;case 38:date-=7;(date>=0)&&(ne=cal.ar_days[date]);break;case 39:(++datethis.maxYear){year=this.maxYear;date.setFullYear(year);}this.mondayFirst=mondayFirst;this.date=new Date(date);var month=date.getMonth();var mday=date.getDate();var no_days=date.getMonthDays();date.setDate(1);var wday=date.getDay();var MON=mondayFirst?1:0;var SAT=mondayFirst?5:6;var SUN=mondayFirst?6:0;if(mondayFirst){wday=(wday>0)?(wday-1):6;}var iday=1;var row=this.tbody.firstChild;var MN=Calendar._MN3[month];var hasToday=((today.getFullYear()==year)&&(today.getMonth()==month));var todayDate=today.getDate();var week_number=date.getWeekNumber();var ar_days=new Array();for(var i=0;i<6;++i){if(iday>no_days){row.className="emptyrow";row=row.nextSibling;continue;}var cell=row.firstChild;if(this.weekNumbers){cell.className="day wn";cell.firstChild.data=week_number;cell=cell.nextSibling;}++week_number;row.className="daysrow";for(var j=0;j<7;++j){cell.className="day";if((!i&&jno_days){cell.innerHTML=" ";cell.disabled=true;cell=cell.nextSibling;continue;}cell.disabled=false;cell.firstChild.data=iday;if(typeof this.checkDisabled=="function"){date.setDate(iday);if(this.checkDisabled(date)){cell.className+=" disabled";cell.disabled=true;}}if(!cell.disabled){ar_days[ar_days.length]=cell;cell.caldate=iday;cell.ttip="_";if(iday==mday){cell.className+=" selected";this.currentDateEl=cell;}if(hasToday&&(iday==todayDate)){cell.className+=" today";cell.ttip+=Calendar._TT["PART_TODAY"];}if(wday==SAT||wday==SUN){cell.className+=" weekend";}}++iday;((++wday)^ 7)||(wday=0);cell=cell.nextSibling;}row=row.nextSibling;}this.ar_days=ar_days;this.title.firstChild.data=Calendar._MN[month]+", "+year;};Calendar.prototype.setDate=function(date){if(!date.equalsTo(this.date)){this._init(this.mondayFirst,date);}};Calendar.prototype.refresh=function(){this._init(this.mondayFirst,this.date);};Calendar.prototype.setMondayFirst=function(mondayFirst){this._init(mondayFirst,this.date);this._displayWeekdays();};Calendar.prototype.setDisabledHandler=function(unaryFunction){this.checkDisabled=unaryFunction;};Calendar.prototype.setRange=function(a,z){this.minYear=a;this.maxYear=z;};Calendar.prototype.callHandler=function(){if(this.onSelected){this.onSelected(this,this.date.print(this.dateFormat));}};Calendar.prototype.callCloseHandler=function(){if(this.onClose){this.onClose(this);}this.hideShowCovered();};Calendar.prototype.destroy=function(){var el=this.element.parentNode;el.removeChild(this.element);Calendar._C=null;};Calendar.prototype.reparent=function(new_parent){var el=this.element;el.parentNode.removeChild(el);new_parent.appendChild(el);};Calendar._checkCalendar=function(ev){if(!window.calendar){return false;}var el=Calendar.is_ie?Calendar.getElement(ev):Calendar.getTargetElement(ev);for(;el!=null&&el!=calendar.element;el=el.parentNode);if(el==null){window.calendar.callCloseHandler();return Calendar.stopEvent(ev);}};Calendar.prototype.show=function(){var rows=this.table.getElementsByTagName("tr");for(var i=rows.length;i>0;){var row=rows[--i];Calendar.removeClass(row,"rowhilite");var cells=row.getElementsByTagName("td");for(var j=cells.length;j>0;){var cell=cells[--j];Calendar.removeClass(cell,"hilite");Calendar.removeClass(cell,"active");}}this.element.style.display="block";this.hidden=false;if(this.isPopup){window.calendar=this;Calendar.addEvent(document,"keydown",Calendar._keyEvent);Calendar.addEvent(document,"keypress",Calendar._keyEvent);Calendar.addEvent(document,"mousedown",Calendar._checkCalendar);}this.hideShowCovered();};Calendar.prototype.hide=function(){if(this.isPopup){Calendar.removeEvent(document,"keydown",Calendar._keyEvent);Calendar.removeEvent(document,"keypress",Calendar._keyEvent);Calendar.removeEvent(document,"mousedown",Calendar._checkCalendar);}this.element.style.display="none";this.hidden=true;this.hideShowCovered();};Calendar.prototype.showAt=function(x,y){var s=this.element.style;s.left=x+"px";s.top=y+"px";this.show();};Calendar.prototype.showAtElement=function(el,opts){var p=Calendar.getAbsolutePos(el);if(!opts||typeof opts!="string"){this.showAt(p.x,p.y+el.offsetHeight);return true;}this.show();var w=this.element.offsetWidth;var h=this.element.offsetHeight;this.hide();var valign=opts.substr(0,1);var halign="l";if(opts.length>1){halign=opts.substr(1,1);}switch(valign){case "T":p.y-=h;break;case "B":p.y+=el.offsetHeight;break;case "C":p.y+=(el.offsetHeight-h)/2;break;case "t":p.y+=el.offsetHeight-h;break;case "b":break;}switch(halign){case "L":p.x-=w;break;case "R":p.x+=el.offsetWidth;break;case "C":p.x+=(el.offsetWidth-w)/2;break;case "r":p.x+=el.offsetWidth-w;break;case "l":break;}this.showAt(p.x,p.y);};Calendar.prototype.setDateFormat=function(str){this.dateFormat=str;};Calendar.prototype.setTtDateFormat=function(str){this.ttDateFormat=str;};Calendar.prototype.parseDate=function(str,fmt){var y=0;var m=-1;var d=0;var a=str.split(/\W+/);if(!fmt){fmt=this.dateFormat;}var b=fmt.split(/\W+/);var i=0,j=0;for(i=0;i29)?1900:2000);}if(b[i]=="M"||b[i]=="MM"){for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){m=j;break;}}}}if(y!=0&&m!=-1&&d!=0){this.setDate(new Date(y,m,d));return;}y=0;m=-1;d=0;for(i=0;i31&&y==0){y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);}else if(d==0){d=a[i];}}if(y==0){var today=new Date();y=today.getFullYear();}if(m!=-1&&d!=0){this.setDate(new Date(y,m,d));}};Calendar.prototype.hideShowCovered=function(){function getStyleProp(obj,style){var value=obj.style[style];if(!value){if(document.defaultView&&typeof(document.defaultView.getComputedStyle)=="function"){value=document.defaultView.getComputedStyle(obj,"").getPropertyValue(style);}else if(obj.currentStyle){value=obj.currentStyle[style];}else{value=obj.style[style];}}return value;};var tags=new Array("applet","iframe","select");var el=this.element;var p=Calendar.getAbsolutePos(el);var EX1=p.x;var EX2=el.offsetWidth+EX1;var EY1=p.y;var EY2=el.offsetHeight+EY1;for(var k=tags.length;k>0;){var ar=document.getElementsByTagName(tags[--k]);var cc=null;for(var i=ar.length;i>0;){cc=ar[--i];p=Calendar.getAbsolutePos(cc);var CX1=p.x;var CX2=cc.offsetWidth+CX1;var CY1=p.y;var CY2=cc.offsetHeight+CY1;if(this.hidden||(CX1>EX2)||(CX2EY2)||(CY23)&&(day-=4)||(day+=3);return Math.round(((time/Date.DAY)+day)/7);};Date.prototype.equalsTo=function(date){return((this.getFullYear()==date.getFullYear())&&(this.getMonth()==date.getMonth())&&(this.getDate()==date.getDate()));};Date.prototype.print=function(frm){var str=new String(frm);var m=this.getMonth();var d=this.getDate();var y=this.getFullYear();var wn=this.getWeekNumber();var w=this.getDay();var s=new Array();s["d"]=d;s["dd"]=(d<10)?("0"+d):d;s["m"]=1+m;s["mm"]=(m<9)?("0"+(1+m)):(1+m);s["y"]=y;s["yy"]=new String(y).substr(2,2);s["w"]=wn;s["ww"]=(wn<10)?("0"+wn):wn;with(Calendar){s["D"]=_DN3[w];s["DD"]=_DN[w];s["M"]=_MN3[m];s["MM"]=_MN[m];}var re=/(.*)(\W|^)(d|dd|m|mm|y|yy|MM|M|DD|D|w|ww)(\W|$)(.*)/;while(re.exec(str)!=null){str=RegExp.$1+RegExp.$2+s[RegExp.$3]+RegExp.$4+RegExp.$5;}return str;};window.calendar=null; \ No newline at end of file + Calendar=function(mondayFirst,dateStr,onSelected,onClose){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.timeout=null;this.onSelected=onSelected||null;this.onClose=onClose||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT["DEF_DATE_FORMAT"];this.ttDateFormat=Calendar._TT["TT_DATE_FORMAT"];this.isPopup=true;this.weekNumbers=true;this.mondayFirst=mondayFirst;this.dateStr=dateStr;this.ar_days=null;this.showsTime=false;this.time24=true;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(typeof Calendar._SDN=="undefined"){if(typeof Calendar._SDN_len=="undefined")Calendar._SDN_len=3;var ar=new Array();for(var i=8;i>0;){ar[--i]=Calendar._DN[i].substr(0,Calendar._SDN_len);}Calendar._SDN=ar;if(typeof Calendar._SMN_len=="undefined")Calendar._SMN_len=3;ar=new Array();for(var i=12;i>0;){ar[--i]=Calendar._MN[i].substr(0,Calendar._SMN_len);}Calendar._SMN=ar;}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar.is_opera=/opera/i.test(navigator.userAgent);Calendar.is_khtml=/Konqueror|Safari|KHTML/i.test(navigator.userAgent);Calendar.getAbsolutePos=function(el){var SL=0,ST=0;var is_div=/^div$/i.test(el.tagName);if(is_div&&el.scrollLeft)SL=el.scrollLeft;if(is_div&&el.scrollTop)ST=el.scrollTop;var r={x:el.offsetLeft-SL,y:el.offsetTop-ST};if(el.offsetParent){var tmp=Calendar.getAbsolutePos(el.offsetParent);r.x+=tmp.x;r.y+=tmp.y;}return r;};Calendar.isRelated=function(el,evt){var related=evt.relatedTarget;if(!related){var type=evt.type;if(type=="mouseover"){related=evt.fromElement;}else if(type=="mouseout"){related=evt.toElement;}}while(related){if(related==el){return true;}related=related.parentNode;}return false;};Calendar.removeClass=function(el,className){if(!(el&&el.className)){return;}var cls=el.className.split(" ");var ar=new Array();for(var i=cls.length;i>0;){if(cls[--i]!=className){ar[ar.length]=cls[i];}}el.className=ar.join(" ");};Calendar.addClass=function(el,className){Calendar.removeClass(el,className);el.className+=" "+className;};Calendar.getElement=function(ev){if(Calendar.is_ie){return window.event.srcElement;}else{return ev.currentTarget;}};Calendar.getTargetElement=function(ev){if(Calendar.is_ie){return window.event.srcElement;}else{return ev.target;}};Calendar.stopEvent=function(ev){ev||(ev=window.event);if(Calendar.is_ie){ev.cancelBubble=true;ev.returnValue=false;}else{ev.preventDefault();ev.stopPropagation();}return false;};Calendar.addEvent=function(el,evname,func){if(el.attachEvent){el.attachEvent("on"+evname,func);}else if(el.addEventListener){el.addEventListener(evname,func,true);}else{el["on"+evname]=func;}};Calendar.removeEvent=function(el,evname,func){if(el.detachEvent){el.detachEvent("on"+evname,func);}else if(el.removeEventListener){el.removeEventListener(evname,func,true);}else{el["on"+evname]=null;}};Calendar.createElement=function(type,parent){var el=null;if(document.createElementNS){el=document.createElementNS("http://www.w3.org/1999/xhtml",type);}else{el=document.createElement(type);}if(typeof parent!="undefined"){parent.appendChild(el);}return el;};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true);}}};Calendar.findMonth=function(el){if(typeof el.month!="undefined"){return el;}else if(typeof el.parentNode.month!="undefined"){return el.parentNode;}return null;};Calendar.findYear=function(el){if(typeof el.year!="undefined"){return el;}else if(typeof el.parentNode.year!="undefined"){return el.parentNode;}return null;};Calendar.showMonthsCombo=function(){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var mc=cal.monthsCombo;if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}if(cal.activeMonth){Calendar.removeClass(cal.activeMonth,"active");}var mon=cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];Calendar.addClass(mon,"active");cal.activeMonth=mon;var s=mc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else s.left=(cd.offsetLeft+cd.offsetWidth-mc.offsetWidth)+"px";s.top=(cd.offsetTop+cd.offsetHeight)+"px";};Calendar.showYearsCombo=function(fwd){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var yc=cal.yearsCombo;if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}if(cal.activeYear){Calendar.removeClass(cal.activeYear,"active");}cal.activeYear=null;var Y=cal.date.getFullYear()+(fwd?1:-1);var yr=yc.firstChild;var show=false;for(var i=12;i>0;--i){if(Y>=cal.minYear&&Y<=cal.maxYear){yr.firstChild.data=Y;yr.year=Y;yr.style.display="block";show=true;}else{yr.style.display="none";}yr=yr.nextSibling;Y+=fwd?2:-2;}if(show){var s=yc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else s.left=(cd.offsetLeft+cd.offsetWidth-yc.offsetWidth)+"px";s.top=(cd.offsetTop+cd.offsetHeight)+"px";}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false;}if(cal.timeout){clearTimeout(cal.timeout);}var el=cal.activeDiv;if(!el){return false;}var target=Calendar.getTargetElement(ev);ev||(ev=window.event);Calendar.removeClass(el,"active");if(target==el||target.parentNode==el){Calendar.cellClick(el,ev);}var mon=Calendar.findMonth(target);var date=null;if(mon){date=new Date(cal.date);if(mon.month!=date.getMonth()){date.setMonth(mon.month);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}else{var year=Calendar.findYear(target);if(year){date=new Date(cal.date);if(year.year!=date.getFullYear()){date.setFullYear(year.year);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev);}};Calendar.tableMouseOver=function(ev){var cal=Calendar._C;if(!cal){return;}var el=cal.activeDiv;var target=Calendar.getTargetElement(ev);if(target==el||target.parentNode==el){Calendar.addClass(el,"hilite active");Calendar.addClass(el.parentNode,"rowhilite");}else{if(typeof el.navtype=="undefined"||(el.navtype!=50&&(el.navtype==0||Math.abs(el.navtype)>2)))Calendar.removeClass(el,"active");Calendar.removeClass(el,"hilite");Calendar.removeClass(el.parentNode,"rowhilite");}ev||(ev=window.event);if(el.navtype==50&&target!=el){var pos=Calendar.getAbsolutePos(el);var w=el.offsetWidth;var x=ev.clientX;var dx;var decrease=true;if(x>pos.x+w){dx=x-pos.x-w;decrease=false;}else dx=pos.x-x;if(dx<0)dx=0;var range=el._range;var current=el._current;var count=Math.floor(dx/10)%range.length;for(var i=range.length;--i>=0;)if(range[i]==current)break;while(count-->0)if(decrease){if(!(--i in range))i=range.length-1;}else if(!(++i in range))i=0;var newval=range[i];el.firstChild.data=newval;cal.onUpdateTime();}var mon=Calendar.findMonth(target);if(mon){if(mon.month!=cal.date.getMonth()){if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}Calendar.addClass(mon,"hilite");cal.hilitedMonth=mon;}else if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}}else{if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}var year=Calendar.findYear(target);if(year){if(year.year!=cal.date.getFullYear()){if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}Calendar.addClass(year,"hilite");cal.hilitedYear=year;}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}return Calendar.stopEvent(ev);};Calendar.tableMouseDown=function(ev){if(Calendar.getTargetElement(ev)==Calendar.getElement(ev)){return Calendar.stopEvent(ev);}};Calendar.calDragIt=function(ev){var cal=Calendar._C;if(!(cal&&cal.dragging)){return false;}var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posX=ev.pageX;posY=ev.pageY;}cal.hideShowCovered();var st=cal.element.style;st.left=(posX-cal.xOffs)+"px";st.top=(posY-cal.yOffs)+"px";return Calendar.stopEvent(ev);};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false;}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseover",stopEvent);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev);}cal.hideShowCovered();};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false;}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300)with(Calendar){if(el.navtype==50)el._current=el.firstChild.data;addClass(el,"hilite active");addEvent(document,"mouseover",tableMouseOver);addEvent(document,"mousemove",tableMouseOver);addEvent(document,"mouseup",tableMouseUp);}else if(cal.isPopup){cal._dragStart(ev);}if(el.navtype==-1||el.navtype==1){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout("Calendar.showMonthsCombo()",250);}else if(el.navtype==-2||el.navtype==2){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250);}else{cal.timeout=null;}return Calendar.stopEvent(ev);};Calendar.dayMouseDblClick=function(ev){Calendar.cellClick(Calendar.getElement(ev),ev||window.event);if(Calendar.is_ie){document.selection.empty();}};Calendar.dayMouseOver=function(ev){var el=Calendar.getElement(ev);if(Calendar.isRelated(el,ev)||Calendar._C||el.disabled){return false;}if(el.ttip){if(el.ttip.substr(0,1)=="_"){var date=null;with(el.calendar.date){date=new Date(getFullYear(),getMonth(),el.caldate);}el.ttip=date.print(el.calendar.ttDateFormat)+el.ttip.substr(1);}el.calendar.tooltips.firstChild.data=el.ttip;}if(el.navtype!=300){Calendar.addClass(el,"hilite");if(el.caldate){Calendar.addClass(el.parentNode,"rowhilite");}}return Calendar.stopEvent(ev);};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled){return false;}removeClass(el,"hilite");if(el.caldate){removeClass(el.parentNode,"rowhilite");}el.calendar.tooltips.firstChild.data=_TT["SEL_DATE"];return stopEvent(ev);}};Calendar.cellClick=function(el,ev){var cal=el.calendar;var closing=false;var newdate=false;var date=null;if(typeof el.navtype=="undefined"){Calendar.removeClass(cal.currentDateEl,"selected");Calendar.addClass(el,"selected");closing=(cal.currentDateEl==el);if(!closing){cal.currentDateEl=el;}cal.date.setDate(el.caldate);date=cal.date;newdate=true;cal.dateClicked=true;}else{if(el.navtype==200){Calendar.removeClass(el,"hilite");cal.callCloseHandler();return;}date=(el.navtype==0)?new Date():new Date(cal.date);cal.dateClicked=false;var year=date.getFullYear();var mon=date.getMonth();function setMonth(m){var day=date.getDate();var max=date.getMonthDays(m);if(day>max){date.setDate(max);}date.setMonth(m);};switch(el.navtype){case 400:Calendar.removeClass(el,"hilite");var text=Calendar._TT["ABOUT"];if(typeof text!="undefined"){text+=cal.showsTime?Calendar._TT["ABOUT_TIME"]:"";}else{text="Help and about box text is not translated into this language.\n"+"If you know this language and you feel generous please update\n"+"the corresponding file in \"lang\" subdir to match calendar-en.js\n"+"and send it back to to get it into the distribution ;-)\n\n"+"Thank you!\n"+"http://dynarch.com/mishoo/calendar.epl\n";}alert(text);return;case-2:if(year>cal.minYear){date.setFullYear(year-1);}break;case-1:if(mon>0){setMonth(mon-1);}else if(year-->cal.minYear){date.setFullYear(year);setMonth(11);}break;case 1:if(mon<11){setMonth(mon+1);}else if(year=0;)if(range[i]==current)break;if(ev&&ev.shiftKey){if(!(--i in range))i=range.length-1;}else if(!(++i in range))i=0;var newval=range[i];el.firstChild.data=newval;cal.onUpdateTime();return;case 0:if((typeof cal.getDateStatus=="function")&&cal.getDateStatus(date,date.getFullYear(),date.getMonth(),date.getDate())){return false;}break;}if(!date.equalsTo(cal.date)){cal.setDate(date);newdate=true;}}if(newdate){cal.callHandler();}if(closing){Calendar.removeClass(el,"hilite");cal.callCloseHandler();}};Calendar.prototype.create=function(_par){var parent=null;if(!_par){parent=document.getElementsByTagName("body")[0];this.isPopup=true;}else{parent=_par;this.isPopup=false;}this.date=this.dateStr?new Date(this.dateStr):new Date();var table=Calendar.createElement("table");this.table=table;table.cellSpacing=0;table.cellPadding=0;table.calendar=this;Calendar.addEvent(table,"mousedown",Calendar.tableMouseDown);var div=Calendar.createElement("div");this.element=div;div.className="calendar";if(this.isPopup){div.style.position="absolute";div.style.display="none";}div.appendChild(table);var thead=Calendar.createElement("thead",table);var cell=null;var row=null;var cal=this;var hh=function(text,cs,navtype){cell=Calendar.createElement("td",row);cell.colSpan=cs;cell.className="button";if(navtype!=0&&Math.abs(navtype)<=2)cell.className+=" nav";Calendar._add_evs(cell);cell.calendar=cal;cell.navtype=navtype;if(text.substr(0,1)!="&"){cell.appendChild(document.createTextNode(text));}else{cell.innerHTML=text;}return cell;};row=Calendar.createElement("tr",thead);var title_length=6;(this.isPopup)&&--title_length;(this.weekNumbers)&&++title_length;hh("?",1,400).ttip=Calendar._TT["INFO"];this.title=hh("",title_length,300);this.title.className="title";if(this.isPopup){this.title.ttip=Calendar._TT["DRAG_TO_MOVE"];this.title.style.cursor="move";hh("×",1,200).ttip=Calendar._TT["CLOSE"];}row=Calendar.createElement("tr",thead);row.className="headrow";this._nav_py=hh("«",1,-2);this._nav_py.ttip=Calendar._TT["PREV_YEAR"];this._nav_pm=hh("‹",1,-1);this._nav_pm.ttip=Calendar._TT["PREV_MONTH"];this._nav_now=hh(Calendar._TT["TODAY"],this.weekNumbers?4:3,0);this._nav_now.ttip=Calendar._TT["GO_TODAY"];this._nav_nm=hh("›",1,1);this._nav_nm.ttip=Calendar._TT["NEXT_MONTH"];this._nav_ny=hh("»",1,2);this._nav_ny.ttip=Calendar._TT["NEXT_YEAR"];row=Calendar.createElement("tr",thead);row.className="daynames";if(this.weekNumbers){cell=Calendar.createElement("td",row);cell.className="name wn";cell.appendChild(document.createTextNode(Calendar._TT["WK"]));}for(var i=7;i>0;--i){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));if(!i){cell.navtype=100;cell.calendar=this;Calendar._add_evs(cell);}}this.firstdayname=(this.weekNumbers)?row.firstChild.nextSibling:row.firstChild;this._displayWeekdays();var tbody=Calendar.createElement("tbody",table);this.tbody=tbody;for(i=6;i>0;--i){row=Calendar.createElement("tr",tbody);if(this.weekNumbers){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));}for(var j=7;j>0;--j){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));cell.calendar=this;Calendar._add_evs(cell);}}if(this.showsTime){row=Calendar.createElement("tr",tbody);row.className="time";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;cell.innerHTML=" ";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=this.weekNumbers?4:3;(function(){function makeTimePart(className,init,range_start,range_end){var part=Calendar.createElement("span",cell);part.className=className;part.appendChild(document.createTextNode(init));part.calendar=cal;part.ttip=Calendar._TT["TIME_PART"];part.navtype=50;part._range=[];if(typeof range_start!="number")part._range=range_start;else{for(var i=range_start;i<=range_end;++i){var txt;if(i<10&&range_end>=10)txt='0'+i;else txt=''+i;part._range[part._range.length]=txt;}}Calendar._add_evs(part);return part;};var hrs=cal.date.getHours();var mins=cal.date.getMinutes();var t12=!cal.time24;var pm=(hrs>12);if(t12&&pm)hrs-=12;var H=makeTimePart("hour",hrs,t12?1:0,t12?12:23);var span=Calendar.createElement("span",cell);span.appendChild(document.createTextNode(":"));span.className="colon";var M=makeTimePart("minute",mins,0,59);var AP=null;cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;if(t12)AP=makeTimePart("ampm",pm?"pm":"am",["am","pm"]);else cell.innerHTML=" ";cal.onSetTime=function(){var hrs=this.date.getHours();var mins=this.date.getMinutes();var pm=(hrs>12);if(pm&&t12)hrs-=12;H.firstChild.data=(hrs<10)?("0"+hrs):hrs;M.firstChild.data=(mins<10)?("0"+mins):mins;if(t12)AP.firstChild.data=pm?"pm":"am";};cal.onUpdateTime=function(){var date=this.date;var h=parseInt(H.firstChild.data,10);if(t12){if(/pm/i.test(AP.firstChild.data)&&h<12)h+=12;else if(/am/i.test(AP.firstChild.data)&&h==12)h=0;}var d=date.getDate();var m=date.getMonth();var y=date.getFullYear();date.setHours(h);date.setMinutes(parseInt(M.firstChild.data,10));date.setFullYear(y);date.setMonth(m);date.setDate(d);this.dateClicked=false;this.callHandler();};})();}else{this.onSetTime=this.onUpdateTime=function(){};}var tfoot=Calendar.createElement("tfoot",table);row=Calendar.createElement("tr",tfoot);row.className="footrow";cell=hh(Calendar._TT["SEL_DATE"],this.weekNumbers?8:7,300);cell.className="ttip";if(this.isPopup){cell.ttip=Calendar._TT["DRAG_TO_MOVE"];cell.style.cursor="move";}this.tooltips=cell;div=Calendar.createElement("div",this.element);this.monthsCombo=div;div.className="combo";for(i=0;i0;--i){var yr=Calendar.createElement("div");yr.className=Calendar.is_ie?"label-IEfix":"label";yr.appendChild(document.createTextNode(""));div.appendChild(yr);}this._init(this.mondayFirst,this.date);parent.appendChild(this.element);};Calendar._keyEvent=function(ev){if(!window.calendar){return false;}(Calendar.is_ie)&&(ev=window.event);var cal=window.calendar;var act=(Calendar.is_ie||ev.type=="keypress");if(ev.ctrlKey){switch(ev.keyCode){case 37:act&&Calendar.cellClick(cal._nav_pm);break;case 38:act&&Calendar.cellClick(cal._nav_py);break;case 39:act&&Calendar.cellClick(cal._nav_nm);break;case 40:act&&Calendar.cellClick(cal._nav_ny);break;default:return false;}}else switch(ev.keyCode){case 32:Calendar.cellClick(cal._nav_now);break;case 27:act&&cal.hide();break;case 37:case 38:case 39:case 40:if(act){var date=cal.date.getDate()-1;var el=cal.currentDateEl;var ne=null;var prev=(ev.keyCode==37)||(ev.keyCode==38);switch(ev.keyCode){case 37:(--date>=0)&&(ne=cal.ar_days[date]);break;case 38:date-=7;(date>=0)&&(ne=cal.ar_days[date]);break;case 39:(++datethis.maxYear){year=this.maxYear;date.setFullYear(year);}this.mondayFirst=mondayFirst;this.date=new Date(date);var month=date.getMonth();var mday=date.getDate();var no_days=date.getMonthDays();date.setDate(1);var wday=date.getDay();var MON=mondayFirst?1:0;var SAT=mondayFirst?5:6;var SUN=mondayFirst?6:0;if(mondayFirst){wday=(wday>0)?(wday-1):6;}var iday=1;var row=this.tbody.firstChild;var MN=Calendar._SMN[month];var hasToday=((today.getFullYear()==year)&&(today.getMonth()==month));var todayDate=today.getDate();var week_number=date.getWeekNumber();var ar_days=new Array();for(var i=0;i<6;++i){if(iday>no_days){row.className="emptyrow";row=row.nextSibling;continue;}var cell=row.firstChild;if(this.weekNumbers){cell.className="day wn";cell.firstChild.data=week_number;cell=cell.nextSibling;}++week_number;row.className="daysrow";for(var j=0;j<7;++j){cell.className="day";if((!i&&jno_days){cell.innerHTML=" ";cell.disabled=true;cell=cell.nextSibling;continue;}cell.disabled=false;cell.firstChild.data=iday;if(typeof this.getDateStatus=="function"){date.setDate(iday);var status=this.getDateStatus(date,year,month,iday);if(status===true){cell.className+=" disabled";cell.disabled=true;}else{if(/disabled/i.test(status))cell.disabled=true;cell.className+=" "+status;}}if(!cell.disabled){ar_days[ar_days.length]=cell;cell.caldate=iday;cell.ttip="_";if(iday==mday){cell.className+=" selected";this.currentDateEl=cell;}if(hasToday&&(iday==todayDate)){cell.className+=" today";cell.ttip+=Calendar._TT["PART_TODAY"];}if(wday==SAT||wday==SUN){cell.className+=" weekend";}}++iday;((++wday)^ 7)||(wday=0);cell=cell.nextSibling;}row=row.nextSibling;}this.ar_days=ar_days;this.title.firstChild.data=Calendar._MN[month]+", "+year;this.onSetTime();};Calendar.prototype.setDate=function(date){if(!date.equalsTo(this.date)){this._init(this.mondayFirst,date);}};Calendar.prototype.refresh=function(){this._init(this.mondayFirst,this.date);};Calendar.prototype.setMondayFirst=function(mondayFirst){this._init(mondayFirst,this.date);this._displayWeekdays();};Calendar.prototype.setDateStatusHandler=Calendar.prototype.setDisabledHandler=function(unaryFunction){this.getDateStatus=unaryFunction;};Calendar.prototype.setRange=function(a,z){this.minYear=a;this.maxYear=z;};Calendar.prototype.callHandler=function(){if(this.onSelected){this.onSelected(this,this.date.print(this.dateFormat));}};Calendar.prototype.callCloseHandler=function(){if(this.onClose){this.onClose(this);}this.hideShowCovered();};Calendar.prototype.destroy=function(){var el=this.element.parentNode;el.removeChild(this.element);Calendar._C=null;window.calendar=null;};Calendar.prototype.reparent=function(new_parent){var el=this.element;el.parentNode.removeChild(el);new_parent.appendChild(el);};Calendar._checkCalendar=function(ev){if(!window.calendar){return false;}var el=Calendar.is_ie?Calendar.getElement(ev):Calendar.getTargetElement(ev);for(;el!=null&&el!=calendar.element;el=el.parentNode);if(el==null){window.calendar.callCloseHandler();return Calendar.stopEvent(ev);}};Calendar.prototype.show=function(){var rows=this.table.getElementsByTagName("tr");for(var i=rows.length;i>0;){var row=rows[--i];Calendar.removeClass(row,"rowhilite");var cells=row.getElementsByTagName("td");for(var j=cells.length;j>0;){var cell=cells[--j];Calendar.removeClass(cell,"hilite");Calendar.removeClass(cell,"active");}}this.element.style.display="block";this.hidden=false;if(this.isPopup){window.calendar=this;Calendar.addEvent(document,"keydown",Calendar._keyEvent);Calendar.addEvent(document,"keypress",Calendar._keyEvent);Calendar.addEvent(document,"mousedown",Calendar._checkCalendar);}this.hideShowCovered();};Calendar.prototype.hide=function(){if(this.isPopup){Calendar.removeEvent(document,"keydown",Calendar._keyEvent);Calendar.removeEvent(document,"keypress",Calendar._keyEvent);Calendar.removeEvent(document,"mousedown",Calendar._checkCalendar);}this.element.style.display="none";this.hidden=true;this.hideShowCovered();};Calendar.prototype.showAt=function(x,y){var s=this.element.style;s.left=x+"px";s.top=y+"px";this.show();};Calendar.prototype.showAtElement=function(el,opts){var self=this;var p=Calendar.getAbsolutePos(el);if(!opts||typeof opts!="string"){this.showAt(p.x,p.y+el.offsetHeight);return true;}this.element.style.display="block";Calendar.continuation_for_the_fucking_khtml_browser=function(){var w=self.element.offsetWidth;var h=self.element.offsetHeight;self.element.style.display="none";var valign=opts.substr(0,1);var halign="l";if(opts.length>1){halign=opts.substr(1,1);}switch(valign){case "T":p.y-=h;break;case "B":p.y+=el.offsetHeight;break;case "C":p.y+=(el.offsetHeight-h)/2;break;case "t":p.y+=el.offsetHeight-h;break;case "b":break;}switch(halign){case "L":p.x-=w;break;case "R":p.x+=el.offsetWidth;break;case "C":p.x+=(el.offsetWidth-w)/2;break;case "r":p.x+=el.offsetWidth-w;break;case "l":break;}self.showAt(p.x,p.y);};if(Calendar.is_khtml)setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10);else Calendar.continuation_for_the_fucking_khtml_browser();};Calendar.prototype.setDateFormat=function(str){this.dateFormat=str;};Calendar.prototype.setTtDateFormat=function(str){this.ttDateFormat=str;};Calendar.prototype.parseDate=function(str,fmt){var y=0;var m=-1;var d=0;var a=str.split(/\W+/);if(!fmt){fmt=this.dateFormat;}var b=[];fmt.replace(/(%.)/g,function(str,par){return b[b.length]=par;});var i=0,j=0;var hr=0;var min=0;for(i=0;i29)?1900:2000);}if(b[i]=="%b"||b[i]=="%B"){for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){m=j;break;}}}else if(/%[HIkl]/.test(b[i])){hr=parseInt(a[i],10);}else if(/%[pP]/.test(b[i])){if(/pm/i.test(a[i])&&hr<12)hr+=12;}else if(b[i]=="%M"){min=parseInt(a[i],10);}}if(y!=0&&m!=-1&&d!=0){this.setDate(new Date(y,m,d,hr,min,0));return;}y=0;m=-1;d=0;for(i=0;i31&&y==0){y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);}else if(d==0){d=a[i];}}if(y==0){var today=new Date();y=today.getFullYear();}if(m!=-1&&d!=0){this.setDate(new Date(y,m,d,hr,min,0));}};Calendar.prototype.hideShowCovered=function(){var self=this;Calendar.continuation_for_the_fucking_khtml_browser=function(){function getVisib(obj){var value=obj.style.visibility;if(!value){if(document.defaultView&&typeof(document.defaultView.getComputedStyle)=="function"){if(!Calendar.is_khtml)value=document.defaultView. getComputedStyle(obj,"").getPropertyValue("visibility");else value='';}else if(obj.currentStyle){value=obj.currentStyle.visibility;}else value='';}return value;};var tags=new Array("applet","iframe","select");var el=self.element;var p=Calendar.getAbsolutePos(el);var EX1=p.x;var EX2=el.offsetWidth+EX1;var EY1=p.y;var EY2=el.offsetHeight+EY1;for(var k=tags.length;k>0;){var ar=document.getElementsByTagName(tags[--k]);var cc=null;for(var i=ar.length;i>0;){cc=ar[--i];p=Calendar.getAbsolutePos(cc);var CX1=p.x;var CX2=cc.offsetWidth+CX1;var CY1=p.y;var CY2=cc.offsetHeight+CY1;if(self.hidden||(CX1>EX2)||(CX2EY2)||(CY24)&&(day-=4)||(day+=3);return Math.round(((time/Date.DAY)+day)/7);};Date.prototype.equalsTo=function(date){return((this.getFullYear()==date.getFullYear())&&(this.getMonth()==date.getMonth())&&(this.getDate()==date.getDate())&&(this.getHours()==date.getHours())&&(this.getMinutes()==date.getMinutes()));};Date.prototype.print=function(str){var m=this.getMonth();var d=this.getDate();var y=this.getFullYear();var wn=this.getWeekNumber();var w=this.getDay();var s={};var hr=this.getHours();var pm=(hr>=12);var ir=(pm)?(hr-12):hr;var dy=this.getDayOfYear();if(ir==0)ir=12;var min=this.getMinutes();var sec=this.getSeconds();s["%a"]=Calendar._SDN[w];s["%A"]=Calendar._DN[w];s["%b"]=Calendar._SMN[m];s["%B"]=Calendar._MN[m];s["%C"]=1+Math.floor(y/100);s["%d"]=(d<10)?("0"+d):d;s["%e"]=d;s["%H"]=(hr<10)?("0"+hr):hr;s["%I"]=(ir<10)?("0"+ir):ir;s["%j"]=(dy<100)?((dy<10)?("00"+dy):("0"+dy)):dy;s["%k"]=hr;s["%l"]=ir;s["%m"]=(m<9)?("0"+(1+m)):(1+m);s["%M"]=(min<10)?("0"+min):min;s["%n"]="\n";s["%p"]=pm?"PM":"AM";s["%P"]=pm?"pm":"am";s["%s"]=Math.floor(this.getTime()/1000);s["%S"]=(sec<10)?("0"+sec):sec;s["%t"]="\t";s["%U"]=s["%W"]=s["%V"]=(wn<10)?("0"+wn):wn;s["%u"]=w+1;s["%w"]=w;s["%y"]=(''+y).substr(2,2);s["%Y"]=y;s["%%"]="%";var re=Date._msh_formatRegexp;if(typeof re=="undefined"){var tmp="";for(var i in s)tmp+=tmp?("|"+i):i;Date._msh_formatRegexp=re=new RegExp("("+tmp+")",'g');}return str.replace(re,function(match,par){return s[par];});};window.calendar=null; \ No newline at end of file diff --git a/phpgwapi/js/jscalendar/doc/html/reference.html b/phpgwapi/js/jscalendar/doc/html/reference.html index 944ef99ed1..9c0c856ff7 100644 --- a/phpgwapi/js/jscalendar/doc/html/reference.html +++ b/phpgwapi/js/jscalendar/doc/html/reference.html @@ -42,28 +42,25 @@ DHTML Calendar Widget

- +

+



DHTML Calendar Widget

-Mihai Bazon, <mishoo@infoiasi.ro>

July 9, 2003

+Mihai Bazon, <mishoo@infoiasi.ro>

November 5, 2003

-calendar version: 0.9.3
-document version: 0.1 -
+calendar version: 0.9.5 “Your favorite time, bis”

+$Id$

-“Though a program be but three lines of code, someday it will have to be -maintained.”
-— The Tao of Programming
@@ -100,19 +97,20 @@ maintained.”
            4.3.5  Calendar.setDateFormat
            4.3.6  Calendar.setTtDateFormat
            4.3.7  Calendar.setDisabledHandler
-            4.3.8  Calendar.show
-            4.3.9  Calendar.showAt
-            4.3.10  Calendar.showAtElement
-            4.3.11  Calendar.setDate
-            4.3.12  Calendar.setMondayFirst
-            4.3.13  Calendar.parseDate
-            4.3.14  Calendar.setRange
+            4.3.8  Calendar.setDateStatusHandler
+            4.3.9  Calendar.show
+            4.3.10  Calendar.showAt
+            4.3.11  Calendar.showAtElement
+            4.3.12  Calendar.setDate
+            4.3.13  Calendar.setMondayFirst
+            4.3.14  Calendar.parseDate
+            4.3.15  Calendar.setRange

    5  Side effects

-    6  Sponsors
+    6  Credits

@@ -121,7 +119,7 @@ maintained.”

1  Overview

The DHTML Calendar widget1 is an (HTML) user interface element that gives end-users a friendly way to -input dates. It works in a web browser. The first versions only provided +select date and time. It works in a web browser. The first versions only provided support for popup calendars, while starting with version 0.9 it also supports “flat” display. A “flat” calendar is a calendar that stays visible in the page all the time. In this mode it could be very useful for “blog” pages and @@ -129,16 +127,17 @@ other pages that require the calendar to be always present.

The calendar is compatible with most popular browsers nowadays. While it’s created using web standards and it should generally work with any compliant -browser, the following browsers were found to work: Mozilla (the main +browser, the following browsers were found to work: Mozilla (the development platform), Netscape 6.0 or better, all other Gecko-based browsers, -Internet Explorer 5.0 or better for Windows2, Opera 73.

+Internet Explorer 5.0 or better for Windows2, Opera 73 and Konqueror 3.1.2 (with pretty much the +same dysfunctions as in Opera).

You can find the latest info and version at the calendar homepage:

@@ -148,7 +147,8 @@ refers to the combination of HTML, CSS, JavaScript and DOM. DOM (Document Object Model) is a set of interfaces that glues the other three together. In other words, DOM allows dynamic modification of an HTML page through a program. JavaScript is our programming language, since that’s what browsers like. CSS -is a way to make it look good ;-).

+is a way to make it look good ;-). So all this soup is generically known as +DHTML.

Using DOM calls, the program dynamically creates a <table> element that contains a calendar for the given date and then inserts it in the document @@ -195,14 +195,13 @@ version 0.9.3 this is the recommended way to setup a calendar.

© Mihai Bazon, 2002 – 2003, <mishoo@infoiasi.ro>
-http://students.infoiasi.ro/~mishoo +http://dynarch.com/mishoo/

The calendar is released under the -GNU Lesser General Public -License. This basically means that you are allowed to use it for anything you -like, except selling it for profit or claiming it’s authorship. You can read -the entire license text here.

+GNU Lesser General Public License. You +can read the entire license text +here.

@@ -210,7 +209,9 @@ the entire license text here

Installing the calendar used to be quite a task until version 0.9.3. Starting with 0.9.3 I have included the file calendar-setup.js whose goal is to -assist you to setup a popup or flat calendar within minutes.

+assist you to setup a popup or flat calendar in minutes. You are +encouraged to modify this file and not calendar.js if you need +extra customization, but you’re on your own.

First you have to include the needed scripts and style-sheet. Make sure you do this in your document’s <head> section, also make sure you put the @@ -344,11 +345,11 @@ warning message saying that there’s nothing to setup.

ifFormat string The format string that will be used to enter the date in the input field. This format will be honored even if the input field is hidden. -“y/mm/dd” +“%Y/%m/%d” daFormat string Format of the date displayed in the displayArea (if specified). -“y/mm/dd” +“%Y/%m/%d” singleClick boolean Wether the calendar is in “single-click mode” or “double-click mode”. If true (the default) the calendar will be created in single-click mode. @@ -357,11 +358,28 @@ warning message saying that there’s nothing to setup.

disableFunc function A function that receives a JS Date object. It should return true if that date has to be disabled, false otherwise. +DEPRECATED (see below). +null + +dateStatusFunc +function A function that receives a JS Date object and returns a boolean +or a string. This function allows one to set a certain CSS class to some +date, therefore making it look different. If it returns true then +the date will be disabled. If it returns false nothing special +happens with the given date. If it returns a string then that will be taken +as a CSS class and appended to the date element. If this string is +“disabled” then the date is also disabled (therefore is like returning +true). For more information please also refer to section +4.3.8. null mondayFirst -boolean If “true” then the calendar will display with Monday being the first day of week. -false +boolean If true (default) then the calendar will display with +Monday being the first day of week. If false then Sunday will be +the first day of week. This has changed from default false to +default true because the ISO 8601 defines week as starting Monday +and this definition is used for computing the week number. +true weekNumbers boolean If “true” then the calendar will display week numbers. @@ -372,7 +390,7 @@ warning message saying that there’s nothing to setup.

reference element is dynamically chosen like this: if a displayArea is specified then it will be the reference element. Otherwise, the input field is the reference element. For the meaning of the alignment characters -please section 4.3.10. +please section 4.3.11. “Bl” range @@ -382,7 +400,7 @@ please section 4.3.10. flat string If you want a flat calendar, pass the ID of the parent object in this property. If not, pass null here (or nothing at all as -null is the default value. +null is the default value). null flatCallback @@ -391,6 +409,41 @@ will be called when the date in the calendar is changed with a reference to the calendar object. See section 2.2 for an example of how to setup a flat calendar. null + +onSelect +function If you provide a function handler here then you have to manage +the “click-on-date” event by yourself. Look in the calendar-setup.js and +take as an example the onSelect handler that you can see there. +null + +onClose +function This handler will be called when the calendar needs to close. +You don’t need to provide one, but if you do it’s your responsibility to +hide/destroy the calendar. You’re on your own. Check the calendar-setup.js +file for an example. +null + +onUpdate +function If you supply a function handler here, it will be called right +after the target field is updated with a new date. You can use this to +chain 2 calendars, for instance to setup a default date in the second just +after a date was selected in the first. +null + +date +date This allows you to setup an initial date where the calendar will be +positioned to. If absent then the calendar will open to the today date. +null + +showsTime +boolean If this is set to true then the calendar will also +allow time selection. +false + +timeFormat +string Set this to “12” or “24” to configure the way that the +calendar will display time. +“24” @@ -400,7 +453,7 @@ of how to setup a flat calendar.

3  The Calendar object overview

Basically you should be able to setup the calendar with the function presented -in the last section. However, if for some reason Calendar.setup +in the previous section. However, if for some reason Calendar.setup doesn’t provide all the functionality that you need and you want to tweak into the process of creating and configuring the calendar “by hand”, then this section is the way to go.

@@ -417,13 +470,18 @@ calendar, for instance:

cal.weekNumbers = false; // do not display week numbers
-cal.setDateFormat("y.mm.dd"); // set this format: 2003.12.31
-cal.setDisabledHandler(function(date) {
+cal.showsTime = true;    // include a time selector
+cal.setDateFormat("%Y.%m.%d %H:%M"); // set this format: 2003.12.31 23:59
+cal.setDisabledHandler(function(date, year, month, day) {
   // verify date and return true if it has to be disabled
-  if (date.getFullYear() == 2004) {
+  // ``date'' is a JS Date object, but if you only need the
+  // year, month and/or day you can get them separately as
+  // next 3 parameters, as you can see in the declaration
+  if (year == 2004) {
     // disable all dates from 2004
-    return false;
+    return true;
   }
+  return false;
 });
 

@@ -437,7 +495,8 @@ that you provided.

3.1  Creating a calendar

The calendar is created by following some steps (even the function Calendar.setup, described in section 2, does the -same):

+same). While you can skip optional (marked “opt”) steps if you’re happy with +the defaults, please respect the order below.

    @@ -446,22 +505,31 @@ same):

    section 4.1.

    -
  1. optional   Set the weekNumbers property to false if you don’t want -the calendar to display week numbers. This step must take place before -calling Calendar.create.

    +
  2. opt   Set the weekNumbers property to false if you don’t want +the calendar to display week numbers.

    -
  3. optional   Set the range of years available for selection (see section -4.3.14). The default range is [1970..2050].

    +
  4. opt   Set the showsTime property to true if you +want the calendar to also provide a time selector.

    -
  5. optional   Set the disabledHandler property. You should pass +

  6. opt   Set the time24 property to false if you want +the time selector to be in 12-hour format. Default is 24-hour format. This +property only has effect if you also set showsTime to +true.

    +

    +

    +
  7. opt   Set the range of years available for selection (see section +4.3.15). The default range is [1970..2050].

    +

    +

    +
  8. opt   Set the getDateStatus property. You should pass here a function that receives a JavaScript Date object and returns true if the given date should be disabled, false otherwise (details in section 4.3.7).

    -
  9. optional   Set a date format. Your handler function, passed to the +

  10. opt   Set a date format. Your handler function, passed to the calendar constructor, will be called when a date is selected with a reference to the calendar and a date string in this format.

    @@ -472,11 +540,11 @@ practically puts the calendar in your HTML page. You simply call create a flat calendar (details in section 4.3.1).

    -
  11. optional   Initialize the calendar to a certain date, for instance from +

  12. opt   Initialize the calendar to a certain date, for instance from the input field.

    -
  13. Show the calendar (details in section 4.3.8).

    +
  14. Show the calendar (details in section 4.3.9).

@@ -549,6 +617,13 @@ Calendar object. When the end-user closes the calendar, our code will only call “hide” on it, therefore keeping the JavaScript object and the HTML elements in place.

+CAVEAT:     Since time selection support was introduced, this +“object caching” mechanism has the following drawback: if you once created +the calendar with the time selection support, then other items that may not +require this functionality will still get a calendar with the time selection +support enabled. And reciprocal. ;-) Hopefully this will be corrected in a +later version, but for now it doesn’t seem such a big problem.

+

3.4  Callback functions

You might rightfully wonder how is the calendar related to the input field? @@ -577,10 +652,14 @@ user’s responsibility to close the calendar. Details in section 4.1.

-
  • disabledHandler   — this function gets called for any day in a month, +

  • getDateStatus   — this function gets called for any day in a month, just before displaying the month. It is called with a JavaScript Date -object and should return true if that date should be disabled -or false otherwise. Details in section 4.3.7.

    +object and should return true if that date should be disabled, false +if it’s an ordinary date and no action should be taken, or it can return a +string in which case the returned value will be appended to the element’s CSS +class (this way it provides a powerful way to make some dates “special”, +i.e. highlight them differently). Details in section +4.3.8.

    @@ -704,6 +783,14 @@ displays week numbers. If you don’t want week numbers you have to set thi variable to false before calling Calendar.create.

    +
  • showsTime – if you set this to true (it is +false by default) then the calendar will also include a time selector.

    +

    +

    +
  • time24 – if you set this to false then the time +selector will be in 12-hour format. It is in 24-hour format by default.

    +

    +

  • mondayFirst — if true then the calendar uses Monday as first day of week, otherwise Sunday. This variable is set from constructor, but you still have a chance to modify it before calling @@ -777,7 +864,7 @@ This function configures the format in which the calendar reports the date to your “onSelect” handler. Call it like this:

    -
    calendar.setDateFormat("y/mm/dd");
    +
    calendar.setDateFormat("%y/%m/%d");
     

    As you can see, it receives only one parameter, the required format. The magic @@ -785,27 +872,38 @@ characters are the following:

    - - - - - - - - - - - - - -
    d the date ( ex: 1 .. 31 )
    dd the date, zero padded ( ex: 01 .. 31 )
    m month as a number ( ex: 1 .. 12 )
    mm month, zero padded ( ex: 01 .. 12 )
    y 4 digit year ( ex: 1979 )
    yy 2 digit year, yy - 1900 ( ex: 79 ) (USING THIS IS NOT RECOMMENDED)
    w the number of the week in the year (1 or 2 digits)
    ww the number of the week, zero padded (2 digits)
    D short weekday name ( ex: Sun, Wed, Fri )
    DD long weekday name ( ex: Sunday, Wednesday, Friday )
    M short month name ( ex: Mar, Jan, Oct )
    MM long month name ( ex: March, January, October )

    -WARNING!    The format specifiers are likely to change. -The current is a complete mess, in that that, for instance, you can’t have a -format like this: “ymmdd”—you have to separate them through non-word -characters, like for example “y-mm-dd”. In next versions of calendar the -format will probably use a “%” prefix, like in strftime from -ANSI-C, so the format above will be possible to write like this: -“%y%mm%dd”.

    +%a abbreviated weekday name +%A full weekday name +%b abbreviated month name +%B full month name +%C century number +%d the day of the month ( 00 .. 31 ) +%e the day of the month ( 0 .. 31 ) +%H hour ( 00 .. 23 ) +%I hour ( 01 .. 12 ) +%j day of the year ( 000 .. 366 ) +%k hour ( 0 .. 23 ) +%l hour ( 1 .. 12 ) +%m month ( 01 .. 12 ) +%M minute ( 00 .. 59 ) +%n a newline character +%p “PM” or “AM” +%P “pm” or “am” +%S second ( 00 .. 59 ) +%s number of seconds since Epoch (since Jan 01 1970 00:00:00 UTC) +%t a tab character +%U, %W, %V the week number +%u the day of the week ( 1 .. 7, 1 = MON ) +%w the day of the week ( 0 .. 6, 0 = SUN ) +%y year without the century ( 00 .. 99 ) +%Y year including the century ( ex. 1979 ) +%% a literal % character +

    +There are more algorithms for computing the week number. All +three specifiers currently implement the same one, as defined by ISO 8601: +“the week 01 is the week that has the Thursday in the current year, which is +equivalent to the week that contains the fourth day of January. Weeks start on +Monday.

    @@ -849,9 +947,74 @@ that it’s still good, but in the future I might switch it to a different d (for instance, to call it once per month and to return an array of dates that must be disabled).

    +This function should be considered deprecated in the favor of +Calendar.setDateStatusHandler, described below.

    +

    -

    4.3.8  Calendar.show

    +

    4.3.8  Calendar.setDateStatusHandler

    +

    +This function obsoletes Calendar.setDisabledHandler. You call it with +a function parameter, but this function can return a boolean +or a string. If the return value is a boolean (true or +false) then it behaves just like setDisabledHandler, +therefore disabling the date if the return value is true.

    +

    +If the returned value is a string then the given date will gain an additional +CSS class, namely the returned value. You can use this to highlight some dates +in some way. Note that you are responsible for defining the CSS class that you +return. If you return the string “disabled” then that date will be disabled, +just as if you returned true.

    +

    +Here is a simple scenario that shows what you can do with this function. The +following should be present in some of your styles, or in the document head in +a STYLE tag (but put it after the place where the calendar styles were +loaded):

    +

    +

    +
    .special { background-color: #000; color: #fff; }
    +

    +

    +And you would use the following code before calling Calendar.create():

    +

    +

    +
    // this table holds your special days, so that we can automatize
    +// things a bit:
    +var SPECIAL_DAYS = {
    +    0 : [ 13, 24 ],             // special days in January
    +    2 : [ 1, 6, 8, 12, 18 ],    // special days in March
    +    8 : [ 21, 11 ],             // special days in September
    +   11 : [ 25, 28 ]              // special days in December
    +};
    +
    +// this function returns true if the passed date is special
    +function dateIsSpecial(year, month, day) {
    +    var m = SPECIAL_DAYS[month];
    +    if (!m) return false;
    +    for (var i in m) if (m[i] == day) return true;
    +    return false;
    +}
    +
    +// this is the actual date status handler.  Note that it receives the
    +// date object as well as separate values of year, month and date, for
    +// your confort.
    +function dateStatusHandler(date, y, m, d) {
    +    if (dateIsSpecial(y, m, d)) return ``special'';
    +    else return false;
    +    // return true above if you want to disable other dates
    +}
    +
    +// configure it to the calendar
    +calendar.setDateStatusHandler(dateStatusHandler);
    +

    +

    +The above code adds the “special” class name to some dates that are defined +in the SPECIAL_DAYS table. Other dates will simply be displayed as default, +enabled.

    +

    +

    + +

    4.3.9  Calendar.show

    Call this function do show the calendar. It basically sets the CSS “display” property to “block”. It doesn’t modify the calendar position.

    @@ -859,8 +1022,8 @@ property to “block”. It doesn’t modify the calendar position. This function only makes sense when the calendar is in popup mode.

    - -

    4.3.9  Calendar.showAt

    + +

    4.3.10  Calendar.showAt

    Call this to show the calendar at a certain (x, y) position. Prototype:

    @@ -876,8 +1039,8 @@ After setting the given coordinates it calls Calendar.show. This function only makes sense when the calendar is in popup mode.

    - -

    4.3.10  Calendar.showAtElement

    + +

    4.3.11  Calendar.showAtElement

    This function is useful if you want to display the calendar near some element. You call it like this:

    @@ -967,8 +1130,8 @@ calendar aligned to the right margin of the element).

    0.9.3) which did not support custom alignment.

    - -

    4.3.11  Calendar.setDate

    + +

    4.3.12  Calendar.setDate

    Receives a JavaScript Date object. Sets the given date in the calendar. If the calendar is visible the new date is displayed immediately.

    @@ -978,8 +1141,8 @@ calendar. If the calendar is visible the new date is displayed immediately.

    - -

    4.3.12  Calendar.setMondayFirst

    + +

    4.3.13  Calendar.setMondayFirst

    Changes the first day of week. If the parameter is true then Monday will be the first day of week, otherwise Sunday.

    @@ -989,8 +1152,8 @@ will be the first day of week, otherwise Sunday.

    - -

    4.3.13  Calendar.parseDate

    + +

    4.3.14  Calendar.parseDate

    Use this function to parse a date given as string and to move the calendar to that date.

    @@ -1004,8 +1167,8 @@ tries to get some valid date out of it (it doesn’t read your thoughts, tho

    - -

    4.3.14  Calendar.setRange

    + +

    4.3.15  Calendar.setRange

    Sets the range of years that are allowed in the calendar. Synopsis:

    @@ -1075,15 +1238,18 @@ specified in section 4.3.5.

    -

    6  Sponsors

    The following people either sponsored, donated money to the project or bought -developer licenses (listed in reverse chronological order). Your name could be here -too! If you wish to sponsor the project (for instance request a feature and -pay me for implementing it) or donate some money please +

    6  Credits

    The following people either sponsored, donated money to the project or bought +commercial licenses (listed in reverse chronological order). Your name could +be here too! If you wish to sponsor the project (for instance request a +feature and pay me for implementing it) or donate some money please please contact me at mishoo@infoiasi.ro.

      +
    • Himanshukumar Shah

      +

      +

    • Seyhan Ersoy (http://www.oocgi.com)

      @@ -1117,7 +1283,7 @@ in other supported browsers.

      4 user interface

      -Last modified: Mon, July 7, 2003, 5:18 pm
      +Last modified: Wed, Nov 5, 2003, 7:30 pm
      HTML conversion by TeX2page 4r8f
      diff --git a/phpgwapi/js/jscalendar/doc/reference.pdf b/phpgwapi/js/jscalendar/doc/reference.pdf index 544db53ded..31d569803a 100644 Binary files a/phpgwapi/js/jscalendar/doc/reference.pdf and b/phpgwapi/js/jscalendar/doc/reference.pdf differ diff --git a/phpgwapi/js/jscalendar/cal.html b/phpgwapi/js/jscalendar/index.html similarity index 61% rename from phpgwapi/js/jscalendar/cal.html rename to phpgwapi/js/jscalendar/index.html index 8ea6b9506f..2690fb3b66 100644 --- a/phpgwapi/js/jscalendar/cal.html +++ b/phpgwapi/js/jscalendar/index.html @@ -1,13 +1,10 @@ - - + + + + The Coolest DHTML Calendar - Online Demo @@ -18,20 +15,12 @@ - - - - - - - - @@ -69,21 +58,27 @@ function selected(cal, date) { // destroying it. function closeHandler(cal) { cal.hide(); // hide the calendar + cal.destroy(); + calendar = null; } // This function shows the calendar under the element having the given id. // It takes care of catching "mousedown" signals on document and hiding the // calendar if the click was outside. -function showCalendar(id, format) { +function showCalendar(id, format, showsTime) { var el = document.getElementById(id); if (calendar != null) { // we already have some calendar created calendar.hide(); // so we hide it first. } else { // first-time call, create the calendar. - var cal = new Calendar(false, null, selected, closeHandler); + var cal = new Calendar(true, null, selected, closeHandler); // uncomment the following line to hide the week numbers // cal.weekNumbers = false; + if (typeof showsTime == "string") { + cal.showsTime = true; + cal.time24 = (showsTime == "24"); + } calendar = cal; // remember it in the global var cal.setRange(1900, 2070); // min/max year allowed. cal.create(); @@ -129,14 +124,14 @@ function showFlatCalendar() { var parent = document.getElementById("display"); // construct a calendar giving only the "selected" handler. - var cal = new Calendar(false, null, flatSelected); + var cal = new Calendar(true, null, flatSelected); // hide week numbers cal.weekNumbers = false; // We want some dates to be disabled; see function isDisabled above cal.setDisabledHandler(isDisabled); - cal.setDateFormat("DD, M d"); + cal.setDateFormat("%A, %B %e"); // this call must be the last as it might use data initialized above; if // we specify a parent, as opposite to the "showCalendar" function above, @@ -151,7 +146,8 @@ function showFlatCalendar() { -

      jscalendar-0.9.3 release notes

      +

      jscalendar release notes

      -

      This release compiled at Wednesday, 9 Jul 2003 (00:39).

      +

      This release compiled at Wednesday, 5 Nov 2003 (19:30).

      + +

      0.9.5

      + +

      + This release's primary goal is to fix a wrong license statement which + can be found in some files from 0.9.4. For instance in README or + calendar.js, the statement was that the code is distributed under the + GNU GPL; that's because I had plans to change the license, then + changed my mind but unfortunately I committed files so. I am sorry + for this inconvenience, please use the latest (0.9.5) release which is + fully covered by LGPL. +

      + +

      Other changes:

      + +
        + +
      • + Fixed an annoying bug that prevented the calendar to display + correctly when it was configured for an input field inside a + scrolling area. Many thanks to Ian Barrack (Simban.com) who pointed it up and + donated quote some money for the Calendar project! +
      • + +
      • + All examples use UTF-8 now; the translations may not be all + up-to-date, but I strongly suggest everyone to use + UTF-8; other encodings are a plain mess. So far I know for sure + that Romanian translation will work with UTF-8 and not + anymore with ISO-8859-2. Other translations are probably + usable under UTF-8, but if your preferred language isn't... ;-) + please make it and send it to me for inclusion. +
      • + +
      • + Fixed small bug in the documentation (one footnote didn't appear + where it should have). +
      • + +
      • + Updated translations: DE, ES, HU, IT, RO. Thanks to everyone who + sent translations! +
      • + +
      + +

      0.9.4

      + +

      New stuff

      + +
        + +
      • Supports time selection. Yes. ;-) This work has been largely + sponsored by Himanshukumar Shah (thank you!). See + the docs and example files for details on how to setup.
      • + +
      • Easy to link 2 or more fields by using the new + onUpdate parameter of Calendar.setup. This + is useful, say, to automatically set a value in a second field based + on the value selected in the first field. See the documentation and + first sample in simple-1.html.
      • + +
      • Other Calendar.setup low-level parameters, for those + wanting to have the complete control: onSelect and + onClose. The handlers are called when something is + selected in the calendar or when the calendar is closed.
      • + +
      • The translation files can optionally include the short day names + and the short month names. That's because in some languages, like + German, the short form is not the first 3 letters of the entire name + but only the first 2. Also in other languages short names can't be + as easily derived from the full name by just calling substr, so this + patch solves the problem.
      • + +
      • Implemented a nice way to make some dates "special" (look + different). Specifically, the setDisabledHandler method + was replaced with the more general setDateStatusHandler + method (the old one is still available for backwards compatibility but + will be removed). More details about this in the + documentation. Also see simple-3.html + for a live sample.
      • + +
      • Date parsing and formatting engine is now rewritten and supports a + subset of strftime format specifiers from ANSI C. This + makes it possible to use dates like "YYYYMMDD" (the corresponding + format for this would be "%Y%m%d"). Details in the documentation. + Please note that the new engine is not compatibile with older + calendar releases!
      • + +
      • Along with the new date parser I workarounded an unpleasant crash + that occurred in IE when certain accented characters appeared in the + texts. I think German was one of the language with such problems, and + the workaround was to use the letter without an accent. Well, now you + can translate to whatever you want.
      • + +
      • "Fixes" (I mean, "horrible workarounds") for Konqueror (and + hopefully Safari). Unfortunately, this otherwise excellent browser + still has some bugs that keep the calendar from working + exactly as it should.. But they're going to be fixed, + right? ;-)
      • + +
      • CSS themes got pretty much modified too so if you wrote your theme + you need to update it. Aside for the time selector support, the CSS + themes contain a simple hack that makes the navigation buttons show + a little arrow in the lower-right corner which indicates that if one + holds the mouse a menu will appear.
      • + +
      + +

      Translation files

      + +

      The translation files need to be updated in order for the calendar to + work properly. Currently the only updated files are calendar-en.js + (main file) and calendar-ro.js (well, yes, I am a Romanian ;-).

      + +

      Specifically, they need the following:

      + +
        + +
      • Correct date format, according with the new format specifiers + introduced in 0.9.4. Details about the available format specifiers + in the documentation
      • + +
      • Short day or month names, if required. If they can be + derived by taking the first N letters of the full name then a simple + Calendar._SDN_len = N or Calendar._SMN_len = N will suffice. If N + is 3 then nothing needs to be done as we take it for granted if no + other option is offered ;-)
      • + +
      • We have some new texts that shows short usage information as well + as copyright information.
      • + +
      + +

      If your favorite language is not there yet, or it is but not updated + according to the main calendar-en.js file, then please consider + translating calendar-en.js and send the translation back to me so that + I include it in the official distribution.

      + +

      Bug status

      + +

      Check SourceForge, + I didn't keep track. However, there were a lot of bugfixes.

      + +

      0.9.3

      New stuff

      @@ -68,10 +221,10 @@
      -
      Mihai Bazon
      +
      Mihai Bazon
      -Last modified on Tue Jul 8 21:52:23 2003 +Last modified on Wed Oct 29 02:37:07 2003 diff --git a/phpgwapi/js/jscalendar/simple-1.html b/phpgwapi/js/jscalendar/simple-1.html index 779f3f9dec..b53a5e62fb 100644 --- a/phpgwapi/js/jscalendar/simple-1.html +++ b/phpgwapi/js/jscalendar/simple-1.html @@ -1,6 +1,7 @@ + Simple calendar setups [popup calendar] @@ -46,21 +47,48 @@
      -

      Basic setup: one input field only. Clicking in the input field -activates the calendar. Default date format is "y/mm/dd". The calendar -defaults to "single-click mode".

      +

      Basic setup: one input per calendar. Clicking in the input field +activates the calendar. The date format is "%m/%d/%Y %I:%M %p". The +calendar defaults to "single-click mode".

      -

      Note: for some reason this example works -only with Mozilla. It seems that IE and Opera can't set the onclick handler -correctly for the input field.

      +

      The example below has been updated to show you how to create "linked" +fields. Basically, when some field is filled with a date, the other +is updated so that the difference between them remains one week. The +property useful here is "onUpdate".

      +
      @@ -79,7 +107,8 @@ is explicitely set to false).

      diff --git a/phpgwapi/js/jscalendar/simple-2.html b/phpgwapi/js/jscalendar/simple-2.html index 8c41504f85..b55bae85b8 100644 --- a/phpgwapi/js/jscalendar/simple-2.html +++ b/phpgwapi/js/jscalendar/simple-2.html @@ -1,6 +1,7 @@ + Simple calendar setup [flat calendar] diff --git a/phpgwapi/js/jscalendar/simple-3.html b/phpgwapi/js/jscalendar/simple-3.html new file mode 100644 index 0000000000..c096e872bd --- /dev/null +++ b/phpgwapi/js/jscalendar/simple-3.html @@ -0,0 +1,130 @@ + + + + + +Simple calendar setup [flat calendar] + + + + + + + + + + + + + + + + + + + +

      DHTML Calendar — for the impatient

      + +
      +

      + This page demonstrates how to setup a flat calendar. Examples of + popup calendars are available in another page. +

      +

      + The code in this page uses a helper function defined in + "calendar-setup.js". With it you can setup the calendar in + minutes. If you're not that impatient, ;-) complete documenation is + available. +

      +
      + + + +
      + +
      + + + +

      The positioning of the DIV that contains the calendar is entirely your +job. For instance, the "calendar-container" DIV from this page has the +following style: "float: right; margin-left: 1em; margin-bottom: 1em".

      + +

      Following there is the code that has been used to create this calendar. +You can find the full description of the Calendar.setup() function +in the calendar documenation.

      + +
      <div style="float: right; margin-left: 1em; margin-bottom: 1em;"
      +id="calendar-container"></div>
      +
      +<script type="text/javascript">
      +  function dateChanged(calendar) {
      +    // Beware that this function is called even if the end-user only
      +    // changed the month/year.  In order to determine if a date was
      +    // clicked you can use the dateClicked property of the calendar:
      +    if (calendar.dateClicked) {
      +      // OK, a date was clicked, redirect to /yyyy/mm/dd/index.php
      +      var y = calendar.date.getFullYear();
      +      var m = calendar.date.getMonth();     // integer, 0..11
      +      var d = calendar.date.getDate();      // integer, 1..31
      +      // redirect...
      +      window.location = "/" + y + "/" + m + "/" + d + "/index.php";
      +    }
      +  };
      +
      +  Calendar.setup(
      +    {
      +      flat         : "calendar-container", // ID of the parent element
      +      flatCallback : dateChanged           // our callback function
      +    }
      +  );
      +</script>
      + + + diff --git a/phpgwapi/js/jscalendar/simple-4.html b/phpgwapi/js/jscalendar/simple-4.html new file mode 100644 index 0000000000..db84b28dab --- /dev/null +++ b/phpgwapi/js/jscalendar/simple-4.html @@ -0,0 +1,330 @@ + + + + +Simple calendar setups [popup calendar] + + + + + + + + + + + + + + + + + + + + + +
      + +

      DHTML Calendar — for the impatient

      + +
      +

      + This page lists some common setups for the popup calendar. In + order to see how to do any of them please see the source of this + page. For each example it's structured like this: there's the + <form> that contains the input field, and following there is + the JavaScript snippet that setups that form. An example of + flat calendar is available in another page. +

      +

      + The code in this page uses a helper function defined in + "calendar-setup.js". With it you can setup the calendar in + minutes. If you're not that impatient, ;-) complete documenation is + available. +

      +
      + + + +
      + +

      Basic setup: one input per calendar. Clicking in the input field +activates the calendar. The date format is "%m/%d/%Y %I:%M %p". The +calendar defaults to "single-click mode".

      + +

      The example below has been updated to show you how to create "linked" +fields. Basically, when some field is filled with a date, the other +is updated so that the difference between them remains one week. The +property useful here is "onUpdate".

      + +
      + + +
      + + + + + +
      + +

      Input field with a trigger button. Clicking the button activates +the calendar. Note that this one needs double-click (singleClick parameter +is explicitely set to false).

      + +
      + +
      + + + + + +
      + +

      Input field with a trigger image. Note that the Calendar.setup +function doesn't care if the trigger is a button, image, or anything else. +Also in this example we setup a different alignment, just to show how it's +done. The input field is read-only (that is set from HTML).

      + +
      + + + +
      +
      + + + + + +
      + +

      Hidden field, display area. The calendar now puts the date into 2 +elements: one is an input field of type "hidden"—so that the user +can't directly see or modify it— and one is a <span> element in +which the date is displayed. Note that if the trigger is not specified the +calendar will use the displayArea (or inputField as in the first example). +The display area can have it's own format. This is useful if, for instance, +we need to store one format in the database (thus pass it in the input +field) but we wanna show a friendlier format to the end-user.

      + +
      + +
      + +

      Your birthday: + Click to open date selector.

      + + + + + +
      + +

      Hidden field, display area, trigger image. Very similar to the +previous example. The difference is that we also have a trigger image.

      + +
      + +
      + +

      Your birthday: -- not entered -- .

      + + + + + +
      + +

      Hidden field, display area. Very much like the previous examples, +but we now disable some dates (all weekends, that is, Saturdays and +Sundays).

      + +
      + +
      + +

      Your birthday: + Click to open date selector.

      + + +
      +
      + +
      + + +