diff options
Diffstat (limited to 'httemplate/elements')
56 files changed, 4491 insertions, 766 deletions
diff --git a/httemplate/elements/calendar-en.js b/httemplate/elements/calendar-en.js index e9d6a222e..0dbde793d 100644 --- a/httemplate/elements/calendar-en.js +++ b/httemplate/elements/calendar-en.js @@ -1,7 +1,7 @@ // ** I18N // Calendar EN language -// Author: Mihai Bazon, <mishoo@infoiasi.ro> +// Author: Mihai Bazon, <mihai_bazon@yahoo.com> // Encoding: any // Distributed under the same terms as the calendar itself. @@ -43,6 +43,10 @@ Calendar._SDN = new Array "Sat", "Sun"); +// First day of the week. "0" means display Sunday first, "1" means display +// Monday first, etc. +Calendar._FD = 0; + // full month names Calendar._MN = new Array ("January", @@ -79,8 +83,8 @@ Calendar._TT["INFO"] = "About the calendar"; 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" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + "\n\n" + "Date selection:\n" + diff --git a/httemplate/elements/calendar-setup.js b/httemplate/elements/calendar-setup.js index 55e22b933..b27d9bed0 100644 --- a/httemplate/elements/calendar-setup.js +++ b/httemplate/elements/calendar-setup.js @@ -19,7 +19,7 @@ * than modifying calendar.js itself). */ -// $Id: calendar-setup.js,v 1.4 2004-09-22 11:04:41 ivan Exp $ +// $Id: calendar-setup.js,v 1.5 2006-02-09 07:18:08 ivan Exp $ /** * This function "patches" an input field (or other element) to use a calendar @@ -71,7 +71,8 @@ Calendar.setup = function (params) { param_default("singleClick", true); param_default("disableFunc", null); param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined - param_default("firstDay", 0); // defaults to "Sunday" first + param_default("dateText", null); + param_default("firstDay", null); param_default("align", "Br"); param_default("range", [1900, 2999]); param_default("weekNumbers", true); @@ -88,6 +89,7 @@ Calendar.setup = function (params) { param_default("position", null); param_default("cache", false); param_default("showOthers", false); + param_default("multiple", null); var tmp = ["inputField", "displayArea", "button"]; for (var i in tmp) { @@ -95,7 +97,7 @@ Calendar.setup = function (params) { params[tmp[i]] = document.getElementById(params[tmp[i]]); } } - if (!(params.flat || params.inputField || params.displayArea || params.button)) { + if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) { alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code"); return false; } @@ -103,13 +105,6 @@ Calendar.setup = function (params) { function onSelect(cal) { var p = cal.params; var update = (cal.dateClicked || p.electric); - if (update && p.flat) { - if (typeof p.flatCallback == "function") - p.flatCallback(cal); - else - alert("No flatCallback given -- doing nothing."); - return false; - } if (update && p.inputField) { p.inputField.value = cal.date.print(p.ifFormat); if (typeof p.inputField.onchange == "function") @@ -117,10 +112,14 @@ Calendar.setup = function (params) { } if (update && p.displayArea) p.displayArea.innerHTML = cal.date.print(p.daFormat); - if (update && p.singleClick && cal.dateClicked) - cal.callCloseHandler(); if (update && typeof p.onUpdate == "function") p.onUpdate(cal); + if (update && p.flat) { + if (typeof p.flatCallback == "function") + p.flatCallback(cal); + } + if (update && p.singleClick && cal.dateClicked) + cal.callCloseHandler(); }; if (params.flat != null) { @@ -131,12 +130,20 @@ Calendar.setup = function (params) { return false; } var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect); + cal.showsOtherMonths = params.showOthers; 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.getDateText = params.dateText; + if (params.ifFormat) { + cal.setDateFormat(params.ifFormat); + } + if (params.inputField && typeof params.inputField.value == "string") { + cal.parseDate(params.inputField.value); + } cal.create(params.flat); cal.show(); return false; @@ -148,6 +155,8 @@ Calendar.setup = function (params) { var dateFmt = params.inputField ? params.ifFormat : params.daFormat; var mustCreate = false; var cal = window.calendar; + if (dateEl) + params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt); if (!(cal && params.cache)) { window.calendar = cal = new Calendar(params.firstDay, params.date, @@ -162,15 +171,23 @@ Calendar.setup = function (params) { cal.setDate(params.date); cal.hide(); } + if (params.multiple) { + cal.multiple = {}; + for (var i = params.multiple.length; --i >= 0;) { + var d = params.multiple[i]; + var ds = d.print("%Y%m%d"); + cal.multiple[ds] = d; + } + } cal.showsOtherMonths = params.showOthers; cal.yearStep = params.step; cal.setRange(params.range[0], params.range[1]); cal.params = params; cal.setDateStatusHandler(params.dateStatusFunc); + cal.getDateText = params.dateText; cal.setDateFormat(dateFmt); if (mustCreate) cal.create(); - cal.parseDate(dateEl.value || dateEl.innerHTML); cal.refresh(); if (!params.position) cal.showAtElement(params.button || params.displayArea || params.inputField, params.align); @@ -178,4 +195,6 @@ Calendar.setup = function (params) { cal.showAt(params.position[0], params.position[1]); return false; }; + + return cal; }; diff --git a/httemplate/elements/calendar-win2k-2.css b/httemplate/elements/calendar-win2k-2.css index 6001cfaa4..6f37b7dcd 100644 --- a/httemplate/elements/calendar-win2k-2.css +++ b/httemplate/elements/calendar-win2k-2.css @@ -206,6 +206,7 @@ background: #e4d8e0; font-size: 90%; padding: 1px; + z-index: 100; } .calendar .combo .label, diff --git a/httemplate/elements/calendar.js b/httemplate/elements/calendar.js index ec18d80ce..f5c74f608 100644 --- a/httemplate/elements/calendar.js +++ b/httemplate/elements/calendar.js @@ -1,16 +1,18 @@ -/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ - * ------------------------------------------------------------------ +/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo + * ----------------------------------------------------------- * - * The DHTML Calendar, version 0.9.6 "Keep cool but don't freeze" + * The DHTML Calendar, version 1.0 "It is happening again" * * Details and latest version at: - * http://dynarch.com/mishoo/calendar.epl + * www.dynarch.com/projects/calendar + * + * This script is developed by Dynarch.com. Visit us at www.dynarch.com. * * 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: calendar.js,v 1.4 2004-09-22 11:04:41 ivan Exp $ +// $Id: calendar.js,v 1.5 2006-02-09 07:18:08 ivan Exp $ /** The Calendar object constructor. */ Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) { @@ -18,6 +20,8 @@ Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) { this.activeDiv = null; this.currentDateEl = null; this.getDateStatus = null; + this.getDateToolTip = null; + this.getDateText = null; this.timeout = null; this.onSelected = onSelected || null; this.onClose = onClose || null; @@ -29,13 +33,15 @@ Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) { this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"]; this.isPopup = true; this.weekNumbers = true; - this.firstDayOfWeek = firstDayOfWeek; // 0 for Sunday, 1 for Monday, etc. + this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc. this.showsOtherMonths = false; this.dateStr = dateStr; this.ar_days = null; this.showsTime = false; this.time24 = true; this.yearStep = 2; + this.hiliteToday = true; + this.multiple = null; // HTML elements this.table = null; this.element = null; @@ -146,20 +152,19 @@ Calendar.addClass = function(el, className) { el.className += " " + className; }; +// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately. Calendar.getElement = function(ev) { - if (Calendar.is_ie) { - return window.event.srcElement; - } else { - return ev.currentTarget; - } + var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget; + while (f.nodeType != 1 || /^div$/i.test(f.tagName)) + f = f.parentNode; + return f; }; Calendar.getTargetElement = function(ev) { - if (Calendar.is_ie) { - return window.event.srcElement; - } else { - return ev.target; - } + var f = Calendar.is_ie ? window.event.srcElement : ev.target; + while (f.nodeType != 1) + f = f.parentNode; + return f; }; Calendar.stopEvent = function(ev) { @@ -295,7 +300,7 @@ Calendar.showYearsCombo = function (fwd) { var show = false; for (var i = 12; i > 0; --i) { if (Y >= cal.minYear && Y <= cal.maxYear) { - yr.firstChild.data = Y; + yr.innerHTML = Y; yr.year = Y; yr.style.display = "block"; show = true; @@ -416,7 +421,7 @@ Calendar.tableMouseOver = function (ev) { } else if ( ++i >= range.length ) i = 0; var newval = range[i]; - el.firstChild.data = newval; + el.innerHTML = newval; cal.onUpdateTime(); } @@ -504,7 +509,7 @@ Calendar.dayMouseDown = function(ev) { Calendar._C = cal; if (el.navtype != 300) with (Calendar) { if (el.navtype == 50) { - el._current = el.firstChild.data; + el._current = el.innerHTML; addEvent(document, "mousemove", tableMouseOver); } else addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver); @@ -541,7 +546,7 @@ Calendar.dayMouseOver = function(ev) { if (el.ttip.substr(0, 1) == "_") { el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1); } - el.calendar.tooltips.firstChild.data = el.ttip; + el.calendar.tooltips.innerHTML = el.ttip; } if (el.navtype != 300) { Calendar.addClass(el, "hilite"); @@ -555,14 +560,13 @@ Calendar.dayMouseOver = function(ev) { Calendar.dayMouseOut = function(ev) { with (Calendar) { var el = getElement(ev); - if (isRelated(el, ev) || _C || el.disabled) { + if (isRelated(el, ev) || _C || el.disabled) return false; - } removeClass(el, "hilite"); - if (el.caldate) { + if (el.caldate) removeClass(el.parentNode, "rowhilite"); - } - el.calendar.tooltips.firstChild.data = _TT["SEL_DATE"]; + if (el.calendar) + el.calendar.tooltips.innerHTML = _TT["SEL_DATE"]; return stopEvent(ev); } }; @@ -577,17 +581,23 @@ Calendar.cellClick = function(el, ev) { 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; + if (cal.currentDateEl) { + Calendar.removeClass(cal.currentDateEl, "selected"); + Calendar.addClass(el, "selected"); + closing = (cal.currentDateEl == el); + if (!closing) { + cal.currentDateEl = el; + } } - cal.date = new Date(el.caldate); + cal.date.setDateOnly(el.caldate); date = cal.date; - newdate = true; + var other_month = !(cal.dateClicked = !el.otherMonth); + if (!other_month && !cal.currentDateEl) + cal._toggleMultipleDate(new Date(date)); + else + newdate = !el.disabled; // a date was clicked - if (!(cal.dateClicked = !el.otherMonth)) + if (other_month) cal._init(cal.firstDayOfWeek, date); } else { if (el.navtype == 200) { @@ -595,7 +605,9 @@ Calendar.cellClick = function(el, ev) { cal.callCloseHandler(); return; } - date = (el.navtype == 0) ? new Date() : new Date(cal.date); + date = new Date(cal.date); + if (el.navtype == 0) + date.setDateOnly(new Date()); // TODAY // 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. @@ -622,7 +634,7 @@ Calendar.cellClick = function(el, ev) { 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 <mishoo@infoiasi.ro> to get it into the distribution ;-)\n\n" + + "and send it back to <mihai_bazon@yahoo.com> to get it into the distribution ;-)\n\n" + "Thank you!\n" + "http://dynarch.com/mishoo/calendar.epl\n"; } @@ -659,7 +671,7 @@ Calendar.cellClick = function(el, ev) { return; case 50: var range = el._range; - var current = el.firstChild.data; + var current = el.innerHTML; for (var i = range.length; --i >= 0;) if (range[i] == current) break; @@ -669,15 +681,13 @@ Calendar.cellClick = function(el, ev) { } else if ( ++i >= range.length ) i = 0; var newval = range[i]; - el.firstChild.data = newval; + el.innerHTML = newval; cal.onUpdateTime(); return; case 0: // TODAY will bring us here - 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. + if ((typeof cal.getDateStatus == "function") && + cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) { return false; } break; @@ -685,14 +695,15 @@ Calendar.cellClick = function(el, ev) { if (!date.equalsTo(cal.date)) { cal.setDate(date); newdate = true; - } + } else if (el.navtype == 0) + newdate = closing = true; } if (newdate) { - cal.callHandler(); + ev && cal.callHandler(); } if (closing) { Calendar.removeClass(el, "hilite"); - cal.callCloseHandler(); + ev && cal.callCloseHandler(); } }; @@ -749,13 +760,7 @@ Calendar.prototype.create = function (_par) { Calendar._add_evs(cell); cell.calendar = cal; cell.navtype = navtype; - if (text.substr(0, 1) != "&") { - cell.appendChild(document.createTextNode(text)); - } - else { - // FIXME: dirty hack for entities - cell.innerHTML = text; - } + cell.innerHTML = "<div unselectable='on'>" + text + "</div>"; return cell; }; @@ -797,11 +802,10 @@ Calendar.prototype.create = function (_par) { if (this.weekNumbers) { cell = Calendar.createElement("td", row); cell.className = "name wn"; - cell.appendChild(document.createTextNode(Calendar._TT["WK"])); + cell.innerHTML = 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; @@ -818,11 +822,9 @@ Calendar.prototype.create = function (_par) { 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); } @@ -845,7 +847,7 @@ Calendar.prototype.create = function (_par) { function makeTimePart(className, init, range_start, range_end) { var part = Calendar.createElement("span", cell); part.className = className; - part.appendChild(document.createTextNode(init)); + part.innerHTML = init; part.calendar = cal; part.ttip = Calendar._TT["TIME_PART"]; part.navtype = 50; @@ -870,7 +872,7 @@ Calendar.prototype.create = function (_par) { 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.innerHTML = ":"; span.className = "colon"; var M = makeTimePart("minute", mins, 0, 59); var AP = null; @@ -883,30 +885,32 @@ Calendar.prototype.create = function (_par) { 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"; + var pm, hrs = this.date.getHours(), + mins = this.date.getMinutes(); + if (t12) { + pm = (hrs >= 12); + if (pm) hrs -= 12; + if (hrs == 0) hrs = 12; + AP.innerHTML = pm ? "pm" : "am"; + } + H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs; + M.innerHTML = (mins < 10) ? ("0" + mins) : mins; }; cal.onUpdateTime = function() { var date = this.date; - var h = parseInt(H.firstChild.data, 10); + var h = parseInt(H.innerHTML, 10); if (t12) { - if (/pm/i.test(AP.firstChild.data) && h < 12) + if (/pm/i.test(AP.innerHTML) && h < 12) h += 12; - else if (/am/i.test(AP.firstChild.data) && h == 12) + else if (/am/i.test(AP.innerHTML) && 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.setMinutes(parseInt(M.innerHTML, 10)); date.setFullYear(y); date.setMonth(m); date.setDate(d); @@ -938,7 +942,7 @@ Calendar.prototype.create = function (_par) { var mn = Calendar.createElement("div"); mn.className = Calendar.is_ie ? "label-IEfix" : "label"; mn.month = i; - mn.appendChild(document.createTextNode(Calendar._SMN[i])); + mn.innerHTML = Calendar._SMN[i]; div.appendChild(mn); } @@ -948,7 +952,6 @@ Calendar.prototype.create = function (_par) { for (i = 12; i > 0; --i) { var yr = Calendar.createElement("div"); yr.className = Calendar.is_ie ? "label-IEfix" : "label"; - yr.appendChild(document.createTextNode("")); div.appendChild(yr); } @@ -958,14 +961,14 @@ Calendar.prototype.create = function (_par) { /** keyboard navigation, only for popup calendars */ Calendar._keyEvent = function(ev) { - if (!window.calendar) { + var cal = window._dynarch_popupCalendar; + if (!cal || cal.multiple) return false; - } (Calendar.is_ie) && (ev = window.event); - var cal = window.calendar; - var act = (Calendar.is_ie || ev.type == "keypress"); + var act = (Calendar.is_ie || ev.type == "keypress"), + K = ev.keyCode; if (ev.ctrlKey) { - switch (ev.keyCode) { + switch (K) { case 37: // KEY left act && Calendar.cellClick(cal._nav_pm); break; @@ -981,7 +984,7 @@ Calendar._keyEvent = function(ev) { default: return false; } - } else switch (ev.keyCode) { + } else switch (K) { case 32: // KEY space (now) Calendar.cellClick(cal._nav_now); break; @@ -993,48 +996,78 @@ Calendar._keyEvent = function(ev) { case 39: // KEY right case 40: // KEY down 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: // KEY left - (--date >= 0) && (ne = cal.ar_days[date]); - break; - case 38: // KEY up - date -= 7; - (date >= 0) && (ne = cal.ar_days[date]); - break; - case 39: // KEY right - (++date < cal.ar_days.length) && (ne = cal.ar_days[date]); - break; - case 40: // KEY down - date += 7; - (date < cal.ar_days.length) && (ne = cal.ar_days[date]); + var prev, x, y, ne, el, step; + prev = K == 37 || K == 38; + step = (K == 37 || K == 39) ? 1 : 7; + function setVars() { + el = cal.currentDateEl; + var p = el.pos; + x = p & 15; + y = p >> 4; + ne = cal.ar_days[y][x]; + };setVars(); + function prevMonth() { + var date = new Date(cal.date); + date.setDate(date.getDate() - step); + cal.setDate(date); + }; + function nextMonth() { + var date = new Date(cal.date); + date.setDate(date.getDate() + step); + cal.setDate(date); + }; + while (1) { + switch (K) { + case 37: // KEY left + if (--x >= 0) + ne = cal.ar_days[y][x]; + else { + x = 6; + K = 38; + continue; + } + break; + case 38: // KEY up + if (--y >= 0) + ne = cal.ar_days[y][x]; + else { + prevMonth(); + setVars(); + } + break; + case 39: // KEY right + if (++x < 7) + ne = cal.ar_days[y][x]; + else { + x = 0; + K = 40; + continue; + } + break; + case 40: // KEY down + if (++y < cal.ar_days.length) + ne = cal.ar_days[y][x]; + else { + nextMonth(); + setVars(); + } + break; + } break; } - if (!ne) { - if (prev) { - Calendar.cellClick(cal._nav_pm); - } else { - Calendar.cellClick(cal._nav_nm); - } - date = (prev) ? cal.date.getMonthDays() : 1; - el = cal.currentDateEl; - ne = cal.ar_days[date - 1]; + if (ne) { + if (!ne.disabled) + Calendar.cellClick(ne); + else if (prev) + prevMonth(); + else + nextMonth(); } - Calendar.removeClass(el, "selected"); - Calendar.addClass(ne, "selected"); - cal.date = new Date(ne.caldate); - cal.callHandler(); - cal.currentDateEl = ne; } break; case 13: // KEY enter - if (act) { - cal.callHandler(); - cal.hide(); - } + if (act) + Calendar.cellClick(cal.currentDateEl, ev); break; default: return false; @@ -1046,7 +1079,10 @@ Calendar._keyEvent = function(ev) { * (RE)Initializes the calendar to the given date and firstDayOfWeek */ Calendar.prototype._init = function (firstDayOfWeek, date) { - var today = new Date(); + var today = new Date(), + TY = today.getFullYear(), + TM = today.getMonth(), + TD = today.getDate(); this.table.style.visibility = "hidden"; var year = date.getFullYear(); if (year < this.minYear) { @@ -1074,21 +1110,24 @@ Calendar.prototype._init = function (firstDayOfWeek, date) { var row = this.tbody.firstChild; var MN = Calendar._SMN[month]; - var ar_days = new Array(); + var ar_days = this.ar_days = new Array(); var weekend = Calendar._TT["WEEKEND"]; + var dates = this.multiple ? (this.datesCells = {}) : null; for (var i = 0; i < 6; ++i, row = row.nextSibling) { var cell = row.firstChild; if (this.weekNumbers) { cell.className = "day wn"; - cell.firstChild.data = date.getWeekNumber(); + cell.innerHTML = date.getWeekNumber(); cell = cell.nextSibling; } row.className = "daysrow"; - var hasdays = false; - for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(date.getDate() + 1)) { - var iday = date.getDate(); + var hasdays = false, iday, dpos = ar_days[i] = []; + for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) { + iday = date.getDate(); var wday = date.getDay(); cell.className = "day"; + cell.pos = i << 4 | j; + dpos[j] = cell; var current_month = (date.getMonth() == month); if (!current_month) { if (this.showsOtherMonths) { @@ -1105,9 +1144,16 @@ Calendar.prototype._init = function (firstDayOfWeek, date) { hasdays = true; } cell.disabled = false; - cell.firstChild.data = iday; - if (typeof this.getDateStatus == "function") { + cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday; + if (dates) + dates[date.print("%Y%m%d")] = cell; + if (this.getDateStatus) { var status = this.getDateStatus(date, year, month, iday); + if (this.getDateToolTip) { + var toolTip = this.getDateToolTip(date, year, month, iday); + if (toolTip) + cell.title = toolTip; + } if (status === true) { cell.className += " disabled"; cell.disabled = true; @@ -1118,33 +1164,66 @@ Calendar.prototype._init = function (firstDayOfWeek, date) { } } if (!cell.disabled) { - ar_days[ar_days.length] = cell; cell.caldate = new Date(date); cell.ttip = "_"; - if (current_month && iday == mday) { + if (!this.multiple && current_month + && iday == mday && this.hiliteToday) { cell.className += " selected"; this.currentDateEl = cell; } - if (date.getFullYear() == today.getFullYear() && - date.getMonth() == today.getMonth() && - iday == today.getDate()) { + if (date.getFullYear() == TY && + date.getMonth() == TM && + iday == TD) { cell.className += " today"; cell.ttip += Calendar._TT["PART_TODAY"]; } - if (weekend.indexOf(wday.toString()) != -1) { + if (weekend.indexOf(wday.toString()) != -1) cell.className += cell.otherMonth ? " oweekend" : " weekend"; - } } } if (!(hasdays || this.showsOtherMonths)) row.className = "emptyrow"; } - this.ar_days = ar_days; - this.title.firstChild.data = Calendar._MN[month] + ", " + year; + this.title.innerHTML = Calendar._MN[month] + ", " + year; this.onSetTime(); this.table.style.visibility = "visible"; + this._initMultipleDates(); // PROFILE - // this.tooltips.firstChild.data = "Generated in " + ((new Date()) - today) + " ms"; + // this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms"; +}; + +Calendar.prototype._initMultipleDates = function() { + if (this.multiple) { + for (var i in this.multiple) { + var cell = this.datesCells[i]; + var d = this.multiple[i]; + if (!d) + continue; + if (cell) + cell.className += " selected"; + } + } +}; + +Calendar.prototype._toggleMultipleDate = function(date) { + if (this.multiple) { + var ds = date.print("%Y%m%d"); + var cell = this.datesCells[ds]; + if (cell) { + var d = this.multiple[ds]; + if (!d) { + Calendar.addClass(cell, "selected"); + this.multiple[ds] = date; + } else { + Calendar.removeClass(cell, "selected"); + delete this.multiple[ds]; + } + } + } +}; + +Calendar.prototype.setDateToolTipHandler = function (unaryFunction) { + this.getDateToolTip = unaryFunction; }; /** @@ -1209,7 +1288,7 @@ Calendar.prototype.destroy = function () { var el = this.element.parentNode; el.removeChild(this.element); Calendar._C = null; - window.calendar = null; + window._dynarch_popupCalendar = null; }; /** @@ -1226,14 +1305,15 @@ Calendar.prototype.reparent = function (new_parent) { // document, if the calendar is shown. If the click was outside the open // calendar this function closes it. Calendar._checkCalendar = function(ev) { - if (!window.calendar) { + var calendar = window._dynarch_popupCalendar; + if (!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) { // calls closeHandler which should hide the calendar. - window.calendar.callCloseHandler(); + window._dynarch_popupCalendar.callCloseHandler(); return Calendar.stopEvent(ev); } }; @@ -1254,7 +1334,7 @@ Calendar.prototype.show = function () { this.element.style.display = "block"; this.hidden = false; if (this.isPopup) { - window.calendar = this; + window._dynarch_popupCalendar = this; Calendar.addEvent(document, "keydown", Calendar._keyEvent); Calendar.addEvent(document, "keypress", Calendar._keyEvent); Calendar.addEvent(document, "mousedown", Calendar._checkCalendar); @@ -1344,8 +1424,8 @@ Calendar.prototype.showAtElement = function (el, opts) { 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 + case "l": p.x += el.offsetWidth - w; break; + case "r": break; // already there } p.width = w; p.height = h + 40; @@ -1373,14 +1453,140 @@ Calendar.prototype.setTtDateFormat = function (str) { * Tries to identify the date represented in a string. If successful it also * calls this.setDate which moves the calendar to the given date. */ -Calendar.prototype.parseDate = function (str, fmt) { +Calendar.prototype.parseDate = function(str, fmt) { + if (!fmt) + fmt = this.dateFormat; + this.setDate(Date.parseDate(str, fmt)); +}; + +Calendar.prototype.hideShowCovered = function () { + if (!Calendar.is_ie && !Calendar.is_opera) + return; + 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 = 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 = 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"; + } + } + } +}; + +/** Internal function; it displays the bar with the names of the weekday. */ +Calendar.prototype._displayWeekdays = function () { + var fdow = this.firstDayOfWeek; + var cell = this.firstdayname; + var weekend = Calendar._TT["WEEKEND"]; + for (var i = 0; i < 7; ++i) { + cell.className = "day name"; + var realday = (i + fdow) % 7; + if (i) { + cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]); + cell.navtype = 100; + cell.calendar = this; + cell.fdow = realday; + Calendar._add_evs(cell); + } + if (weekend.indexOf(realday.toString()) != -1) { + Calendar.addClass(cell, "weekend"); + } + cell.innerHTML = Calendar._SDN[(i + fdow) % 7]; + cell = cell.nextSibling; + } +}; + +/** Internal function. Hides all combo boxes that might be displayed. */ +Calendar.prototype._hideCombos = function () { + this.monthsCombo.style.display = "none"; + this.yearsCombo.style.display = "none"; +}; + +/** Internal function. Starts dragging the element. */ +Calendar.prototype._dragStart = function (ev) { + if (this.dragging) { + return; + } + this.dragging = true; + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posY = ev.clientY + window.scrollY; + posX = ev.clientX + window.scrollX; + } + var st = this.element.style; + this.xOffs = posX - parseInt(st.left); + this.yOffs = posY - parseInt(st.top); + with (Calendar) { + addEvent(document, "mousemove", calDragIt); + addEvent(document, "mouseup", calDragEnd); + } +}; + +// BEGIN: DATE OBJECT PATCHES + +/** Adds the number of days array to the Date object. */ +Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31); + +/** Constants used for time computations */ +Date.SECOND = 1000 /* milliseconds */; +Date.MINUTE = 60 * Date.SECOND; +Date.HOUR = 60 * Date.MINUTE; +Date.DAY = 24 * Date.HOUR; +Date.WEEK = 7 * Date.DAY; + +Date.parseDate = function(str, fmt) { + var today = new Date(); var y = 0; var m = -1; var d = 0; var a = str.split(/\W+/); - if (!fmt) { - fmt = this.dateFormat; - } var b = fmt.match(/%./g); var i = 0, j = 0; var hr = 0; @@ -1422,6 +1628,8 @@ Calendar.prototype.parseDate = function (str, fmt) { case "%p": if (/pm/i.test(a[i]) && hr < 12) hr += 12; + else if (/am/i.test(a[i]) && hr >= 12) + hr -= 12; break; case "%M": @@ -1429,10 +1637,13 @@ Calendar.prototype.parseDate = function (str, fmt) { break; } } - if (y != 0 && m != -1 && d != 0) { - this.setDate(new Date(y, m, d, hr, min, 0)); - return; - } + if (isNaN(y)) y = today.getFullYear(); + if (isNaN(m)) m = today.getMonth(); + if (isNaN(d)) d = today.getDate(); + if (isNaN(hr)) hr = today.getHours(); + if (isNaN(min)) min = today.getMinutes(); + if (y != 0 && m != -1 && d != 0) + return new Date(y, m, d, hr, min, 0); y = 0; m = -1; d = 0; for (i = 0; i < a.length; ++i) { if (a[i].search(/[a-zA-Z]+/) != -1) { @@ -1455,142 +1666,13 @@ Calendar.prototype.parseDate = function (str, fmt) { d = a[i]; } } - if (y == 0) { - var today = new Date(); + if (y == 0) 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") { // 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"; - } - } - } - }; - 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. */ -Calendar.prototype._displayWeekdays = function () { - var fdow = this.firstDayOfWeek; - var cell = this.firstdayname; - var weekend = Calendar._TT["WEEKEND"]; - for (var i = 0; i < 7; ++i) { - cell.className = "day name"; - var realday = (i + fdow) % 7; - if (i) { - cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]); - cell.navtype = 100; - cell.calendar = this; - cell.fdow = realday; - Calendar._add_evs(cell); - } - if (weekend.indexOf(realday.toString()) != -1) { - Calendar.addClass(cell, "weekend"); - } - cell.firstChild.data = Calendar._SDN[(i + fdow) % 7]; - cell = cell.nextSibling; - } -}; - -/** Internal function. Hides all combo boxes that might be displayed. */ -Calendar.prototype._hideCombos = function () { - this.monthsCombo.style.display = "none"; - this.yearsCombo.style.display = "none"; -}; - -/** Internal function. Starts dragging the element. */ -Calendar.prototype._dragStart = function (ev) { - if (this.dragging) { - return; - } - this.dragging = true; - var posX; - var posY; - if (Calendar.is_ie) { - posY = window.event.clientY + document.body.scrollTop; - posX = window.event.clientX + document.body.scrollLeft; - } else { - posY = ev.clientY + window.scrollY; - posX = ev.clientX + window.scrollX; - } - var st = this.element.style; - this.xOffs = posX - parseInt(st.left); - this.yOffs = posY - parseInt(st.top); - with (Calendar) { - addEvent(document, "mousemove", calDragIt); - addEvent(document, "mouseup", calDragEnd); - } + if (m != -1 && d != 0) + return new Date(y, m, d, hr, min, 0); + return today; }; -// BEGIN: DATE OBJECT PATCHES - -/** Adds the number of days array to the Date object. */ -Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31); - -/** Constants used for time computations */ -Date.SECOND = 1000 /* milliseconds */; -Date.MINUTE = 60 * Date.SECOND; -Date.HOUR = 60 * Date.MINUTE; -Date.DAY = 24 * Date.HOUR; -Date.WEEK = 7 * Date.DAY; - /** Returns the number of days in the current month */ Date.prototype.getMonthDays = function(month) { var year = this.getFullYear(); @@ -1623,7 +1705,7 @@ Date.prototype.getWeekNumber = function() { return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1; }; -/** Checks dates equality (ignores time) */ +/** Checks date and time equality */ Date.prototype.equalsTo = function(date) { return ((this.getFullYear() == date.getFullYear()) && (this.getMonth() == date.getMonth()) && @@ -1632,6 +1714,15 @@ Date.prototype.equalsTo = function(date) { (this.getMinutes() == date.getMinutes())); }; +/** Set only the year, month, date parts (keep existing time) */ +Date.prototype.setDateOnly = function(date) { + var tmp = new Date(date); + this.setDate(1); + this.setFullYear(tmp.getFullYear()); + this.setMonth(tmp.getMonth()); + this.setDate(tmp.getDate()); +}; + /** Prints the date in a string according to the given format. */ Date.prototype.print = function (str) { var m = this.getMonth(); @@ -1684,7 +1775,7 @@ Date.prototype.print = function (str) { s["%%"] = "%"; // a literal '%' character var re = /%./g; - if (!Calendar.is_ie5) + if (!Calendar.is_ie5 && !Calendar.is_khtml) return str.replace(re, function (par) { return s[par] || par; }); var a = str.match(re); @@ -1712,4 +1803,4 @@ Date.prototype.setFullYear = function(y) { // global object that remembers the calendar -window.calendar = null; +window._dynarch_popupCalendar = null; diff --git a/httemplate/elements/calendar_stripped.js b/httemplate/elements/calendar_stripped.js index 6a8e326af..4fe03f1ea 100644 --- a/httemplate/elements/calendar_stripped.js +++ b/httemplate/elements/calendar_stripped.js @@ -1,12 +1,14 @@ -/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ - * ------------------------------------------------------------------ +/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo + * ----------------------------------------------------------- * - * The DHTML Calendar, version 0.9.6 "Keep cool but don't freeze" + * The DHTML Calendar, version 1.0 "It is happening again" * * Details and latest version at: - * http://dynarch.com/mishoo/calendar.epl + * www.dynarch.com/projects/calendar + * + * This script is developed by Dynarch.com. Visit us at www.dynarch.com. * * 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(firstDayOfWeek,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.firstDayOfWeek=firstDayOfWeek;this.showsOtherMonths=false;this.dateStr=dateStr;this.ar_days=null;this.showsTime=false;this.time24=true;this.yearStep=2;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_ie5=(Calendar.is_ie&&/msie 5\.0/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=this.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{var mcw=mc.offsetWidth;if(typeof mcw=="undefined")mcw=50;s.left=(cd.offsetLeft+cd.offsetWidth-mcw)+"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?cal.yearStep:-cal.yearStep;}if(show){var s=yc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else{var ycw=yc.offsetWidth;if(typeof ycw=="undefined")ycw=50;s.left=(cd.offsetLeft+cd.offsetWidth-ycw)+"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<0)i=range.length-1;}else if(++i>=range.length)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,"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;addEvent(document,"mousemove",tableMouseOver);}else addEvent(document,Calendar.is_ie5?"mousemove":"mouseover",tableMouseOver);addClass(el,"hilite active");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)=="_"){el.ttip=el.caldate.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=new Date(el.caldate);date=cal.date;newdate=true;if(!(cal.dateClicked=!el.otherMonth))cal._init(cal.firstDayOfWeek,date);}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 <mishoo@infoiasi.ro> 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<cal.maxYear){date.setFullYear(year+1);setMonth(0);}break;case 2:if(year<cal.maxYear){date.setFullYear(year+1);}break;case 100:cal.setFirstDayOfWeek(el.fdow);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<0)i=range.length-1;}else if(++i>=range.length)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=Calendar._TT["TIME"]||" ";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;i<Calendar._MN.length;++i){var mn=Calendar.createElement("div");mn.className=Calendar.is_ie?"label-IEfix":"label";mn.month=i;mn.appendChild(document.createTextNode(Calendar._SMN[i]));div.appendChild(mn);}div=Calendar.createElement("div",this.element);this.yearsCombo=div;div.className="combo";for(i=12;i>0;--i){var yr=Calendar.createElement("div");yr.className=Calendar.is_ie?"label-IEfix":"label";yr.appendChild(document.createTextNode(""));div.appendChild(yr);}this._init(this.firstDayOfWeek,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.callCloseHandler();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:(++date<cal.ar_days.length)&&(ne=cal.ar_days[date]);break;case 40:date+=7;(date<cal.ar_days.length)&&(ne=cal.ar_days[date]);break;}if(!ne){if(prev){Calendar.cellClick(cal._nav_pm);}else{Calendar.cellClick(cal._nav_nm);}date=(prev)?cal.date.getMonthDays():1;el=cal.currentDateEl;ne=cal.ar_days[date-1];}Calendar.removeClass(el,"selected");Calendar.addClass(ne,"selected");cal.date=new Date(ne.caldate);cal.callHandler();cal.currentDateEl=ne;}break;case 13:if(act){cal.callHandler();cal.hide();}break;default:return false;}return Calendar.stopEvent(ev);};Calendar.prototype._init=function(firstDayOfWeek,date){var today=new Date();this.table.style.visibility="hidden";var year=date.getFullYear();if(year<this.minYear){year=this.minYear;date.setFullYear(year);}else if(year>this.maxYear){year=this.maxYear;date.setFullYear(year);}this.firstDayOfWeek=firstDayOfWeek;this.date=new Date(date);var month=date.getMonth();var mday=date.getDate();var no_days=date.getMonthDays();date.setDate(1);var day1=(date.getDay()-this.firstDayOfWeek)%7;if(day1<0)day1+=7;date.setDate(-day1);date.setDate(date.getDate()+1);var row=this.tbody.firstChild;var MN=Calendar._SMN[month];var ar_days=new Array();var weekend=Calendar._TT["WEEKEND"];for(var i=0;i<6;++i,row=row.nextSibling){var cell=row.firstChild;if(this.weekNumbers){cell.className="day wn";cell.firstChild.data=date.getWeekNumber();cell=cell.nextSibling;}row.className="daysrow";var hasdays=false;for(var j=0;j<7;++j,cell=cell.nextSibling,date.setDate(date.getDate()+1)){var iday=date.getDate();var wday=date.getDay();cell.className="day";var current_month=(date.getMonth()==month);if(!current_month){if(this.showsOtherMonths){cell.className+=" othermonth";cell.otherMonth=true;}else{cell.className="emptycell";cell.innerHTML=" ";cell.disabled=true;continue;}}else{cell.otherMonth=false;hasdays=true;}cell.disabled=false;cell.firstChild.data=iday;if(typeof this.getDateStatus=="function"){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=new Date(date);cell.ttip="_";if(current_month&&iday==mday){cell.className+=" selected";this.currentDateEl=cell;}if(date.getFullYear()==today.getFullYear()&&date.getMonth()==today.getMonth()&&iday==today.getDate()){cell.className+=" today";cell.ttip+=Calendar._TT["PART_TODAY"];}if(weekend.indexOf(wday.toString())!=-1){cell.className+=cell.otherMonth?" oweekend":" weekend";}}}if(!(hasdays||this.showsOtherMonths))row.className="emptyrow";}this.ar_days=ar_days;this.title.firstChild.data=Calendar._MN[month]+", "+year;this.onSetTime();this.table.style.visibility="visible";};Calendar.prototype.setDate=function(date){if(!date.equalsTo(this.date)){this._init(this.firstDayOfWeek,date);}};Calendar.prototype.refresh=function(){this._init(this.firstDayOfWeek,this.date);};Calendar.prototype.setFirstDayOfWeek=function(firstDayOfWeek){this._init(firstDayOfWeek,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;}function fixPosition(box){if(box.x<0)box.x=0;if(box.y<0)box.y=0;var cp=document.createElement("div");var s=cp.style;s.position="absolute";s.right=s.bottom=s.width=s.height="0px";document.body.appendChild(cp);var br=Calendar.getAbsolutePos(cp);document.body.removeChild(cp);if(Calendar.is_ie){br.y+=document.body.scrollTop;br.x+=document.body.scrollLeft;}else{br.y+=window.scrollY;br.x+=window.scrollX;}var tmp=box.x+box.width-br.x;if(tmp>0)box.x-=tmp;tmp=box.y+box.height-br.y;if(tmp>0)box.y-=tmp;};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;}p.width=w;p.height=h+40;self.monthsCombo.style.display="none";fixPosition(p);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.match(/%./g);var i=0,j=0;var hr=0;var min=0;for(i=0;i<a.length;++i){if(!a[i])continue;switch(b[i]){case "%d":case "%e":d=parseInt(a[i],10);break;case "%m":m=parseInt(a[i],10)-1;break;case "%Y":case "%y":y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);break;case "%b":case "%B":for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){m=j;break;}}break;case "%H":case "%I":case "%k":case "%l":hr=parseInt(a[i],10);break;case "%P":case "%p":if(/pm/i.test(a[i])&&hr<12)hr+=12;break;case "%M":min=parseInt(a[i],10);break;}}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;i<a.length;++i){if(a[i].search(/[a-zA-Z]+/)!=-1){var t=-1;for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){t=j;break;}}if(t!=-1){if(m!=-1){d=m+1;}m=t;}}else if(parseInt(a[i],10)<=12&&m==-1){m=a[i]-1;}else if(parseInt(a[i],10)>31&&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)||(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";}}}};if(Calendar.is_khtml)setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10);else Calendar.continuation_for_the_fucking_khtml_browser();};Calendar.prototype._displayWeekdays=function(){var fdow=this.firstDayOfWeek;var cell=this.firstdayname;var weekend=Calendar._TT["WEEKEND"];for(var i=0;i<7;++i){cell.className="day name";var realday=(i+fdow)%7;if(i){cell.ttip=Calendar._TT["DAY_FIRST"].replace("%s",Calendar._DN[realday]);cell.navtype=100;cell.calendar=this;cell.fdow=realday;Calendar._add_evs(cell);}if(weekend.indexOf(realday.toString())!=-1){Calendar.addClass(cell,"weekend");}cell.firstChild.data=Calendar._SDN[(i+fdow)%7];cell=cell.nextSibling;}};Calendar.prototype._hideCombos=function(){this.monthsCombo.style.display="none";this.yearsCombo.style.display="none";};Calendar.prototype._dragStart=function(ev){if(this.dragging){return;}this.dragging=true;var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posY=ev.clientY+window.scrollY;posX=ev.clientX+window.scrollX;}var st=this.element.style;this.xOffs=posX-parseInt(st.left);this.yOffs=posY-parseInt(st.top);with(Calendar){addEvent(document,"mousemove",calDragIt);addEvent(document,"mouseup",calDragEnd);}};Date._MD=new Array(31,28,31,30,31,30,31,31,30,31,30,31);Date.SECOND=1000;Date.MINUTE=60*Date.SECOND;Date.HOUR=60*Date.MINUTE;Date.DAY=24*Date.HOUR;Date.WEEK=7*Date.DAY;Date.prototype.getMonthDays=function(month){var year=this.getFullYear();if(typeof month=="undefined"){month=this.getMonth();}if(((0==(year%4))&&((0!=(year%100))||(0==(year%400))))&&month==1){return 29;}else{return Date._MD[month];}};Date.prototype.getDayOfYear=function(){var now=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var then=new Date(this.getFullYear(),0,0,0,0,0);var time=now-then;return Math.floor(time/Date.DAY);};Date.prototype.getWeekNumber=function(){var d=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var DoW=d.getDay();d.setDate(d.getDate()-(DoW+6)%7+3);var ms=d.valueOf();d.setMonth(0);d.setDate(4);return Math.round((ms-d.valueOf())/(7*864e5))+1;};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=/%./g;if(!Calendar.is_ie5)return str.replace(re,function(par){return s[par]||par;});var a=str.match(re);for(var i=0;i<a.length;i++){var tmp=s[a[i]];if(tmp){re=new RegExp(a[i],'g');str=str.replace(re,tmp);}}return str;};Date.prototype.__msh_oldSetFullYear=Date.prototype.setFullYear;Date.prototype.setFullYear=function(y){var d=new Date(this);d.__msh_oldSetFullYear(y);if(d.getMonth()!=this.getMonth())this.setDate(28);this.__msh_oldSetFullYear(y);};window.calendar=null;
\ No newline at end of file + Calendar=function(firstDayOfWeek,dateStr,onSelected,onClose){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.getDateToolTip=null;this.getDateText=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.firstDayOfWeek=typeof firstDayOfWeek=="number"?firstDayOfWeek:Calendar._FD;this.showsOtherMonths=false;this.dateStr=dateStr;this.ar_days=null;this.showsTime=false;this.time24=true;this.yearStep=2;this.hiliteToday=true;this.multiple=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(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_ie5=(Calendar.is_ie&&/msie 5\.0/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=this.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){var f=Calendar.is_ie?window.event.srcElement:ev.currentTarget;while(f.nodeType!=1||/^div$/i.test(f.tagName))f=f.parentNode;return f;};Calendar.getTargetElement=function(ev){var f=Calendar.is_ie?window.event.srcElement:ev.target;while(f.nodeType!=1)f=f.parentNode;return f;};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{var mcw=mc.offsetWidth;if(typeof mcw=="undefined")mcw=50;s.left=(cd.offsetLeft+cd.offsetWidth-mcw)+"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.innerHTML=Y;yr.year=Y;yr.style.display="block";show=true;}else{yr.style.display="none";}yr=yr.nextSibling;Y+=fwd?cal.yearStep:-cal.yearStep;}if(show){var s=yc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else{var ycw=yc.offsetWidth;if(typeof ycw=="undefined")ycw=50;s.left=(cd.offsetLeft+cd.offsetWidth-ycw)+"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<0)i=range.length-1;}else if(++i>=range.length)i=0;var newval=range[i];el.innerHTML=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,"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.innerHTML;addEvent(document,"mousemove",tableMouseOver);}else addEvent(document,Calendar.is_ie5?"mousemove":"mouseover",tableMouseOver);addClass(el,"hilite active");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)=="_"){el.ttip=el.caldate.print(el.calendar.ttDateFormat)+el.ttip.substr(1);}el.calendar.tooltips.innerHTML=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");if(el.calendar)el.calendar.tooltips.innerHTML=_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"){if(cal.currentDateEl){Calendar.removeClass(cal.currentDateEl,"selected");Calendar.addClass(el,"selected");closing=(cal.currentDateEl==el);if(!closing){cal.currentDateEl=el;}}cal.date.setDateOnly(el.caldate);date=cal.date;var other_month=!(cal.dateClicked=!el.otherMonth);if(!other_month&&!cal.currentDateEl)cal._toggleMultipleDate(new Date(date));else newdate=!el.disabled;if(other_month)cal._init(cal.firstDayOfWeek,date);}else{if(el.navtype==200){Calendar.removeClass(el,"hilite");cal.callCloseHandler();return;}date=new Date(cal.date);if(el.navtype==0)date.setDateOnly(new 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 <mihai_bazon@yahoo.com> 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<cal.maxYear){date.setFullYear(year+1);setMonth(0);}break;case 2:if(year<cal.maxYear){date.setFullYear(year+1);}break;case 100:cal.setFirstDayOfWeek(el.fdow);return;case 50:var range=el._range;var current=el.innerHTML;for(var i=range.length;--i>=0;)if(range[i]==current)break;if(ev&&ev.shiftKey){if(--i<0)i=range.length-1;}else if(++i>=range.length)i=0;var newval=range[i];el.innerHTML=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;}else if(el.navtype==0)newdate=closing=true;}if(newdate){ev&&cal.callHandler();}if(closing){Calendar.removeClass(el,"hilite");ev&&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;cell.innerHTML="<div unselectable='on'>"+text+"</div>";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.innerHTML=Calendar._TT["WK"];}for(var i=7;i>0;--i){cell=Calendar.createElement("td",row);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);}for(var j=7;j>0;--j){cell=Calendar.createElement("td",row);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=Calendar._TT["TIME"]||" ";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.innerHTML=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.innerHTML=":";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 pm,hrs=this.date.getHours(),mins=this.date.getMinutes();if(t12){pm=(hrs>=12);if(pm)hrs-=12;if(hrs==0)hrs=12;AP.innerHTML=pm?"pm":"am";}H.innerHTML=(hrs<10)?("0"+hrs):hrs;M.innerHTML=(mins<10)?("0"+mins):mins;};cal.onUpdateTime=function(){var date=this.date;var h=parseInt(H.innerHTML,10);if(t12){if(/pm/i.test(AP.innerHTML)&&h<12)h+=12;else if(/am/i.test(AP.innerHTML)&&h==12)h=0;}var d=date.getDate();var m=date.getMonth();var y=date.getFullYear();date.setHours(h);date.setMinutes(parseInt(M.innerHTML,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;i<Calendar._MN.length;++i){var mn=Calendar.createElement("div");mn.className=Calendar.is_ie?"label-IEfix":"label";mn.month=i;mn.innerHTML=Calendar._SMN[i];div.appendChild(mn);}div=Calendar.createElement("div",this.element);this.yearsCombo=div;div.className="combo";for(i=12;i>0;--i){var yr=Calendar.createElement("div");yr.className=Calendar.is_ie?"label-IEfix":"label";div.appendChild(yr);}this._init(this.firstDayOfWeek,this.date);parent.appendChild(this.element);};Calendar._keyEvent=function(ev){var cal=window._dynarch_popupCalendar;if(!cal||cal.multiple)return false;(Calendar.is_ie)&&(ev=window.event);var act=(Calendar.is_ie||ev.type=="keypress"),K=ev.keyCode;if(ev.ctrlKey){switch(K){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(K){case 32:Calendar.cellClick(cal._nav_now);break;case 27:act&&cal.callCloseHandler();break;case 37:case 38:case 39:case 40:if(act){var prev,x,y,ne,el,step;prev=K==37||K==38;step=(K==37||K==39)?1:7;function setVars(){el=cal.currentDateEl;var p=el.pos;x=p&15;y=p>>4;ne=cal.ar_days[y][x];};setVars();function prevMonth(){var date=new Date(cal.date);date.setDate(date.getDate()-step);cal.setDate(date);};function nextMonth(){var date=new Date(cal.date);date.setDate(date.getDate()+step);cal.setDate(date);};while(1){switch(K){case 37:if(--x>=0)ne=cal.ar_days[y][x];else{x=6;K=38;continue;}break;case 38:if(--y>=0)ne=cal.ar_days[y][x];else{prevMonth();setVars();}break;case 39:if(++x<7)ne=cal.ar_days[y][x];else{x=0;K=40;continue;}break;case 40:if(++y<cal.ar_days.length)ne=cal.ar_days[y][x];else{nextMonth();setVars();}break;}break;}if(ne){if(!ne.disabled)Calendar.cellClick(ne);else if(prev)prevMonth();else nextMonth();}}break;case 13:if(act)Calendar.cellClick(cal.currentDateEl,ev);break;default:return false;}return Calendar.stopEvent(ev);};Calendar.prototype._init=function(firstDayOfWeek,date){var today=new Date(),TY=today.getFullYear(),TM=today.getMonth(),TD=today.getDate();this.table.style.visibility="hidden";var year=date.getFullYear();if(year<this.minYear){year=this.minYear;date.setFullYear(year);}else if(year>this.maxYear){year=this.maxYear;date.setFullYear(year);}this.firstDayOfWeek=firstDayOfWeek;this.date=new Date(date);var month=date.getMonth();var mday=date.getDate();var no_days=date.getMonthDays();date.setDate(1);var day1=(date.getDay()-this.firstDayOfWeek)%7;if(day1<0)day1+=7;date.setDate(-day1);date.setDate(date.getDate()+1);var row=this.tbody.firstChild;var MN=Calendar._SMN[month];var ar_days=this.ar_days=new Array();var weekend=Calendar._TT["WEEKEND"];var dates=this.multiple?(this.datesCells={}):null;for(var i=0;i<6;++i,row=row.nextSibling){var cell=row.firstChild;if(this.weekNumbers){cell.className="day wn";cell.innerHTML=date.getWeekNumber();cell=cell.nextSibling;}row.className="daysrow";var hasdays=false,iday,dpos=ar_days[i]=[];for(var j=0;j<7;++j,cell=cell.nextSibling,date.setDate(iday+1)){iday=date.getDate();var wday=date.getDay();cell.className="day";cell.pos=i<<4|j;dpos[j]=cell;var current_month=(date.getMonth()==month);if(!current_month){if(this.showsOtherMonths){cell.className+=" othermonth";cell.otherMonth=true;}else{cell.className="emptycell";cell.innerHTML=" ";cell.disabled=true;continue;}}else{cell.otherMonth=false;hasdays=true;}cell.disabled=false;cell.innerHTML=this.getDateText?this.getDateText(date,iday):iday;if(dates)dates[date.print("%Y%m%d")]=cell;if(this.getDateStatus){var status=this.getDateStatus(date,year,month,iday);if(this.getDateToolTip){var toolTip=this.getDateToolTip(date,year,month,iday);if(toolTip)cell.title=toolTip;}if(status===true){cell.className+=" disabled";cell.disabled=true;}else{if(/disabled/i.test(status))cell.disabled=true;cell.className+=" "+status;}}if(!cell.disabled){cell.caldate=new Date(date);cell.ttip="_";if(!this.multiple&¤t_month&&iday==mday&&this.hiliteToday){cell.className+=" selected";this.currentDateEl=cell;}if(date.getFullYear()==TY&&date.getMonth()==TM&&iday==TD){cell.className+=" today";cell.ttip+=Calendar._TT["PART_TODAY"];}if(weekend.indexOf(wday.toString())!=-1)cell.className+=cell.otherMonth?" oweekend":" weekend";}}if(!(hasdays||this.showsOtherMonths))row.className="emptyrow";}this.title.innerHTML=Calendar._MN[month]+", "+year;this.onSetTime();this.table.style.visibility="visible";this._initMultipleDates();};Calendar.prototype._initMultipleDates=function(){if(this.multiple){for(var i in this.multiple){var cell=this.datesCells[i];var d=this.multiple[i];if(!d)continue;if(cell)cell.className+=" selected";}}};Calendar.prototype._toggleMultipleDate=function(date){if(this.multiple){var ds=date.print("%Y%m%d");var cell=this.datesCells[ds];if(cell){var d=this.multiple[ds];if(!d){Calendar.addClass(cell,"selected");this.multiple[ds]=date;}else{Calendar.removeClass(cell,"selected");delete this.multiple[ds];}}}};Calendar.prototype.setDateToolTipHandler=function(unaryFunction){this.getDateToolTip=unaryFunction;};Calendar.prototype.setDate=function(date){if(!date.equalsTo(this.date)){this._init(this.firstDayOfWeek,date);}};Calendar.prototype.refresh=function(){this._init(this.firstDayOfWeek,this.date);};Calendar.prototype.setFirstDayOfWeek=function(firstDayOfWeek){this._init(firstDayOfWeek,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._dynarch_popupCalendar=null;};Calendar.prototype.reparent=function(new_parent){var el=this.element;el.parentNode.removeChild(el);new_parent.appendChild(el);};Calendar._checkCalendar=function(ev){var calendar=window._dynarch_popupCalendar;if(!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._dynarch_popupCalendar.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._dynarch_popupCalendar=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;}function fixPosition(box){if(box.x<0)box.x=0;if(box.y<0)box.y=0;var cp=document.createElement("div");var s=cp.style;s.position="absolute";s.right=s.bottom=s.width=s.height="0px";document.body.appendChild(cp);var br=Calendar.getAbsolutePos(cp);document.body.removeChild(cp);if(Calendar.is_ie){br.y+=document.body.scrollTop;br.x+=document.body.scrollLeft;}else{br.y+=window.scrollY;br.x+=window.scrollX;}var tmp=box.x+box.width-br.x;if(tmp>0)box.x-=tmp;tmp=box.y+box.height-br.y;if(tmp>0)box.y-=tmp;};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 "l":p.x+=el.offsetWidth-w;break;case "r":break;}p.width=w;p.height=h+40;self.monthsCombo.style.display="none";fixPosition(p);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){if(!fmt)fmt=this.dateFormat;this.setDate(Date.parseDate(str,fmt));};Calendar.prototype.hideShowCovered=function(){if(!Calendar.is_ie&&!Calendar.is_opera)return;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=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=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";}}}};Calendar.prototype._displayWeekdays=function(){var fdow=this.firstDayOfWeek;var cell=this.firstdayname;var weekend=Calendar._TT["WEEKEND"];for(var i=0;i<7;++i){cell.className="day name";var realday=(i+fdow)%7;if(i){cell.ttip=Calendar._TT["DAY_FIRST"].replace("%s",Calendar._DN[realday]);cell.navtype=100;cell.calendar=this;cell.fdow=realday;Calendar._add_evs(cell);}if(weekend.indexOf(realday.toString())!=-1){Calendar.addClass(cell,"weekend");}cell.innerHTML=Calendar._SDN[(i+fdow)%7];cell=cell.nextSibling;}};Calendar.prototype._hideCombos=function(){this.monthsCombo.style.display="none";this.yearsCombo.style.display="none";};Calendar.prototype._dragStart=function(ev){if(this.dragging){return;}this.dragging=true;var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posY=ev.clientY+window.scrollY;posX=ev.clientX+window.scrollX;}var st=this.element.style;this.xOffs=posX-parseInt(st.left);this.yOffs=posY-parseInt(st.top);with(Calendar){addEvent(document,"mousemove",calDragIt);addEvent(document,"mouseup",calDragEnd);}};Date._MD=new Array(31,28,31,30,31,30,31,31,30,31,30,31);Date.SECOND=1000;Date.MINUTE=60*Date.SECOND;Date.HOUR=60*Date.MINUTE;Date.DAY=24*Date.HOUR;Date.WEEK=7*Date.DAY;Date.parseDate=function(str,fmt){var today=new Date();var y=0;var m=-1;var d=0;var a=str.split(/\W+/);var b=fmt.match(/%./g);var i=0,j=0;var hr=0;var min=0;for(i=0;i<a.length;++i){if(!a[i])continue;switch(b[i]){case "%d":case "%e":d=parseInt(a[i],10);break;case "%m":m=parseInt(a[i],10)-1;break;case "%Y":case "%y":y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);break;case "%b":case "%B":for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){m=j;break;}}break;case "%H":case "%I":case "%k":case "%l":hr=parseInt(a[i],10);break;case "%P":case "%p":if(/pm/i.test(a[i])&&hr<12)hr+=12;else if(/am/i.test(a[i])&&hr>=12)hr-=12;break;case "%M":min=parseInt(a[i],10);break;}}if(isNaN(y))y=today.getFullYear();if(isNaN(m))m=today.getMonth();if(isNaN(d))d=today.getDate();if(isNaN(hr))hr=today.getHours();if(isNaN(min))min=today.getMinutes();if(y!=0&&m!=-1&&d!=0)return new Date(y,m,d,hr,min,0);y=0;m=-1;d=0;for(i=0;i<a.length;++i){if(a[i].search(/[a-zA-Z]+/)!=-1){var t=-1;for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){t=j;break;}}if(t!=-1){if(m!=-1){d=m+1;}m=t;}}else if(parseInt(a[i],10)<=12&&m==-1){m=a[i]-1;}else if(parseInt(a[i],10)>31&&y==0){y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);}else if(d==0){d=a[i];}}if(y==0)y=today.getFullYear();if(m!=-1&&d!=0)return new Date(y,m,d,hr,min,0);return today;};Date.prototype.getMonthDays=function(month){var year=this.getFullYear();if(typeof month=="undefined"){month=this.getMonth();}if(((0==(year%4))&&((0!=(year%100))||(0==(year%400))))&&month==1){return 29;}else{return Date._MD[month];}};Date.prototype.getDayOfYear=function(){var now=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var then=new Date(this.getFullYear(),0,0,0,0,0);var time=now-then;return Math.floor(time/Date.DAY);};Date.prototype.getWeekNumber=function(){var d=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var DoW=d.getDay();d.setDate(d.getDate()-(DoW+6)%7+3);var ms=d.valueOf();d.setMonth(0);d.setDate(4);return Math.round((ms-d.valueOf())/(7*864e5))+1;};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.setDateOnly=function(date){var tmp=new Date(date);this.setDate(1);this.setFullYear(tmp.getFullYear());this.setMonth(tmp.getMonth());this.setDate(tmp.getDate());};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=/%./g;if(!Calendar.is_ie5&&!Calendar.is_khtml)return str.replace(re,function(par){return s[par]||par;});var a=str.match(re);for(var i=0;i<a.length;i++){var tmp=s[a[i]];if(tmp){re=new RegExp(a[i],'g');str=str.replace(re,tmp);}}return str;};Date.prototype.__msh_oldSetFullYear=Date.prototype.setFullYear;Date.prototype.setFullYear=function(y){var d=new Date(this);d.__msh_oldSetFullYear(y);if(d.getMonth()!=this.getMonth())this.setDate(28);this.__msh_oldSetFullYear(y);};window._dynarch_popupCalendar=null;
\ No newline at end of file diff --git a/httemplate/elements/checkboxes-table-name.html b/httemplate/elements/checkboxes-table-name.html new file mode 100644 index 000000000..0a92e4548 --- /dev/null +++ b/httemplate/elements/checkboxes-table-name.html @@ -0,0 +1,85 @@ +% +% +% ## +% # required +% ## +% # 'link_table' => 'table_name', +% # +% # 'name_col' => 'name_column', +% # #or +% # 'name_callback' => sub { }, +% # +% # 'names_list' => [ 'value', 'other value' ], +% # +% ## +% # recommended (required?) +% ## +% # 'source_obj' => $obj, +% # #or? +% # #'source_table' => 'table_name', +% # #'sourcenum' => '4', #current value of primary key in source_table +% # # # (none is okay, just pass it if you have it) +% ## +% # optional +% ## +% # 'num_col' => 'col_name' #if column name is different in link_table than +% # #source_table +% # 'link_static' => { 'column' => 'value' }, +% +% my( %opt ) = @_; +% +% my( $source_pkey, $sourcenum, $source_obj ); +% if ( $opt{'source_obj'} ) { +% +% $source_obj = $opt{'source_obj'}; +% #$source_table = $source_obj->dbdef_table->table; +% $source_pkey = $source_obj->dbdef_table->primary_key; +% $sourcenum = $source_obj->$source_pkey(); +% +% } else { +% +% #$source_obj? +% $source_pkey = $opt{'source_table'} +% ? dbdef->table($opt{'source_table'})->primary_key +% : ''; +% $sourcenum = $opt{'sourcenum'}; +% } +% +% $source_pkey = $opt{'num_col'} || $source_pkey; +% +% my $link_static = $opt{'link_static'} || {}; +% +% +% foreach my $name ( @{ $opt{'names_list'} } ) { +% +% my $checked; +% if ( $cgi->param('error') ) { +% +% $checked = $cgi->param($opt{'link_table'}. ".$name" ) +% ? 'CHECKED' +% : ''; +% +% } else { +% +% $checked = +% qsearchs( $opt{'link_table'}, { +% $source_pkey => $sourcenum, +% $opt{'name_col'} => $name, +% %$link_static, +% } ) +% ? 'CHECKED' +% : '' +% +% } +% +% + + + <INPUT TYPE="checkbox" NAME="<% $opt{'link_table'}. ".$name" %>" <% $checked %> VALUE="ON"> + + <% $name %> + + <BR> +% } + + diff --git a/httemplate/elements/checkboxes-table.html b/httemplate/elements/checkboxes-table.html new file mode 100644 index 000000000..cdfa58eca --- /dev/null +++ b/httemplate/elements/checkboxes-table.html @@ -0,0 +1,123 @@ +% +% +% ## +% # required +% ## +% # 'target_table' => 'table_name', +% # 'link_table' => 'table_name', +% # +% # 'name_col' => 'name_column', +% # #or +% # 'name_callback' => sub { }, +% # +% ## +% # recommended (required?) +% ## +% # 'source_obj' => $obj, +% # #or? +% # #'source_table' => 'table_name', +% # #'sourcenum' => '4', #current value of primary key in source_table +% # # # (none is okay, just pass it if you have it) +% ## +% # optional +% ## +% # 'disable-able' => 1, +% +% my( %opt ) = @_; +% +% my $target_pkey = dbdef->table($opt{'target_table'})->primary_key; +% +% my( $source_pkey, $sourcenum, $source_obj ); +% if ( $opt{'source_obj'} ) { +% +% $source_obj = $opt{'source_obj'}; +% #$source_table = $source_obj->dbdef_table->table; +% $source_pkey = $source_obj->dbdef_table->primary_key; +% $sourcenum = $source_obj->$source_pkey(); +% +% } else { +% +% #$source_obj? +% $source_pkey = $opt{'source_table'} +% ? dbdef->table($opt{'source_table'})->primary_key +% : ''; +% $sourcenum = $opt{'sourcenum'}; +% } +% +% my $hashref = $opt{'hashref'} || {}; +% +% my $extra_sql = ''; +% +% if ( $opt{'disable-able'} ) { +% $hashref->{'disabled'} = ''; +% +% $extra_sql .= ( $sourcenum && $source_pkey ) +% ? "OR $source_pkey = $sourcenum" +% : ''; +% } +% +% +% foreach my $target_obj ( +% qsearch({ 'table' => $opt{'target_table'}, +% 'hashref' => $hashref, +% 'select' => $opt{'target_table'}. '.*', +% 'addl_from' => "LEFT JOIN $opt{'link_table'} USING ( $target_pkey )", +% 'extra_sql' => $extra_sql, +% }) +% ) { +% +% my $targetnum = $target_obj->$target_pkey(); +% +% my $checked; +% if ( $cgi->param('error') ) { +% +% $checked = $cgi->param($target_pkey.$targetnum) +% ? 'CHECKED' +% : ''; +% +% } else { +% +% $checked = qsearchs( $opt{'link_table'}, { +% $source_pkey => $sourcenum, +% $target_pkey => $targetnum, +% } ) +% ? 'CHECKED' +% : '' +% +% } +% +% + + + <INPUT TYPE="checkbox" NAME="<% $target_pkey. $targetnum %>" <% $checked %> VALUE="ON"> +% if ( $opt{'target_link'} ) { + + + <A HREF="<% $opt{'target_link'} %><% $targetnum %>"> +% +% +% } +% +<% $targetnum %>: +% if ( $opt{'name_callback'} ) { + + + <% &{ $opt{'name_callback'} }( $target_obj ) %><% $opt{'target_link'} ? '</A>' : '' %> +% } else { +% my $name_col = $opt{'name_col'}; +% + + + <% $target_obj->$name_col() %><% $opt{'target_link'} ? '</A>' : '' %> +% } +% if ( $opt{'disable-able'} ) { + + + <% $target_obj->disabled =~ /^Y/i ? ' (DISABLED)' : '' %> +% } + + + <BR> +% } + + diff --git a/httemplate/elements/cssexpr.js b/httemplate/elements/cssexpr.js new file mode 100644 index 000000000..c434d8da0 --- /dev/null +++ b/httemplate/elements/cssexpr.js @@ -0,0 +1,66 @@ +function constExpression(x) { + return x; +} + +function simplifyCSSExpression() { + try { + var ss,sl, rs, rl; + ss = document.styleSheets; + sl = ss.length + + for (var i = 0; i < sl; i++) { + simplifyCSSBlock(ss[i]); + } + } + catch (exc) { + //alert("Got an error while processing css. The page should still work but might be a bit slower"); + throw exc; + } +} + +function simplifyCSSBlock(ss) { + var rs, rl; + + for (var i = 0; i < ss.imports.length; i++) + simplifyCSSBlock(ss.imports[i]); + + if (ss.cssText.indexOf("expression(constExpression(") == -1) + return; + + rs = ss.rules; + rl = rs.length; + for (var j = 0; j < rl; j++) + simplifyCSSRule(rs[j]); + +} + +function simplifyCSSRule(r) { + var str = r.style.cssText; + var str2 = str; + var lastStr; + do { + lastStr = str2; + str2 = simplifyCSSRuleHelper(lastStr); + } while (str2 != lastStr) + + if (str2 != str) + r.style.cssText = str2; +} + +function simplifyCSSRuleHelper(str) { + var i, i2; + i = str.indexOf("expression(constExpression("); + if (i == -1) return str; + i2 = str.indexOf("))", i); + var hd = str.substring(0, i); + var tl = str.substring(i2 + 2); + var exp = str.substring(i + 27, i2); + var val = eval(exp) + return hd + val + tl; +} + +if (/msie/i.test(navigator.userAgent) && window.attachEvent != null) { + window.attachEvent("onload", function () { + simplifyCSSExpression(); + }); +} diff --git a/httemplate/elements/dashboard-toplist.html b/httemplate/elements/dashboard-toplist.html new file mode 100644 index 000000000..7ee6f2d43 --- /dev/null +++ b/httemplate/elements/dashboard-toplist.html @@ -0,0 +1,109 @@ +% if ( $conf->exists('dashboard-toplist') ) { + + <% include('/elements/table-grid.html') %> + +% my $bgcolor1 = '#eeeeee'; +% my $bgcolor2 = '#ffffff'; +% my $bgcolor = $bgcolor2; + +% foreach my $line ( $conf->config('dashboard-toplist') ) { +% +% if ( $bgcolor eq $bgcolor1 ) { +% $bgcolor = $bgcolor2; +% } else { +% $bgcolor = $bgcolor1; +% } + +% if ( $line =~ /^\s*cust_main:\s*(\d+)\s*$/ ) { #customer line +% my $custnum = $1; +% my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ); +% if ( $cust_main ) { + + <TR> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <A HREF="view/cust_main.cgi?<% $custnum %>"><% $cust_main->name %></A> + </TD> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ALIGN="right"> + <FONT SIZE="-1"><A HREF="<% FS::TicketSystem->href_new_ticket($cust_main, join(', ', grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list ) ) %>">(new ticket)</A></FONT> + </TD> + +% foreach my $priority ( @custom_priorities, '' ) { +% my $num = +% FS::TicketSystem->num_customer_tickets($custnum,$priority); +% my $ahref = ''; +% $ahref= '<A HREF="'. +% FS::TicketSystem->href_customer_tickets($custnum,$priority). +% '">' +% if $num; + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ALIGN="right"> + <% $ahref.$num %></A> + </TD> +% } + </TR> + +% } else { + + <TR> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> + Unknown customer number <% $custnum %> + </TD> + </TR> + +% } +% +% } elsif ( $line =~ /^\-\-+$/ ) { #divider +% + <TR> + <TH CLASS="grid" COLSPAN="<% scalar(@custom_priorities) + 3 %>"></TH> + </TR> + +% next; +% +% } elsif ( $line =~ /^\s*$/ ) { + + <TR> + <TD CLASS="grid" COLSPAN="<% scalar(@custom_priorities) + 3 %>" BGCOLOR="<% $bgcolor %>"> </TD> + </TR> + +% } elsif ( $line =~ /^\S/ ) { #label line + + <TR> + <TH CLASS="grid" BGCOLOR="#cccccc"><% $line %></TH> + <TH CLASS="grid" BGCOLOR="#cccccc"></TH> +% foreach my $priority ( @custom_priorities, '' ) { + <TH CLASS="grid" BGCOLOR="#cccccc"> + <% $priority || '<i>(none)</i>'%> + </TH> +% } + </TR> + +% } else { #regular line + + <TR> + <TD CLASS="grid" COLSPAN="<% scalar(@custom_priorities) + 3 %>" BGCOLOR="<% $bgcolor %>"><% $line %></TD> + </TR> + +% } + +% +% } + + </TABLE> + <BR> + +% } +<%init> + +my $conf = new FS::Conf; + +#false laziness w/httemplate/search/cust_main.cgi... care if +# custom_priority_field becomes anything but a local hack... +my @custom_priorities = (); +if ( $conf->config('ticket_system-custom_priority_field') + && @{[ $conf->config('ticket_system-custom_priority_field-values') ]} ) { + @custom_priorities = + $conf->config('ticket_system-custom_priority_field-values'); +} + +</%init> diff --git a/httemplate/elements/error.html b/httemplate/elements/error.html new file mode 100644 index 000000000..e8ba93010 --- /dev/null +++ b/httemplate/elements/error.html @@ -0,0 +1,4 @@ +% if ( $cgi->param('error') ) { + <FONT SIZE="+1" COLOR="#ff0000">Error: <% $cgi->param('error') %></FONT> + <BR><BR> +% } diff --git a/httemplate/elements/footer.html b/httemplate/elements/footer.html new file mode 100644 index 000000000..32d121996 --- /dev/null +++ b/httemplate/elements/footer.html @@ -0,0 +1,5 @@ + </TD> + </TR> + </TABLE> + </BODY> +</HTML> diff --git a/httemplate/elements/freeside.css b/httemplate/elements/freeside.css new file mode 100644 index 000000000..6f7cadb2e --- /dev/null +++ b/httemplate/elements/freeside.css @@ -0,0 +1,15 @@ +* { + font-family: Arial, Verdana, Helvetica, sans-serif; +} + +A:link IMG, A:visited { border-style: none } +/* A:focus {text-decoration: underline } */ + +a:link, a:visited { + /* text-decoration: none; */ + color: #000000; +} +/* a:hover { text-decoration: underline } */ + +/* a:focus { background-color: #ccccee } */ + diff --git a/httemplate/elements/header-popup.html b/httemplate/elements/header-popup.html new file mode 100644 index 000000000..43d9bc3af --- /dev/null +++ b/httemplate/elements/header-popup.html @@ -0,0 +1,23 @@ +% +% my($title, $menubar) = ( shift, shift ); #$menubar is unused here though +% my $etc = @_ ? shift : ''; #$etc is for things like onLoad= etc. +% my $head = @_ ? shift : ''; #$head is for things that go in the <HEAD> section +% my $conf = new FS::Conf; +% + +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<HTML> + <HEAD> + <TITLE> + <% $title %> + </TITLE> + <META HTTP-Equiv="Cache-Control" Content="no-cache"> + <META HTTP-Equiv="Pragma" Content="no-cache"> + <META HTTP-Equiv="Expires" Content="0"> + <% $head %> + </HEAD> + <BODY BGCOLOR="#e8e8e8" <% $etc %>> + <FONT SIZE=6> + <CENTER><% $title %></CENTER> + </FONT> + <BR><!--<BR>--> diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html index 10e4e40f1..1f5674885 100644 --- a/httemplate/elements/header.html +++ b/httemplate/elements/header.html @@ -1,21 +1,244 @@ -<% - my($title, $menubar) = ( shift, shift ); - my $etc = @_ ? shift : ''; #$etc is for things like onLoad= etc. - my $head = @_ ? shift : ''; #$head is for things that go in the <HEAD> section -%> - <HTML> - <HEAD> - <TITLE> - <%= $title %> - </TITLE> - <META HTTP-Equiv="Cache-Control" Content="no-cache"> - <META HTTP-Equiv="Pragma" Content="no-cache"> - <META HTTP-Equiv="Expires" Content="0"> - <%= $head %> - </HEAD> - <BODY BGCOLOR="#e8e8e8"<%= $etc %>> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<HTML> + <HEAD> + <TITLE> + <% $title %> + </TITLE> + <META HTTP-Equiv="Cache-Control" Content="no-cache"> + <META HTTP-Equiv="Pragma" Content="no-cache"> + <META HTTP-Equiv="Expires" Content="0"> + + <% include('menu.html', 'freeside_baseurl' => $fsurl, + 'position' => $menu_position, + ) + %> + + <SCRIPT TYPE="text/javascript"> + function clearhint_search_cust (what) { + if ( what.value == '(cust #, name, company or phone)' ) + what.value = ''; + } + + function clearhint_search_invoice (what) { + if ( what.value == '(inv #)' ) + what.value = ''; + } + + function clearhint_search_svc (what) { + if ( what.value == '(user, user@domain or domain)' ) + what.value = ''; + } + + function clearhint_search_ticket (what) { + if ( what.value == '(ticket # or subject string)' ) + what.value = ''; + } + </SCRIPT> + + <% $head %> + + </HEAD> + <BODY <% $menu_position eq 'left' ? qq( BACKGROUND="${fsurl}images/background-cheat.png" ) : ' BGCOLOR="#e8e8e8" ' %> <% $etc %> STYLE="margin-top:0; margin-bottom:0; margin-left:0; margin-right:0"> + <table width="100%" CELLPADDING=0 CELLSPACING=0 STYLE="padding-left:0; padding-right:4"> + <tr> + <td rowspan=2 BGCOLOR="#ffffff"><IMG BORDER=0 ALT="freeside" SRC="<%$fsurl%>images/small-logo.png"></td> + <td align=left rowspan=2 BGCOLOR="#ffffff"> <!-- valign="top" --> + <font size=6><% $conf->config('company_name') || 'ExampleCo' %></font> + </td> + <td align=right valign=top BGCOLOR="#ffffff"><FONT SIZE="-1">Logged in as <b><% getotaker %> </b><br></FONT><FONT SIZE="-2"><a href="<%$fsurl%>pref/pref.html">Preferences</a> <BR></FONT> + </td> + </tr> + <tr> + <td align=right valign=bottom BGCOLOR="#ffffff"> + + <table> + <tr> + <td align=right BGCOLOR="#ffffff"> + <FONT SIZE="-2"> + <A HREF="http://www.sisd.com/freeside">Freeside</A> v<% $FS::VERSION %><BR> + <A HREF="<% $conf->config('support-key') ? "http://www.sisd.com/mediawiki/index.php/Supported:Documentation" : "http://www.sisd.com/mediawiki/index.php/Freeside:1.7:Documentation" %>">Documentation</A><BR> + </FONT> + </td> +% if ( $conf->config('ticket_system') eq 'RT_Internal' ) { +% eval "use RT;"; + + <td bgcolor=#000000></td> + <td align=left> + <FONT SIZE="-2"> + <A HREF="http://www.bestpractical.com/rt">RT<A> v<% $RT::VERSION %><BR> + <A HREF="http://wiki.bestpractical.com/">Documentation</A><BR> + </FONT> + </td> +% } + + + </tr> + </table> + + </td> + </tr> + </table> + +<style type="text/css"> +input.fsblackbutton { + background-color:#333333; + color: #ffffff; + border:1px solid; + border-top-color:#cccccc; + border-left-color:#cccccc; + border-right-color:#aaaaaa; + border-bottom-color:#aaaaaa; + font-weight:bold; + padding-left:12px; + padding-right:12px; + overflow:visible; + filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr='#ff333333',EndColorStr='#ff666666') +} + +input.fsblackbuttonselected { + background-color:#7e0079; + color: #ffffff; + border:1px solid; + border-top-color:#cccccc; + border-left-color:#cccccc; + border-right-color:#aaaaaa; + border-bottom-color:#aaaaaa; + font-weight:bold; + padding-left:12px; + padding-right:12px; + overflow:visible; + filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr='#ff330033',EndColorStr='#ff7e0079') +} +</style> + + <TABLE WIDTH="100%" CELLSPACING=0 CELLPADDING=0> + <TR> + <TD COLSPAN=5 WIDTH="100%" STYLE="padding:0"><IMG BORDER=0 ALT="" SRC="<%$fsurl%>images/black-gradient.png" HEIGHT="13" WIDTH="100%"></TD> + </TR> + +% if ( $menu_position eq 'top' ) { + + <TR> + + <TD COLSPAN="5" WIDTH="100%" STYLE="padding:0"> + <SCRIPT TYPE="text/javascript"> + document.write(myBar); + </SCRIPT> + </TD> + + </TR> + + <TR> + <TD COLSPAN="5" WIDTH="100%" HEIGHT="2px" STYLE="padding:0" BGCOLOR="#000000"> + </TD> + </TR> + + <TR> + <TD COLSPAN="5" WIDTH="100%" HEIGHT="4px" STYLE="padding:0" BGCOLOR="#000000"> + </TD> + </TR> + +% } + + <TR> + + <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right"> + <FORM ACTION="<%$fsurl%>edit/cust_main.cgi" METHOD="GET" STYLE="margin:0"> + <INPUT TYPE="submit" VALUE="New customer" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="vertical-align:bottom"> + </FORM> + </TD> + + <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right"> + <FORM ACTION="<%$fsurl%>search/cust_main.cgi" METHOD="GET" STYLE="margin:0"> + <INPUT NAME="search_cust" TYPE="text" VALUE="(cust #, name, company or phone)" SIZE="28" onFocus="clearhint_search_cust(this);" onClick="clearhint_search_cust(this);" STYLE="vertical-align:bottom;text-align:right"><BR> + <A NOTYET="<%$fsurl%>search/cust_main.html" STYLE="color: #000000; font-size: 70%">Advanced</A> + <INPUT TYPE="submit" VALUE="Search customers" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%"> + </FORM> + </TD> + + <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right"> +% if ( $FS::CurrentUser::CurrentUser->access_right('View invoices') ) { + + <FORM ACTION="<%$fsurl%>search/cust_bill.html" METHOD="GET" STYLE="margin:0;display:inline"> + <INPUT NAME="invnum" TYPE="text" VALUE="(inv #)" SIZE="4" onFocus="clearhint_search_invoice(this);" onClick="clearhint_search_invoice(this);" STYLE="vertical-align:bottom;text-align:right;margin-bottom:1px"> +% if ( $FS::CurrentUser::CurrentUser->access_right('List invoices') ) { + + <A HREF="<%$fsurl%>search/report_cust_bill.html" STYLE="color: #ffffff; font-size: 70%">Advanced</A> +% } + + <BR> + <INPUT TYPE="submit" VALUE="Search invoices" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%"> + </FORM> +% } + + </TD> + + <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right"> + <FORM ACTION="<%$fsurl%>search/cust_svc.html" METHOD="GET" STYLE="margin:0"> + <INPUT NAME="search_svc" TYPE="text" VALUE="(user, user@domain or domain)" SIZE="26" onFocus="clearhint_search_svc(this);" onClick="clearhint_search_svc(this);" STYLE="vertical-align:bottom;text-align:right"><BR> + <A NOTYET="<%$fsurl%>search/svc_Smarter.html" STYLE="color: #000000; font-size: 70%">Advanced</A> + <INPUT TYPE="submit" VALUE="Search services" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%"> + </FORM> + </TD> + + <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right" STYLE="padding-right:4px"> + <FORM ACTION="<%$fsurl%>rt/index.html" METHOD="GET" STYLE="margin:0"> + <INPUT NAME="q" TYPE="text" VALUE="(ticket # or subject string)" onFocus="clearhint_search_ticket(this);" onClick="clearhint_search_ticket(this);" STYLE="vertical-align:bottom;text-align:right"><BR> + <A HREF="<%$fsurl%>rt/Search/Build.html" STYLE="color: #ffffff; font-size: 70%">Advanced</A> + <INPUT TYPE="submit" VALUE="Search tickets" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%;padding-left:2px;padding-right:2px"> + </FORM> + </TD> + + </TR> + </TABLE> + + <TABLE WIDTH="100%" HEIGHT="100%" CELLSPACING=0 CELLPADDING=4> + + <TR> + +% if ( $menu_position eq 'left' ) { + + <TD BGCOLOR="#000000" STYLE="padding:0" WIDTH="154"></TD> + <TD STYLE="padding:0" WIDTH="13"><IMG BORDER=0 ALT="" SRC="<%$fsurl%>images/black-gray-corner.png"></TD> + +% } + + <TD STYLE="padding:0" WIDTH="100%"><IMG BORDER=0 ALT="" SRC="<%$fsurl%>images/black-gray-top.png" HEIGHT="13" WIDTH="100%"></TD> + + </TR> + + <TR HEIGHT="100%"> + +% if ( $menu_position eq 'left' ) { + + <TD BGCOLOR="#000000" ALIGN="left" HEIGHT="100%" WIDTH="154" VALIGN="top" ALIGN="right"> + <SCRIPT TYPE="text/javascript"> + document.write(myBar); + </SCRIPT> + <BR> + <IMG SRC="<%$fsurl%>images/32clear.gif" HEIGHT="1" WIDTH="154"> + + </TD> + <TD STYLE="padding:0" HEIGHT="100%" WIDTH=13 VALIGN="top"><IMG WIDTH="13" HEIGHT="100%" BORDER=0 ALT="" SRC="<%$fsurl%>images/black-gray-side.png"></TD> + +% } + + <TD BGCOLOR="#e8e8e8" HEIGHT="100%" VALIGN="top"> <!-- WIDTH="100%"> --> + <FONT SIZE=6> - <%= $title %> + <% $title %> </FONT> + <BR><BR> - <%= $menubar ? "$menubar<BR><BR>" : '' %> + <% $menubar !~ /^\s*$/ ? "$menubar<BR><BR>" : '' %> +<%init> + +my($title, $menubar) = ( shift, shift ); +my $etc = @_ ? shift : ''; #$etc is for things like onLoad= etc. +my $head = @_ ? shift : ''; #$head is for things that go in the <HEAD> section +my $conf = new FS::Conf; + +my $menu_position = $FS::CurrentUser::CurrentUser->option('menu_position') + || 'left'; + +</%init> diff --git a/httemplate/elements/iframecontentmws.js b/httemplate/elements/iframecontentmws.js new file mode 100644 index 000000000..c80998957 --- /dev/null +++ b/httemplate/elements/iframecontentmws.js @@ -0,0 +1,20 @@ +/*
+ iframecontentmws.js - Foteos Macrides
+ Initial: October 10, 2004 - Last Revised: May 9, 2005
+ Simple script for using an HTML file as iframe content in overlibmws popups.
+ Include WRAP and TEXTPADDING,0 in the overlib call to ensure that the width
+ arg is respected (unless the CAPTION plus CLOSETEXT widths add up to more than
+ the width arg, in which case you should increase the width arg). The name arg
+ should be a unique string for each popup with iframe content in the document.
+ The frameborder arg should be 1 (browser default if omitted) or 0.
+
+ See http://www.macridesweb.com/oltest/IFRAME.html for demonstration.
+*/
+
+function OLiframeContent(src, width, height, name, frameborder) {
+ return ('<iframe src="'+src+'" width="'+width+'" height="'+height+'"'
+ +(name!=null?' name="'+name+'" id="'+name+'"':'')
+ +(frameborder!=null?' frameborder="'+frameborder+'"':'')
+ +' scrolling="auto">'
+ +'<div>[iframe not supported]</div></iframe>');
+}
diff --git a/httemplate/elements/jsrsServer.html b/httemplate/elements/jsrsServer.html index fd6dc5465..f37b0aaee 100644 --- a/httemplate/elements/jsrsServer.html +++ b/httemplate/elements/jsrsServer.html @@ -1,3 +1,4 @@ -<% - my $server = new FS::UI::Web::JSRPC '', $cgi; -%><%= $server->process %> +% +% my $server = new FS::UI::Web::JSRPC '', $cgi; +% +<% $server->process %> diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html new file mode 100644 index 000000000..9565ff2d0 --- /dev/null +++ b/httemplate/elements/menu.html @@ -0,0 +1,353 @@ +<script type="text/javascript" src="<%$fsurl%>elements/cssexpr.js"></script> + +% if ( $opt{'position'} eq 'top' ) { + + <script type="text/javascript" src="<%$fsurl%>elements/xmenu.top.js"></script> + <link href="<%$fsurl%>elements/xmenu.top.css" type="text/css" rel="stylesheet"> + +% } else { # elsif ( $opt{'position'} eq 'left' ) { + + <script type="text/javascript" src="<%$fsurl%>elements/xmenu.js"></script> + <link href="<%$fsurl%>elements/xmenu.css" type="text/css" rel="stylesheet"> + +% } + +<link href="<%$fsurl%>elements/freeside.css" type="text/css" rel="stylesheet"> + +<SCRIPT TYPE="text/javascript"> + + webfxMenuImagePath = "<%$fsurl%>images/"; + webfxMenuUseHover = 1; + webfxMenuShowTime = 300; + webfxMenuHideTime = 500; + + var myBar = new WebFXMenuBar; + +% foreach my $item ( keys %menu ) { +% +% my( $url_or_submenu, $tooltip ) = @{ $menu{$item} }; +% +% if ( ref($url_or_submenu) ) { +% +% #warn $item; +% +% my( $subhtml, $submenuname ) = submenu($url_or_submenu, $item); + + <% $subhtml %> + myBar.add(new WebFXMenuButton("<% $item %>", null, "<% $tooltip %>", <% $submenuname %> )); + +% } else { + + myBar.add(new WebFXMenuButton("<% $item %>", "<% $url_or_submenu %>", "<% $tooltip %>" )); + +% } +% +% } + + myBar.show( null, 'vertical' ); + myBar.width = 154; + +</SCRIPT> + +<%init> +my( %opt ) = @_; +my $conf = new FS::Conf; +my $fsurl = $opt{'freeside_baseurl'}; + +my $curuser = $FS::CurrentUser::CurrentUser; + +#Active tickets not assigned to a customer + +tie my %report_customers_lists, 'Tie::IxHash', + 'by customer number' => [ $fsurl. 'search/cust_main.cgi?browse=custnum', '' ], + 'by last name' => [ $fsurl. 'search/cust_main.cgi?browse=last', '' ], + 'by company name' => [ $fsurl. 'search/cust_main.cgi?browse=company', '' ], +; +$report_customers_lists{'by active trouble tickets'} = [ $fsurl. 'search/cust_main.cgi?browse=tickets', '' ] + if $conf->config('ticket_system'); + +tie my %report_customers_search, 'Tie::IxHash'; +$report_customers_search{'by ordering employee'} = [ $fsurl. 'search/cust_main-otaker.cgi' ] + if $curuser->access_right('Configuration'); + +tie my %report_customers, 'Tie::IxHash', + 'List customers' => [ \%report_customers_lists, 'List customers' ], +; +$report_customers{'Search customers'} = [ \%report_customers_search, 'Search customers' ] + if keys %report_customers_search; +$report_customers{'Zip code distribution'} = [ $fsurl.'search/report_cust_main-zip.html', 'Zip codes by number of customers' ]; + +tie my %report_invoices_open, 'Tie::IxHash', + 'All open invoices' => [ $fsurl.'search/cust_bill.html?OPEN_date', 'All invoices with an unpaid balance' ], + '15 day open invoices' => [ $fsurl.'search/cust_bill.html?OPEN15_date', 'Invoices 15 days or older with an unpaid balance' ], + '30 day open invoices' => [ $fsurl.'search/cust_bill.html?OPEN30_date', 'Invoices 30 days or older with an unpaid balance' ], + '60 day open invoices' => [ $fsurl.'search/cust_bill.html?OPEN60_date', 'Invoices 60 days or older with an unpaid balance' ], + '90 day open invoices' => [ $fsurl.'search/cust_bill.html?OPEN90_date', 'Invoices 90 days or older with an unpaid balance' ], + '120 day open invoices' => [ $fsurl.'search/cust_bill.html?OPEN120_date', 'Invoices 120 days or older with an unpaid balance' ], +; + +tie my %report_invoices, 'Tie::IxHash', + 'Open invoices' => [ \%report_invoices_open, 'Open invoices' ], + 'All invoices' => [ $fsurl. 'search/cust_bill.html?date', 'List all invoices' ], + 'Advanced invoice reports' => [ $fsurl.'search/report_cust_bill.html', 'by agent, date range, etc.' ], +; + +tie my %report_services, 'Tie::IxHash'; +if ( $curuser->access_right('Configuration') ) { + $report_services{'Service definitions'} = [ $fsurl.'browse/part_svc.cgi?orderby=active', 'Service definitions by number of active packages' ]; + $report_services{'separator'} = ''; +} +foreach my $svcdb ( FS::part_svc->svc_tables() ) { + + my $name = "FS::$svcdb"->table_info->{'name_plural'} + || PL( "FS::$svcdb"->table_info->{'name'} ); + my $lcname = lc($name); + my $longname = "FS::$svcdb"->table_info->{'longname_plural'} || $name; + my $lclongname = lc($longname); + my $sorts = "FS::$svcdb"->table_info->{'sorts'} || [ 'svcnum' ]; + $sorts = [ $sorts ] unless ref($sorts); + my %svc_url = ( 'm' => $m, + 'action' => 'search', + 'svcdb' => $svcdb, + ); + + tie my %report_svc, 'Tie::IxHash'; + + foreach my $sort ( @$sorts ) { + + my $title = "All $lcname"; + $title .= " by ". FS::part_svc->svc_table_fields($svcdb)->{$sort}->{'label'} + if scalar(@$sorts) > 1; + + $report_svc{$title} = + [ FS::UI::Web::svc_url( %svc_url, 'query' => "magic=all;sortby=$sort" ), + '', + ]; + } + + if ( $curuser->access_right('View/link unlinked services') ) { + $report_svc{"Unlinked $lcname"} = + [ FS::UI::Web::svc_url( %svc_url, 'query' => "magic=unlinked;sortby=". $sorts->[0] ), + "Pre-Freeside $lcname without a customer record", + ]; + } + + $report_services{$name} = [ \%report_svc, $longname ]; + +} + +tie my %report_packages, 'Tie::IxHash'; +if ( $curuser->access_right('Configuration') ) { + $report_packages{'Package definitions'} = [ $fsurl.'browse/part_pkg.cgi?active=1', 'Package definitions by number of active packages' ]; + $report_packages{'separator'} = ''; +} +$report_packages{'All customer packages'} = [ $fsurl.'search/cust_pkg.cgi?pkgnum', 'List all customer packages', ]; +$report_packages{'Suspended customer packages'} = [ $fsurl.'search/cust_pkg.cgi?magic=suspended', 'List suspended packages' ]; +$report_packages{'Customer packages with unconfigured services'} = [ $fsurl.'search/cust_pkg.cgi?APKG_pkgnum', 'List packages which have provisionable services' ]; +$report_packages{'Advanced package reports'} = [ $fsurl.'search/report_cust_pkg.html', 'by agent, date range, status, package definition' ]; + +tie my %report_rating, 'Tie::IxHash', + 'RADIUS sessions' => [ $fsurl.'search/sqlradius.html', '' ], + 'Call Detail Records (CDRs)' => [ $fsurl.'search/report_cdr.html', '' ], +; + +tie my %report_bill_event, 'Tie::IxHash', + 'All billing events' => [ $fsurl.'search/cust_bill_event.html', 'All billing events for a date range' ], + 'Invoice event errors' => [ $fsurl.'search/cust_bill_event.html?failed=1', 'failed credit cards, processor or printer problems, etc.' ], +; + +tie my %report_financial, 'Tie::IxHash', + 'Sales, Credits and Receipts' => [ $fsurl.'graph/report_money_time.html', 'Sales, credits and receipts summary graph' ], + 'Sales Report' => [ $fsurl.'graph/report_cust_bill_pkg.html', 'Sales report and graph (by agent, package class and/or date range)' ], + 'Credit Report' => [ $fsurl.'search/report_cust_credit.html', 'Credit report (by employee and/or date range)' ], + 'Payment Report' => [ $fsurl.'search/report_cust_pay.html', 'Payment report (by type and/or date range)' ], +; +$report_financial{'Payment Batch Report'} = [ $fsurl.'search/pay_batch.html', 'Payment batches (by status and/or date range)' ] + if $conf->exists('batch-enable'); +$report_financial{'A/R Aging'} = [ $fsurl.'search/report_receivables.html', 'Accounts Receivable Aging report' ]; +$report_financial{'Prepaid Income'} = [ $fsurl.'search/report_prepaid_income.html', 'Prepaid income (unearned revenue) report' ]; +$report_financial{'Sales Tax Liability'} = [ $fsurl.'search/report_tax.html', 'Sales tax liability report' ]; +; + +tie my %report_menu, 'Tie::IxHash'; +$report_menu{'Customers'} = [ \%report_customers, 'Customer reports' ] + if $curuser->access_right('List customers'); +$report_menu{'Invoices'} = [ \%report_invoices, 'Invoice reports' ] + if $curuser->access_right('List invoices'); +$report_menu{'Packages'} = [ \%report_packages, 'Package reports' ] + if $curuser->access_right('List packages'); +$report_menu{'Services'} = [ \%report_services, 'Services reports' ] + if $curuser->access_right('List services'); +$report_menu{'Usage'} = [ \%report_rating, 'Usage reports' ] + if $curuser->access_right('List rating data'); +$report_menu{'Billing events'} = [ \%report_bill_event, 'Billing events' ] + if $curuser->access_right('Billing event reports'); +$report_menu{'Financial'} = [ \%report_financial, 'Financial reports' ] + if $curuser->access_right('Financial reports'); + +tie my %tools_importing, 'Tie::IxHash', + 'Import customers from CSV file' => [ $fsurl.'misc/cust_main-import.cgi', '' ], + 'Import one-time charges from CSV file' => [ $fsurl.'misc/cust_main-import_charges.cgi', '' ], + 'Import Call Detail Records (CDRs) from CSV file' => [ $fsurl.'misc/cdr-import.html', '' ], +; + +tie my %tools_exporting, 'Tie::IxHash', + 'Download database dump' => [ $fsurl. 'misc/dump.cgi', '' ], +; + +# <!-- <BR>View active NAS ports: +# <A HREF="browse/nas.cgi">session server</A> --> +# <!-- or <A HREF="browse/nas-sqlradius.cgi">RADIUS</A> +# <BR> --> + +tie my %tools_menu, 'Tie::IxHash', (); +$tools_menu{'Quick payment entry'} = [ $fsurl.'misc/batch-cust_pay.html', 'Enter multiple payments in a batch' ] + if $curuser->access_right('Post payment batch'); +$tools_menu{'Process payment batches'} = [ $fsurl.'search/pay_batch.cgi?magic=_date;open=1;intransit=1', 'Process credit card and electronic check batches' ] + if $conf->exists('batch-enable') && $curuser->access_right('Process batches'); +$tools_menu{'Job Queue'} = [ $fsurl.'search/queue.html', 'View pending job queue' ] + if $curuser->access_right('Job queue'); +$tools_menu{'Importing'} = [ \%tools_importing, 'Import tools' ] + if $curuser->access_right('Import'); +$tools_menu{'Exporting'} = [ \%tools_exporting, 'Export tools' ] + if $curuser->access_right('Export'); + +tie my %config_employees, 'Tie::IxHash', + 'View/Edit employees' => [ $fsurl.'browse/access_user.html', 'Setup internal users' ], + 'View/Edit employee groups' => [ $fsurl.'browse/access_group.html', 'Employee groups allow you to control access to the backend' ], +; + +tie my %config_export_svc_pkg, 'Tie::IxHash', + 'View/Edit exports' => [ $fsurl.'browse/part_export.cgi', 'Provisioning services to external machines, databases and APIs' ], + 'View/Edit service definitions' => [ $fsurl.'browse/part_svc.cgi', 'Services are items you offer to your customers' ], + 'View/Edit package definitions' => [ $fsurl.'browse/part_pkg.cgi', 'One or more services are grouped together into a package and given pricing information. Customers purchase packages, not services' ], + 'View/Edit package classes' => [ $fsurl.'browse/pkg_class.html', 'Package classes define groups of packages, for reporting and convenience purposes.' ], + 'View/Edit cancel reason types' => [ $fsurl.'browse/reason_type.html?class=C', 'Cancel reason types define groups of reasons, for reporting and convenience purposes.' ], + 'View/Edit cancel reasons' => [ $fsurl.'browse/reason.html?class=C', 'Cancel reasons explain why a service was cancelled.' ], + 'View/Edit suspend reason types' => [ $fsurl.'browse/reason_type.html?class=S', 'Suspend reason types define groups of reasons, for reporting and convenience purposes.' ], + 'View/Edit suspend reasons' => [ $fsurl.'browse/reason.html?class=S', 'Suspend reasons explain why a service was suspended.' ], +; + +tie my %config_agent, 'Tie::IxHash', + 'View/Edit agent types' => [ $fsurl.'browse/agent_type.cgi', 'Agent types define groups of package definitions that you can then assign to particular agents' ], + 'View/Edit agents' => [ $fsurl.'browse/agent.cgi', 'Agents are resellers of your service. Agents may be limited to a subset of your full offerings (via their type)' ], +; + +tie my %config_billing, 'Tie::IxHash', + 'View/Edit payment gateways' => [ $fsurl.'browse/payment_gateway.html', 'Credit card and electronic check processors' ], + 'View/Edit invoice events' => [ $fsurl.'browse/part_bill_event.cgi', 'Actions for overdue invoices' ], + 'View/Edit prepaid cards' => [ $fsurl.'search/prepay_credit.html', 'View outstanding cards, generate new cards' ], + 'View/Edit call rates and regions' => [ $fsurl.'browse/rate.cgi', 'Manage rate plans, regions and prefixes for VoIP and call billing' ], + 'View/Edit locales and tax rates' => [ $fsurl.'browse/cust_main_county.cgi', 'Change tax rates, or break down a country into states, or a state into counties and assign different tax rates to each' ], +; + +tie my %config_dialup, 'Tie::IxHash', + 'View/Edit access numbers' => [ $fsurl.'browse/svc_acct_pop.cgi', 'Points of Presence' ], +; + +tie my %config_broadband, 'Tie::IxHash', + 'View/Edit routers' => [ $fsurl.'browse/router.cgi', 'Broadband access routers' ], + 'View/Edit address blocks' => [ $fsurl.'browse/addr_block.cgi', 'Manage address blocks and block assignments to broadband routers' ], +; + +tie my %config_misc, 'Tie::IxHash'; +$config_misc{'View/Edit advertising sources'} = [ $fsurl.'browse/part_referral.html', 'Where a customer heard about your service. Tracked for informational purposes' ] + if $curuser->access_right('Configuration') + || $curuser->access_right('Edit advertising sources') + || $curuser->access_right('Edit global advertising sources'); +if ( $curuser->access_right('Configuration') ) { + $config_misc{'View/Edit virtual fields'} = [ $fsurl.'browse/part_virtual_field.cgi', 'Locally defined fields', ]; + $config_misc{'View/Edit message catalog'} = [ $fsurl.'browse/msgcat.cgi', 'Change error messages and other customizable labels' ]; + $config_misc{'View/Edit inventory classes and inventory'} = [ $fsurl.'browse/inventory_class.html', 'Setup inventory classes and stock inventory' ]; +} + +tie my %config_menu, 'Tie::IxHash'; +if ( $curuser->access_right('Configuration' ) ) { + %config_menu = ( + 'Settings' => [ $fsurl.'config/config-view.cgi', '' ], + 'separator' => '', #its a separator! + 'Employees' => [ \%config_employees, '' ], + 'Provisioning, services and packages' + => [ \%config_export_svc_pkg, '' ], + 'Resellers' => [ \%config_agent, '' ], + 'Billing' => [ \%config_billing, '' ], + 'Dialup' => [ \%config_dialup, '' ], + 'Fixed (username-less) broadband' + => [ \%config_broadband, '' ], + ); +} +$config_menu{'Miscellaneous'} = [ \%config_misc, '' ] + if $curuser->access_right('Configuration') + || $curuser->access_right('Edit advertising sources') + || $curuser->access_right('Edit global advertising sources'); + +tie my %menu, 'Tie::IxHash', + 'Billing Main' => [ $fsurl, 'Billing start page', ], +; +if ( $conf->config('ticket_system') ) { + $menu{'Ticketing Main'} = + [ + ( $conf->config('ticket_system') eq 'RT_External' + ? FS::TicketSystem->baseurl() + : $fsurl.'rt/' + ), + 'Ticketing start page', + ], +} +$menu{'Reports'} = [ \%report_menu, 'Lists, reporting and graphing' ] + if keys %report_menu; +$menu{'Tools'} = [ \%tools_menu, 'Tools' ] + if keys %tools_menu; +$menu{'Configuration'} = [ \%config_menu, 'Configuraiton and setup' ] + if $curuser->access_right('Configuration') + || $curuser->access_right('Edit advertising sources') + || $curuser->access_right('Edit global advertising sources'); + +use vars qw($gmenunum); +$gmenunum = 0; + +sub submenu { + my($submenu, $title) = @_; + my $menunum = $gmenunum++; + + #return two args: html, menuname + + "var myMenu$menunum = new WebFXMenu;\n". + #"myMenu$menunum.useAutoPosition = true;\n". + "myMenu$menunum.emptyText = '$title';\n". + + ( + join("\n", map { + + if ( !ref( $submenu->{$_} ) ) { + + "myMenu$menunum.add(new WebFXMenuSeparator());"; + + } else { + + my($url_or_submenu, $tooltip ) = @{ $submenu->{$_} }; + if ( ref($url_or_submenu) ) { + + my($subhtml, $submenuname ) = submenu($url_or_submenu, $_); #mmm, recursion + + "$subhtml\n". + "myMenu$menunum.add(new WebFXMenuItem(\"$_\", null, \"$tooltip\", $submenuname ));"; + + } else { + + "myMenu$menunum.add(new WebFXMenuItem(\"$_\", \"$url_or_submenu\", \"$tooltip\" ));"; + + } + + } + + } keys %$submenu ) + ). "\n". + "myMenu$menunum.width = 280;\n", + + "myMenu$menunum"; + +} + +</%init> + diff --git a/httemplate/elements/menubar.html b/httemplate/elements/menubar.html index 87a50312c..ec6c13fea 100644 --- a/httemplate/elements/menubar.html +++ b/httemplate/elements/menubar.html @@ -1,8 +1,10 @@ -<% - my($item, $url, @html); - while (@_) { - ($item, $url) = splice(@_,0,2); - push @html, qq!<A HREF="$url">$item</A>!; - } -%> -<%= join(' | ', @html) %> +% +% my($item, $url, @html); +% while (@_) { +% ($item, $url) = splice(@_,0,2); +% next if $item =~ /^\s*Main\s+Menu\s*$/i; +% push @html, qq!<A HREF="$url">$item</A>!; +% } +% + +<% join(' | ', @html) %> diff --git a/httemplate/elements/overlibmws.js b/httemplate/elements/overlibmws.js index fba1105b5..5ef50d68f 100644 --- a/httemplate/elements/overlibmws.js +++ b/httemplate/elements/overlibmws.js @@ -1,7 +1,7 @@ /*
Do not remove or change this notice.
overlibmws.js core module - Copyright Foteos Macrides 2002-2005. All rights reserved.
- Initial: August 18, 2002 - Last Revised: February 10, 2005
+ Initial: August 18, 2002 - Last Revised: May 30, 2006
This module is subject to the same terms of usage as for Erik Bosrup's overLIB,
though only a minority of the code and API now correspond with Erik's version.
See the overlibmws Change History and Command Reference via:
@@ -14,30 +14,30 @@ */
// PRE-INIT -- Ignore these lines, configuration is below.
-var OLloaded=0,pmCnt=1,pMtr=new Array(),OLv,OLudf,OLrefXY;
-var OLpct=new Array("83%","67%","83%","100%","117%","150%","200%","267%");
-var OLbubblePI=0,OLcrossframePI=0,OLdebugPI=0,OLdraggablePI=0,OLexclusivePI=0,OLfilterPI=0;
-var OLfunctionPI=0,OLhidePI=0,OLiframePI=0,OLovertwoPI=0,OLscrollPI=0,OLshadowPI=0;
+var OLloaded=0,pmCnt=1,pMtr=new Array(),OLcmdLine=new Array(),OLrunTime=new Array(),OLv,OLudf,
+OLpct=new Array("83%","67%","83%","100%","117%","150%","200%","267%"),OLrefXY,
+OLbubblePI=0,OLcrossframePI=0,OLdebugPI=0,OLdraggablePI=0,OLexclusivePI=0,OLfilterPI=0,
+OLfunctionPI=0,OLhidePI=0,OLiframePI=0,OLovertwoPI=0,OLscrollPI=0,OLshadowPI=0,OLprintPI=0;
if(typeof OLgateOK=='undefined')var OLgateOK=1;
-OLregCmds(
- 'inarray,caparray,caption,sticky,nofollow,background,noclose,mouseoff,offdelay,right,left,'
-+'center,offsetx,offsety,fgcolor,bgcolor,cgcolor,textcolor,capcolor,closecolor,width,wrap,'
-+'wrapmax,height,border,base,status,autostatus,autostatuscap,snapx,snapy,fixx,fixy,relx,rely,'
-+'midx,midy,ref,refc,refp,refx,refy,fgbackground,bgbackground,cgbackground,padx,pady,fullhtml,'
-+'below,above,vcenter,capicon,textfont,captionfont,closefont,textsize,captionsize,closesize,'
-+'timeout,delay,hauto,vauto,nojustx,nojusty,closetext,closeclick,closetitle,fgclass,bgclass,'
-+'cgclass,capbelow,textpadding,textfontclass,captionpadding,captionfontclass,closefontclass,'
-+'label,donothing');
-
+var OLp1or2c='inarray,caparray,caption,closetext,right,left,center,autostatuscap,padx,pady,'
++'below,above,vcenter,donothing',OLp1or2co='nofollow,background,offsetx,offsety,fgcolor,'
++'bgcolor,cgcolor,textcolor,capcolor,width,wrap,wrapmax,height,border,base,status,autostatus,'
++'snapx,snapy,fixx,fixy,relx,rely,midx,midy,ref,refc,refp,refx,refy,fgbackground,bgbackground,'
++'cgbackground,fullhtml,capicon,textfont,captionfont,textsize,captionsize,timeout,delay,hauto,'
++'vauto,nojustx,nojusty,fgclass,bgclass,cgclass,capbelow,textpadding,textfontclass,'
++'captionpadding,captionfontclass,sticky,noclose,mouseoff,offdelay,closecolor,closefont,'
++'closesize,closeclick,closetitle,closefontclass,decode',OLp1or2o='text,cap,close,hpos,vpos,'
++'padxl,padxr,padyt,padyb',OLp1co='label',OLp1or2=OLp1or2co+','+OLp1or2o,OLp1=OLp1co+','+'frame';
+OLregCmds(OLp1or2c+','+OLp1or2co+','+OLp1co);
function OLud(v){return eval('typeof ol_'+v+'=="undefined"')?1:0;}
-// DEFAULT CONFIGURATION -- See overlibConfig.txt for descriptions.
-if(OLud('fgcolor'))var ol_fgcolor="#CCCCFF";
+// DEFAULT CONFIGURATION -- See overlibConfig.txt for descriptions
+if(OLud('fgcolor'))var ol_fgcolor="#ccccff";
if(OLud('bgcolor'))var ol_bgcolor="#333399";
if(OLud('cgcolor'))var ol_cgcolor="#333399";
if(OLud('textcolor'))var ol_textcolor="#000000";
-if(OLud('capcolor'))var ol_capcolor="#FFFFFF";
-if(OLud('closecolor'))var ol_closecolor="#EEEEFF";
+if(OLud('capcolor'))var ol_capcolor="#ffffff";
+if(OLud('closecolor'))var ol_closecolor="#eeeeff";
if(OLud('textfont'))var ol_textfont="Verdana,Arial,Helvetica";
if(OLud('captionfont'))var ol_captionfont="Verdana,Arial,Helvetica";
if(OLud('closefont'))var ol_closefont="Verdana,Arial,Helvetica";
@@ -106,43 +106,41 @@ if(OLud('vauto'))var ol_vauto=0; if(OLud('nojustx'))var ol_nojustx=0;
if(OLud('nojusty'))var ol_nojusty=0;
if(OLud('label'))var ol_label="";
+if(OLud('decode'))var ol_decode=0;
// ARRAY CONFIGURATION - See overlibConfig.txt for descriptions.
if(OLud('texts'))var ol_texts=new Array("Text 0","Text 1");
if(OLud('caps'))var ol_caps=new Array("Caption 0","Caption 1");
// END CONFIGURATION -- Don't change anything below, all configuration is above.
// INIT -- Runtime variables.
-var o3_text="",o3_cap="",o3_sticky=0,o3_nofollow=0,o3_background="",o3_noclose=0,o3_mouseoff=0;
-var o3_offdelay=300,o3_hpos=RIGHT,o3_offsetx=10,o3_offsety=10,o3_fgcolor="",o3_bgcolor="";
-var o3_cgcolor="",o3_textcolor="",o3_capcolor="",o3_closecolor="",o3_width=200,o3_wrap=0;
-var o3_wrapmax=0,o3_height= -1,o3_border=1,o3_base=0,o3_status="",o3_autostatus=0,o3_snapx=0;
-var o3_snapy=0,o3_fixx= -1,o3_fixy= -1,o3_relx=null,o3_rely=null,o3_midx=null,o3_midy=null;
-var o3_ref="",o3_refc='UL',o3_refp='UL',o3_refx=0,o3_refy=0,o3_fgbackground="";
-var o3_bgbackground="",o3_cgbackground="",o3_padxl=0,o3_padxr=0,o3_padyt=0,o3_padyb=0;
-var o3_fullhtml=0,o3_vpos=BELOW,o3_capicon="",o3_textfont="Verdana,Arial,Helvetica";
-var o3_captionfont="Verdana,Arial,Helvetica",o3_closefont="Verdana,Arial,Helvetica";
-var o3_textsize=1,o3_captionsize=1,o3_closesize=1,o3_frame=self,o3_timeout=0,o3_delay=0;
-var o3_hauto=0,o3_vauto=0,o3_nojustx=0,o3_nojusty=0,o3_close="Close",o3_closeclick=0;
-var o3_closetitle="",o3_fgclass="",o3_bgclass="",o3_cgclass="",o3_textpadding=2;
-var o3_textfontclass="",o3_captionpadding=2,o3_captionfontclass="",o3_closefontclass="";
-var o3_capbelow=0,o3_label="",CSSOFF=DONOTHING,CSSCLASS=DONOTHING;
-var OLx=0,OLy=0,OLshowingsticky=0,OLallowmove=0,OLremovecounter=0;
-var OLdelayid=0,OLtimerid=0,OLshowid=0,OLndt=0;
-var over=null,OLfnRef="",OLhover=0;
-var OLua=navigator.userAgent.toLowerCase();
-var OLns4=(navigator.appName=='Netscape'&&parseInt(navigator.appVersion)==4);
-var OLns6=(document.getElementById)?1:0;
-var OLie4=(document.all)?1:0;
-var OLgek=(OLv=OLua.match(/gecko\/(\d{8})/i))?parseInt(OLv[1]):0;
-var OLmac=(OLua.indexOf('mac')>=0)?1:0;
-var OLsaf=(OLua.indexOf('safari')>=0)?1:0;
-var OLkon=(OLua.indexOf('konqueror')>=0)?1:0;
-var OLkht=(OLsaf||OLkon)?1:0;
-var OLopr=(OLua.indexOf('opera')>=0)?1:0;
-var OLop7=(OLopr&&document.createTextNode)?1:0;
+var o3_text="",o3_cap="",o3_sticky=0,o3_nofollow=0,o3_background="",o3_noclose=0,o3_mouseoff=0,
+o3_offdelay=300,o3_hpos=RIGHT,o3_offsetx=10,o3_offsety=10,o3_fgcolor="",o3_bgcolor="",
+o3_cgcolor="",o3_textcolor="",o3_capcolor="",o3_closecolor="",o3_width=200,o3_wrap=0,
+o3_wrapmax=0,o3_height= -1,o3_border=1,o3_base=0,o3_status="",o3_autostatus=0,o3_snapx=0,
+o3_snapy=0,o3_fixx= -1,o3_fixy= -1,o3_relx=null,o3_rely=null,o3_midx=null,o3_midy=null,o3_ref="",
+o3_refc='UL',o3_refp='UL',o3_refx=0,o3_refy=0,o3_fgbackground="",o3_bgbackground="",
+o3_cgbackground="",o3_padxl=0,o3_padxr=0,o3_padyt=0,o3_padyb=0,o3_fullhtml=0,o3_vpos=BELOW,
+o3_capicon="",o3_textfont="Verdana,Arial,Helvetica",o3_captionfont="",o3_closefont="",
+o3_textsize=1,o3_captionsize=1,o3_closesize=1,o3_frame=self,o3_timeout=0,o3_delay=0,o3_hauto=0,
+o3_vauto=0,o3_nojustx=0,o3_nojusty=0,o3_close="",o3_closeclick=0,o3_closetitle="",o3_fgclass="",
+o3_bgclass="",o3_cgclass="",o3_textpadding=2,o3_textfontclass="",o3_captionpadding=2,
+o3_captionfontclass="",o3_closefontclass="",o3_capbelow=0,o3_label="",o3_decode=0,
+CSSOFF=DONOTHING,CSSCLASS=DONOTHING,OLdelayid=0,OLtimerid=0,OLshowid=0,OLndt=0,over=null,
+OLfnRef="",OLhover=0,OLx=0,OLy=0,OLshowingsticky=0,OLallowmove=0,OLcC=null,
+OLua=navigator.userAgent.toLowerCase(),
+OLns4=(navigator.appName=='Netscape'&&parseInt(navigator.appVersion)==4),
+OLns6=(document.getElementById)?1:0,
+OLie4=(document.all)?1:0,
+OLgek=(OLv=OLua.match(/gecko\/(\d{8})/i))?parseInt(OLv[1]):0,
+OLmac=(OLua.indexOf('mac')>=0)?1:0,
+OLsaf=(OLua.indexOf('safari')>=0)?1:0,
+OLkon=(OLua.indexOf('konqueror')>=0)?1:0,
+OLkht=(OLsaf||OLkon)?1:0,
+OLopr=(OLua.indexOf('opera')>=0)?1:0,
+OLop7=(OLopr&&document.createTextNode)?1:0;
if(OLopr){OLns4=OLns6=0;if(!OLop7)OLie4=0;}
-var OLieM=((OLie4&&OLmac)&&!(OLkht||OLopr))?1:0;
-var OLie5=0,OLie55=0;if(OLie4&&!OLop7){
+var OLieM=((OLie4&&OLmac)&&!(OLkht||OLopr))?1:0,
+OLie5=0,OLie55=0;if(OLie4&&!OLop7){
if((OLv=OLua.match(/msie (\d\.\d+)\.*/i))&&(OLv=parseFloat(OLv[1]))>=5.0){
OLie5=1;OLns6=0;if(OLv>=5.5)OLie55=1;}if(OLns6)OLie4=0;}
if(OLns4)window.onresize=function(){location.reload();}
@@ -156,14 +154,16 @@ else{overlib=nd=cClick=OLpageDefaults=no_overlib;} // Loads defaults then args into runtime variables.
function overlib(){
if(!(OLloaded&&OLgateOK))return;
-if((OLexclusivePI)&&OLisExclusive(overlib.arguments))return true;
+if((OLexclusivePI)&&OLisExclusive(arguments))return true;
if(OLchkMh)OLmh();
if(OLndt&&!OLtimerid)OLndt=0;if(over)cClick();
-OLloadP1or2();OLload('close,closeclick,closetitle,noclose,mouseoff,offdelay,sticky,'
-+'closecolor,closefont,closesize,closefontclass,frame,label');OLfnRef="";OLhover=0;
+OLload(OLp1or2);OLload(OLp1);
+OLfnRef="";OLhover=0;
OLsetRunTimeVar();
-OLparseTokens('o3_',overlib.arguments);
+OLparseTokens('o3_',arguments);
if(!(over=OLmkLyr()))return false;
+if(o3_decode)OLdecode();
+if(OLprintPI)OLchkPrint();
if(OLbubblePI)OLchkForBubbleEffect();
if(OLdebugPI)OLsetDebugCanShow();
if(OLshadowPI)OLinitShadow();
@@ -172,7 +172,7 @@ if(OLfilterPI)OLinitFilterLyr(); if(OLexclusivePI&&o3_exclusive&&o3_exclusivestatus!="")o3_status=o3_exclusivestatus;
else if(o3_autostatus==2&&o3_cap!="")o3_status=o3_cap;
else if(o3_autostatus==1&&o3_text!="")o3_status=o3_text;
-if(o3_delay==0){return OLmain();
+if(!o3_delay){return OLmain();
}else{OLdelayid=setTimeout("OLmain()",o3_delay);
if(o3_status!=""){self.status=o3_status;return true;}
else if(!(OLop7&&event&&event.type=='mouseover'))return false;}
@@ -180,25 +180,24 @@ else if(!(OLop7&&event&&event.type=='mouseover'))return false;} // Clears popups if appropriate
function nd(time){
-if(!(OLloaded&&OLgateOK))return;
-if((OLexclusivePI)&&OLisExclusive())return true;
+if(OLloaded&&OLgateOK){if(!((OLexclusivePI)&&OLisExclusive())){
if(time&&over&&!o3_delay){if(OLtimerid>0)clearTimeout(OLtimerid);
OLtimerid=(OLhover&&o3_frame==self&&!OLcursorOff())?0:
-setTimeout("cClick()",(o3_timeout=OLndt=time));
-}else{if(OLremovecounter>=1)OLshowingsticky=0;if(!OLshowingsticky){
-OLallowmove=0;if(over)OLhideObject(over);}else{OLremovecounter++;}}
-return true;
+setTimeout("cClick()",(o3_timeout=OLndt=time));}else{
+if(!OLshowingsticky){OLallowmove=0;if(over)OLhideObject(over);}}}}
+return false;
}
// Close function for stickies
function cClick(){
-if(OLloaded&&OLgateOK){OLhover=0;if(over)OLhideObject(over);OLshowingsticky=0;}
+if(OLloaded&&OLgateOK){OLhover=0;if(over){
+if(OLovertwoPI&&over==over2)cClick2();OLhideObject(over);OLshowingsticky=0;}}
return false;
}
// Sets page-specific defaults.
function OLpageDefaults(){
-OLparseTokens('ol_',OLpageDefaults.arguments);
+OLparseTokens('ol_',arguments);
}
// For unsupported browsers.
@@ -210,24 +209,14 @@ function no_overlib(){return false;} function OLmain(){
o3_delay=0;
if(o3_frame==self){if(o3_noclose)OLoptMOUSEOFF(0);else if(o3_mouseoff)OLoptMOUSEOFF(1);}
-OLdoLyr();
-OLallowmove=0;if(o3_timeout>0){
+if(o3_sticky)OLshowingsticky=1;OLdoLyr();OLallowmove=0;if(o3_timeout>0){
if(OLtimerid>0)clearTimeout(OLtimerid);OLtimerid=setTimeout("cClick()",o3_timeout);}
if(o3_ref){OLrefXY=OLgetRefXY(o3_ref);if(OLrefXY[0]==null){o3_ref="";o3_midx=0;o3_midy=0;}}
-OLdisp(o3_status);
-if(OLdraggablePI)OLcheckDrag();
+OLdisp(o3_status);if(OLdraggablePI)OLcheckDrag();
if(o3_status!="")return true;else if(!(OLop7&&event&&event.type=='mouseover'))return false;
}
-// Loads defaults for primaries or secondaries
-function OLloadP1or2(){
-OLload('text,cap,capbelow,textpadding,captionpadding,border,base,status,autostatus,nofollow,'
-+'width,wrap,wrapmax,height,hpos,vpos,offsetx,offsety,snapx,snapy,relx,rely,midx,midy,ref,'
-+'refc,refp,refx,refy,fixx,fixy,nojustx,nojusty,hauto,vauto,timeout,delay,fgcolor,bgcolor,'
-+'cgcolor,textcolor,capcolor,textfont,captionfont,textsize,captionsize,fgbackground,'
-+'bgbackground,cgbackground,capicon,background,padxl,padxr,padyt,padyb,fullhtml,fgclass,'
-+'bgclass,cgclass,textfontclass,captionfontclass');
-}
+// Loads o3_ variables
function OLload(c){var i,m=c.split(',');for(i=0;i<m.length;i++)eval('o3_'+m[i]+'=ol_'+m[i]);}
// Chooses LGF
@@ -258,8 +247,7 @@ if(o3_bgcolor!='')o3_bgcolor=' bgcolor="'+o3_bgcolor+'"'; if(o3_cgcolor!='')o3_cgcolor=' bgcolor="'+o3_cgcolor+'"';
if(o3_height>0)o3_height=' height="'+o3_height+'"';else o3_height='';}
if(!OLns4)OLrepositionTo(over,(OLns6?20:0),0);var lyrHtml=OLdoLGF();
-if(o3_sticky){if(OLtimerid>0){clearTimeout(OLtimerid);OLtimerid=0;}
-OLshowingsticky=1;OLremovecounter=0;}
+if(o3_sticky&&OLtimerid>0){clearTimeout(OLtimerid);OLtimerid=0;}
if(o3_wrap&&!o3_fullhtml){OLlayerWrite(lyrHtml);
o3_width=(OLns4?over.clip.width:over.offsetWidth);
if(OLns4&&o3_wrapmax<1)o3_wrapmax=o3_frame.innerWidth-40;
@@ -279,19 +267,19 @@ OLsetBackground('');return t; // Makes table with caption and optional close link
function OLcontentCaption(txt,title,close){
-var closing='',closeevent='onmouseover',caption,t;
-if(o3_closeclick==1)closeevent=(o3_closetitle?'title="'+o3_closetitle+'" ':'')+'onclick';
+var closing=(OLprintPI?OLprintCapLGF():''),closeevent='onmouseover',caption,t,
+cC='javascript:return '+OLfnRef+(OLovertwoPI&&over==over2?'cClick2();':'cClick();');
+if(o3_closeclick)closeevent=(o3_closetitle?'title="'+o3_closetitle+'" ':'')+'onclick';
if(o3_capicon!='')o3_capicon='<img src="'+o3_capicon+'" /> ';
-if(close!=''){closing='<td align="right"><a href="javascript:return '+OLfnRef+'cClick();" '
-+closeevent+'="return '+OLfnRef+'cClick();"'+(o3_closefontclass?' class="'+o3_closefontclass
-+'">':'>'+OLlgfUtil(0,'','span',o3_closecolor,o3_closefont,o3_closesize))+close
-+(o3_closefontclass?'':OLlgfUtil(1,'','span'))+'</a></td>';}
+if(close){closing+='<td align="right"><a href="'+cC+'" '
++closeevent+'="'+cC+'"'+(o3_closefontclass?' class="'+o3_closefontclass
++'">':'>'+OLlgfUtil(0,0,'','span',o3_closecolor,o3_closefont,o3_closesize))+close
++(o3_closefontclass?'':OLlgfUtil(1,0,'','span'))+'</a></td>';}
caption='<table'+OLwd(0)+' border="0" cellpadding="'+o3_captionpadding+'" cellspacing="0"'
+(o3_cgclass?' class="'+o3_cgclass+'"':o3_cgcolor+o3_cgbackground)+'><tr><td'+OLwd(0)
+(o3_cgclass?' class="'+o3_cgclass+'">':'>')+(o3_captionfontclass?'<div class="'
-+o3_captionfontclass+'">':'<strong>'
-+OLlgfUtil(0,'','div',o3_capcolor,o3_captionfont,o3_captionsize))+o3_capicon+title
-+OLlgfUtil(1,'','div')+(o3_captionfontclass?'':'</strong>')+'</td>'+closing+'</tr></table>';
++o3_captionfontclass+'">':OLlgfUtil(0,1,'','div',o3_capcolor,o3_captionfont,
+o3_captionsize))+o3_capicon+title+OLlgfUtil(1,1,'','div')+'</td>'+closing+'</tr></table>';
t=OLbgLGF()+(o3_capbelow?OLfgLGF(txt)+caption:caption+OLfgLGF(txt))+OLbaseLGF();
OLsetBackground('');return t;
}
@@ -302,8 +290,8 @@ var t;if(hasfullhtml){t=txt;}else{t='<table'+OLwd(1) +' border="0" cellpadding="0" cellspacing="0" '+'height="'+o3_height
+'"><tr><td colspan="3" height="'+o3_padyt+'"></td></tr><tr><td width="'
+o3_padxl+'"></td><td valign="top"'+OLwd(2)+'>'
-+OLlgfUtil(0,o3_textfontclass,'div',o3_textcolor,o3_textfont,o3_textsize)+txt+
-OLlgfUtil(1,'','div')+'</td><td width="'+o3_padxr+'"></td></tr><tr><td colspan="3" height="'
++OLlgfUtil(0,0,o3_textfontclass,'div',o3_textcolor,o3_textfont,o3_textsize)+txt+
+OLlgfUtil(1,0,'','div')+'</td><td width="'+o3_padxr+'"></td></tr><tr><td colspan="3" height="'
+o3_padyb+'"></td></tr></table>';}
OLsetBackground(image);return t;
}
@@ -317,14 +305,15 @@ function OLfgLGF(t){ return '<table'+OLwd(0)+o3_height+' border="0" cellpadding="'+o3_textpadding
+'" cellspacing="0"'+(o3_fgclass?' class="'+o3_fgclass+'"':o3_fgcolor+o3_fgbackground)
+'><tr><td valign="top"'+(o3_fgclass?' class="'+o3_fgclass+'"':'')+'>'
-+OLlgfUtil(0,o3_textfontclass,'div',o3_textcolor,o3_textfont,o3_textsize)+t
-+OLlgfUtil(1,'','div')+'</td></tr></table>';
++OLlgfUtil(0,0,o3_textfontclass,'div',o3_textcolor,o3_textfont,o3_textsize)+t
++(OLprintPI?OLprintFgLGF():'')+OLlgfUtil(1,0,'','div')+'</td></tr></table>';
}
-function OLlgfUtil(end,tfc,ele,col,fac,siz){
-if(end)return ('</'+(OLns4?'font':ele)+'>');else return (tfc?'<div class="'+tfc+'">':
-('<'+(OLns4?'font color="'+col+'" face="'+OLquoteMultiNameFonts(fac)+'" size="'+siz:ele
-+' style="color:'+col+';font-family:'+OLquoteMultiNameFonts(fac)+';font-size:'+siz+';'
-+(ele=='span'?'text-decoration:underline;':''))+'">'));
+function OLlgfUtil(end,stg,tfc,ele,col,fac,siz){
+if(end)return ('</'+(OLns4?'font'+(stg?'></strong':''):ele)+'>');else return (tfc?'<div '
++'class="' +tfc +'">':('<'+(OLns4?(stg?'strong><':'')+'font color="'+col+'" face="'
++OLquoteMultiNameFonts(fac)+'" size="'+siz:ele+' style="color:'+col
++(stg?';font-weight:bold':'')+';font-family:'+OLquoteMultiNameFonts(fac)+';font-size:'
++siz+';'+(ele=='span'?'text-decoration:underline;':''))+'">'));
}
function OLquoteMultiNameFonts(f){
var i,v,pM=f.split(',');
@@ -354,34 +343,33 @@ else{if(OLns6)over.style.width=o3_width+'px';over.style.backgroundImage='url('+i */
// Displays layer
function OLdisp(s){
-if(OLallowmove==0){if(OLshadowPI)OLdispShadow();if(OLiframePI)OLdispIfs();OLplaceLayer();
+if(!OLallowmove){if(OLshadowPI)OLdispShadow();if(OLiframePI)OLdispIfs();OLplaceLayer();
if(OLndt)OLshowObject(over);else OLshowid=setTimeout("OLshowObject(over)",1);
OLallowmove=(o3_sticky||o3_nofollow)?0:1;}OLndt=0;if(s!="")self.status=s;
}
// Decides placement of layer.
function OLplaceLayer(){
-var snp,X,Y,pgLeft,pgTop,pWd=o3_width,pHt,iWd=100,iHt=100,SB=0,LM=0,CX=0,TM=0,BM=0,CY=0;
-var o=OLfd(),nsb=(OLgek>=20010505&&!o3_frame.scrollbars.visible)?1:0;
+var snp,X,Y,pgLeft,pgTop,pWd=o3_width,pHt,iWd=100,iHt=100,SB=0,LM=0,CX=0,TM=0,BM=0,CY=0,
+o=OLfd(),nsb=(OLgek>=20010505&&!o3_frame.scrollbars.visible)?1:0;
if(!OLkht&&o&&o.clientWidth)iWd=o.clientWidth;
else if(o3_frame.innerWidth){SB=Math.ceil(1.4*(o3_frame.outerWidth-o3_frame.innerWidth));
if(SB>20)SB=20;iWd=o3_frame.innerWidth;}
pgLeft=(OLie4)?o.scrollLeft:o3_frame.pageXOffset;
-if(OLie55&&OLfilterPI&&o3_filtershadow)SB=CX=5;else
+if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow)SB=CX=5;else
if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowx){SB+=((o3_shadowx>0)?o3_shadowx:0);
LM=((o3_shadowx<0)?Math.abs(o3_shadowx):0);CX=Math.abs(o3_shadowx);}
if(o3_ref!=""||o3_fixx> -1||o3_relx!=null||o3_midx!=null){
-if(o3_ref!=""){
-X=OLrefXY[0];if(OLie55&&OLfilterPI&&o3_filtershadow){if(o3_refp=='UR'||o3_refp=='LR')X -= 5;}
-else if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowx){
-if(o3_shadowx<0&&(o3_refp=='UL'||o3_refp=='LL'))X += o3_shadowx;
-else if(o3_shadowx>0&&(o3_refp=='UR'||o3_refp=='LR'))X -= o3_shadowx;}
+if(o3_ref!=""){X=OLrefXY[0];if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow){
+if(o3_refp=='UR'||o3_refp=='LR')X-=5;}
+else if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowx){
+if(o3_shadowx<0&&(o3_refp=='UL'||o3_refp=='LL'))X-=o3_shadowx;else
+if(o3_shadowx>0&&(o3_refp=='UR'||o3_refp=='LR'))X-=o3_shadowx;}
}else{if(o3_midx!=null){
X=parseInt(pgLeft+((iWd-pWd-SB-LM)/2)+o3_midx);
}else{if(o3_relx!=null){
if(o3_relx>=0)X=pgLeft+o3_relx+LM;else X=pgLeft+o3_relx+iWd-pWd-SB;
-}else{
-X=o3_fixx+LM;}}}
+}else{X=o3_fixx+LM;}}}
}else{
if(o3_hauto){
if(o3_hpos==LEFT&&OLx-pgLeft<iWd/2&&OLx-pWd-o3_offsetx<pgLeft+LM)o3_hpos=RIGHT;else
@@ -398,13 +386,12 @@ if(!OLkht&&!nsb&&o&&o.clientHeight)iHt=o.clientHeight; else if(o3_frame.innerHeight)iHt=o3_frame.innerHeight;
if(OLbubblePI&&o3_bubble)pHt=OLbubbleHt;else pHt=OLns4?over.clip.height:over.offsetHeight;
if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowy){TM=(o3_shadowy<0)?Math.abs(o3_shadowy):0;
-if(OLie55&&OLfilterPI&&o3_filtershadow)BM=CY=5;else
+if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow)BM=CY=5;else
BM=(o3_shadowy>0)?o3_shadowy:0;CY=Math.abs(o3_shadowy);}
if(o3_ref!=""||o3_fixy> -1||o3_rely!=null||o3_midy!=null){
-if(o3_ref!=""){
-Y=OLrefXY[1];if(OLie55&&OLfilterPI&&o3_filtershadow){if(o3_refp=='LL'||o3_refp=='LR')Y -= 5;}
-else if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowy){
-if(o3_shadowy<0&&(o3_refp=='UL'||o3_refp=='UR'))Y+=o3_shadowy;else
+if(o3_ref!=""){Y=OLrefXY[1];if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow){
+if(o3_refp=='LL'||o3_refp=='LR')Y-=5;}else if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowy){
+if(o3_shadowy<0&&(o3_refp=='UL'||o3_refp=='UR'))Y-=o3_shadowy;else
if(o3_shadowy>0&&(o3_refp=='LL'||o3_refp=='LR'))Y-=o3_shadowy;}
}else{if(o3_midy!=null){
Y=parseInt(pgTop+((iHt-pHt-CY)/2)+o3_midy);
@@ -434,54 +421,56 @@ return (!OLop7&&fdc&&fdc!='BackCompat'&&fdd&&fdd.clientWidth)?fd.documentElement }
// Gets location of REFerence object
-function OLgetRefXY(r){
-var mn=r,mr=OLgetRef(mn),o,of,rXY;
-if(!mr)return [null,null];
-o=mr;rXY=[o3_refx,o3_refy];
-if(OLns4){if(typeof mr.length!='undefined'&&mr.length>1){
-o=mr[0];rXY[0]+=mr[0].x+mr[1].pageX;rXY[1]+=mr[0].y+mr[1].pageY;
-}else{if((mr.toString().indexOf('Image')!= -1)||(mr.toString().indexOf('Anchor')!= -1)){
-rXY[0]+=mr.x;rXY[1]+=mr.y;}else{rXY[0]+=mr.pageX;rXY[1]+=mr.pageY;}}
-}else{rXY[0]+=OLpageLoc(mr,'Left');rXY[1]+=OLpageLoc(mr,'Top');}
-of=OLgetRefOffsets(o);rXY[0]+=of[0];rXY[1]+=of[1];
+function OLgetRefXY(r,d){
+var o=OLgetRef(r,d),ob=o,rXY=[o3_refx,o3_refy],of;
+if(!o)return [null,null];
+if(OLns4){if(typeof o.length!='undefined'&&o.length>1){
+ob=o[0];rXY[0]+=o[0].x+o[1].pageX;rXY[1]+=o[0].y+o[1].pageY;
+}else{if((o.toString().indexOf('Image')!= -1)||(o.toString().indexOf('Anchor')!= -1)){
+rXY[0]+=o.x;rXY[1]+=o.y;}else{rXY[0]+=o.pageX;rXY[1]+=o.pageY;}}
+}else{rXY[0]+=OLpageLoc(o,'Left');rXY[1]+=OLpageLoc(o,'Top');}
+of=OLgetRefOffsets(ob);rXY[0]+=of[0];rXY[1]+=of[1];
return rXY;
}
-function OLgetRef(l){var r=OLgetRefById(l);return (r)?r:OLgetRefByName(l);}
+function OLgetRef(l,d){var r=OLgetRefById(l,d);return (r)?r:OLgetRefByName(l,d);}
// Seeks REFerence by id
function OLgetRefById(l,d){
-var r="",j;l=(l||'overDiv');d=(d||o3_frame.document);
-if(OLie4&&d.all){return d.all[l];}else if(d.getElementById){return d.getElementById(l);
-}else if(d.layers&&d.layers.length>0){if(d.layers[l])return d.layers[l];
+l=(l||'overDiv');d=(d||o3_frame.document);var j,r;
+if(OLie4&&d.all)return d.all[l];if(d.getElementById)return d.getElementById(l);
+if(d.layers&&d.layers.length>0){if(d.layers[l])return d.layers[l];
for(j=0;j<d.layers.length;j++){r=OLgetRefById(l,d.layers[j].document);if(r)return r;}}
return null;
}
-// Seeks REFerence by name (for img and a)
+// Seeks REFerence by name
function OLgetRefByName(l,d){
-var r=null,j;d=(d||o3_frame.document);
-if(typeof d.images[l]!='undefined'&&d.images[l]){return d.images[l];
-}else if(typeof d.anchors[l]!='undefined'&&d.anchors[l]){return d.anchors[l];
-}else if(d.layers&&d.layers.length>0){
-for(j=0;j<d.layers.length;j++){r=OLgetRefByName(l,d.layers[j].document);
-if(r&&r.length>0)return r;else if(r)return [r,d.layers[j]];}}
+d=(d||o3_frame.document);var j,r,v=OLie4?d.all.tags('iframe'):
+OLns6?d.getElementsByTagName('iframe'):null;
+if(typeof d.images!='undefined'&&d.images[l])return d.images[l];
+if(typeof d.anchors!='undefined'&&d.anchors[l])return d.anchors[l];
+if(v)for(j=0;j<v.length;j++)if(v[j].name==l)return v[j];
+if(d.layers&&d.layers.length>0)for(j=0;j<d.layers.length;j++){
+r=OLgetRefByName(l,d.layers[j].document);
+if(r&&r.length>0)return r;else if(r)return [r,d.layers[j]];}
return null;
}
// Gets layer vs REFerence offsets
function OLgetRefOffsets(o){
-var mc=o3_refc.toUpperCase(),mp=o3_refp.toUpperCase(),mW=0,mH=0,pW=0,pH=0,off=[0,0];
+var c=o3_refc.toUpperCase(),p=o3_refp.toUpperCase(),W=0,H=0,pW=0,pH=0,of=[0,0];
pW=(OLbubblePI&&o3_bubble)?o3_width:OLns4?over.clip.width:over.offsetWidth;
pH=(OLbubblePI&&o3_bubble)?OLbubbleHt:OLns4?over.clip.height:over.offsetHeight;
-if((!OLop7)&&o.toString().indexOf('Image')!= -1){mW=o.width;mH=o.height;
-}else if((!OLop7)&&o.toString().indexOf('Anchor')!= -1){mc=o3_refc='UL';}else{
-mW=(OLns4)?o.clip.width:o.offsetWidth;mH=(OLns4)?o.clip.height:o.offsetHeight;}
-if(mc=='UL'){off=(mp=='UR')?[-pW,0]:(mp=='LL')?[0,-pH]:(mp=='LR')?[-pW,-pH]:[0,0];
-}else if(mc=='UR'){off=(mp=='UR')?[mW-pW,0]:(mp=='LL')?[mW,-pH]:(mp=='LR')?[mW-pW,-pH]:[mW,0];
-}else if(mc=='LL'){off=(mp=='UR')?[-pW,mH]:(mp=='LL')?[0,mH-pH]:(mp=='LR')?[-pW,mH-pH]:[0,mH];
-}else if(mc=='LR'){off=(mp=='UR')?[mW-pW,mH]:(mp=='LL')?[mW,mH-pH]:(mp=='LR')?[mW-pW,mH-pH]:
-[mW,mH];}
-return off;
+if((!OLop7)&&o.toString().indexOf('Image')!= -1){W=o.width;H=o.height;
+}else if((!OLop7)&&o.toString().indexOf('Anchor')!= -1){c=o3_refc='UL';}else{
+W=(OLns4)?o.clip.width:o.offsetWidth;H=(OLns4)?o.clip.height:o.offsetHeight;}
+if((OLns4||(OLns6&&OLgek))&&o.border){W+=2*parseInt(o.border);H+=2*parseInt(o.border);}
+if(c=='UL'){of=(p=='UR')?[-pW,0]:(p=='LL')?[0,-pH]:(p=='LR')?[-pW,-pH]:[0,0];
+}else if(c=='UR'){of=(p=='UR')?[W-pW,0]:(p=='LL')?[W,-pH]:(p=='LR')?[W-pW,-pH]:[W,0];
+}else if(c=='LL'){of=(p=='UR')?[-pW,H]:(p=='LL')?[0,H-pH]:(p=='LR')?[-pW,H-pH]:[0,H];
+}else if(c=='LR'){of=(p=='UR')?[W-pW,H]:(p=='LL')?[W,H-pH]:(p=='LR')?[W-pW,H-pH]:
+[W,H];}
+return of;
}
// Gets x or y location of object
@@ -494,11 +483,13 @@ return l; // Moves layer
function OLmouseMove(e){
var e=(e||event);
+OLcC=(OLovertwoPI&&over2&&over==over2?cClick2:cClick);
OLx=(e.pageX||e.clientX+OLfd().scrollLeft);OLy=(e.pageY||e.clientY+OLfd().scrollTop);
-if((OLallowmove&&over)&&(o3_frame==self||over==OLgetRefById())){
+if((OLallowmove&&over)&&(o3_frame==self||over==OLgetRefById()
+||(OLovertwoPI&&over2==over&&over==OLgetRefById('overDiv2')))){
OLplaceLayer();if(OLhidePI)OLhideUtil(0,1,1,0,0,0);}
-if(OLhover&&over&&o3_frame==self&&OLcursorOff())if(o3_offdelay<1)cClick();else
-{if(OLtimerid>0)clearTimeout(OLtimerid);OLtimerid=setTimeout("cClick()",o3_offdelay);}
+if(OLhover&&over&&o3_frame==self&&OLcursorOff())if(o3_offdelay<1)OLcC();else
+{if(OLtimerid>0)clearTimeout(OLtimerid);OLtimerid=setTimeout("OLcC()",o3_offdelay);}
}
// Capture mouse and chain other scripts.
@@ -515,12 +506,12 @@ OLdw.onmousemove=mh;if(OLns4)OLdw.captureEvents(Event.MOUSEMOVE); PARSING
*/
function OLparseTokens(pf,ar){
-var i,v,md= -1,par=(pf!='ol_'),e=eval,p=OLpar,q=OLparQuo,t=OLtoggle;OLudf=(par&&!ar.length?1:0);
+var i,v,md= -1,par=(pf!='ol_'),p=OLpar,q=OLparQuo,t=OLtoggle;OLudf=(par&&!ar.length?1:0);
for(i=0;i< ar.length;i++){if(md<0){if(typeof ar[i]=='number'){OLudf=(par?1:0);i--;}
else{switch(pf){case 'ol_':ol_text=ar[i];break;default:o3_text=ar[i];}}md=0;
}else{
-if(ar[i]==INARRAY){OLudf=0;e(pf+'text=ol_texts['+ar[++i]+']');continue;}
-if(ar[i]==CAPARRAY){e(pf+'cap=ol_caps['+ar[++i]+']');continue;}
+if(ar[i]==INARRAY){OLudf=0;eval(pf+'text=ol_texts['+ar[++i]+']');continue;}
+if(ar[i]==CAPARRAY){eval(pf+'cap=ol_caps['+ar[++i]+']');continue;}
if(ar[i]==CAPTION){q(ar[++i],pf+'cap');continue;}
if(Math.abs(ar[i])==STICKY){t(ar[i],pf+'sticky');continue;}
if(Math.abs(ar[i])==NOFOLLOW){t(ar[i],pf+'nofollow');continue;}
@@ -545,9 +536,9 @@ if(ar[i]==BORDER){p(ar[++i],pf+'border');continue;} if(ar[i]==BASE){p(ar[++i],pf+'base');continue;}
if(ar[i]==STATUS){q(ar[++i],pf+'status');continue;}
if(Math.abs(ar[i])==AUTOSTATUS){v=pf+'autostatus';
-e(v+'=('+ar[i]+'<0)?('+v+'==2?2:0):('+v+'==1?0:1)');continue;}
+eval(v+'=('+ar[i]+'<0)?('+v+'==2?2:0):('+v+'==1?0:1)');continue;}
if(Math.abs(ar[i])==AUTOSTATUSCAP){v=pf+'autostatus';
-e(v+'=('+ar[i]+'<0)?('+v+'==1?1:0):('+v+'==2?0:2)');continue;}
+eval(v+'=('+ar[i]+'<0)?('+v+'==1?1:0):('+v+'==2?0:2)');continue;}
if(ar[i]==CLOSETEXT){q(ar[++i],pf+'close');continue;}
if(ar[i]==SNAPX){p(ar[++i],pf+'snapx');continue;}
if(ar[i]==SNAPY){p(ar[++i],pf+'snapy');continue;}
@@ -594,6 +585,7 @@ if(ar[i]==CAPTIONFONTCLASS){q(ar[++i],pf+'captionfontclass');continue;} if(ar[i]==CLOSEFONTCLASS){q(ar[++i],pf+'closefontclass');continue;}
if(Math.abs(ar[i])==CAPBELOW){t(ar[i],pf+'capbelow');continue;}
if(ar[i]==LABEL){q(ar[++i],pf+'label');continue;}
+if(Math.abs(ar[i])==DECODE){t(ar[i],pf+'decode');continue;}
if(ar[i]==DONOTHING){continue;}
i=OLparseCmdLine(pf,i,ar);}}
if((OLfunctionPI)&&OLudf&&o3_function)o3_text=o3_function();
@@ -611,6 +603,14 @@ if(OLhasDims(o3_captionsize)){if(OLns4)o3_captionsize="2";}else if(!OLns4){i=parseInt(o3_captionsize);o3_captionsize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
if(OLhasDims(o3_closesize)){if(OLns4)o3_closesize="2";}else
if(!OLns4){i=parseInt(o3_closesize);o3_closesize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
+if(OLprintPI)OLprintDims();
+}
+function OLdecode(){
+var re=/%[0-9A-Fa-f]{2,}/,t=o3_text,c=o3_cap,u=unescape,d=!OLns4&&(!OLgek||OLgek>=20020826)
+&&typeof decodeURIComponent?decodeURIComponent:u;if(typeof(window.TypeError)=='function'){
+if(re.test(t)){eval(new Array('try{','o3_text=d(t);','}catch(e){','o3_text=u(t);',
+'}').join('\n'))};if(c&&re.test(c)){eval(new Array('try{','o3_cap=d(c);','}catch(e){',
+'o3_cap=u(c);','}').join('\n'))}}else{if(re.test(t))o3_text=u(t);if(c&&re.test(c))o3_cap=u(c);}
}
/*
@@ -625,6 +625,7 @@ if(OLns4){over.document.write(t);over.document.close(); domfrag=range.createContextualFragment(t);
while(over.hasChildNodes()){over.removeChild(over.lastChild);}
over.appendChild(domfrag);}
+if(OLprintPI)over.print=o3_print?t:null;
}
// Makes object visible
@@ -661,10 +662,9 @@ if(!c)o3_close=""; over.onmouseover=function(){OLhover=1;if(OLtimerid>0){clearTimeout(OLtimerid);OLtimerid=0;}}
}
function OLcursorOff(){
-if(OLovertwoPI&&over==over2)return false;
-var o=(OLns4?over:over.style),pHt=OLns4?over.clip.height:over.offsetHeight;
-var left=parseInt(o.left),top=parseInt(o.top);
-var right=left+o3_width,bottom=top+((OLbubblePI&&o3_bubble)?OLbubbleHt:pHt);
+var o=(OLns4?over:over.style),pHt=OLns4?over.clip.height:over.offsetHeight,
+left=parseInt(o.left),top=parseInt(o.top),
+right=left+o3_width,bottom=top+((OLbubblePI&&o3_bubble)?OLbubbleHt:pHt);
if(OLx<left||OLx>right||OLy<top||OLy>bottom)return true;
return false;
}
@@ -672,38 +672,26 @@ return false; /*
REGISTRATION
*/
-var OLcmdLine=null,OLrunTime=null;
function OLsetRunTimeVar(){
-if(OLrunTime&&OLrunTime.length)for(var k=0;k<OLrunTime.length;k++)OLrunTime[k]();
+if(OLrunTime.length)for(var k=0;k<OLrunTime.length;k++)OLrunTime[k]();
}
function OLparseCmdLine(pf,i,ar){
-if(OLcmdLine&&OLcmdLine.length){for(var k=0;k<OLcmdLine.length;k++){
+if(OLcmdLine.length){for(var k=0;k<OLcmdLine.length;k++){
var j=OLcmdLine[k](pf,i,ar);if(j>-1){i=j;break;}}}
return i;
}
-function OLisFunc(f){
-var r=1;
-if(typeof f=='object'){for(var i=0;i<f.length;i++){
-if(typeof f[i]=='function')continue;r=0;break;}
-}else if(typeof f!='function')r=0;
-return r;
-}
function OLregCmds(c){
if(typeof c!='string')return;
var pM=c.split(',');pMtr=pMtr.concat(pM);
for(var i=0;i<pM.length;i++)eval(pM[i].toUpperCase()+'='+pmCnt++);
}
function OLregRunTimeFunc(f){
-if(OLisFunc(f)){
-if(!OLrunTime)OLrunTime=new Array();
if(typeof f=='object')OLrunTime=OLrunTime.concat(f);
-else OLrunTime[OLrunTime.length++]=f;}
+else OLrunTime[OLrunTime.length++]=f;
}
function OLregCmdLineFunc(f){
-if(OLisFunc(f)){
-if(!OLcmdLine)OLcmdLine=new Array();
if(typeof f=='object')OLcmdLine=OLcmdLine.concat(f);
-else OLcmdLine[OLcmdLine.length++]=f;}
+else OLcmdLine[OLcmdLine.length++]=f;
}
OLloaded=1;
diff --git a/httemplate/elements/overlibmws_crossframe.js b/httemplate/elements/overlibmws_crossframe.js new file mode 100644 index 000000000..6b21c42e8 --- /dev/null +++ b/httemplate/elements/overlibmws_crossframe.js @@ -0,0 +1,44 @@ +/*
+ overlibmws_crossframe.js plug-in module - Copyright Foteos Macrides 2003-2006
+ For support of FRAME.
+ Initial: August 3, 2003 - Last Revised: November 2, 2004
+ See the Change History and Command Reference for overlibmws via:
+
+ http://www.macridesweb.com/oltest/
+
+ Published under an open source license: http://www.macridesweb.com/oltest/license.html
+*/
+
+OLloaded=0;
+OLregCmds('frame');
+
+function OLparseCrossframe(pf,i,ar){
+var k=i,v;
+if(k<ar.length){
+if(ar[k]==FRAME){v=ar[++k];if(pf=='ol_')ol_frame=v;else OLoptFRAME(v);return k;}}
+return -1;
+}
+
+function OLgetFrameRef(thisFrame,ofrm){
+var i,v,retVal='';for(i=0;i<thisFrame.length;i++){if((((thisFrame[i].length>0)))&&(((OLns4))||
+((OLie4)&&(v=thisFrame[i].document.all.tags('iframe'))!=null&&v.length==0)||
+((OLns6)&&(v=thisFrame[i].document.getElementsByTagName('iframe'))!=null&&v.length==0))){
+retVal=OLgetFrameRef(thisFrame[i],ofrm);if(retVal=='')continue;}
+else if(thisFrame[i]!=ofrm)continue;retVal='['+i+']'+retVal;break;}
+return retVal;
+}
+
+function OLoptFRAME(frm){
+o3_frame=OLmkLyr('overDiv',frm)?frm:self;if(o3_frame!=self){
+var l,tFrm=OLgetFrameRef(top.frames,o3_frame),sFrm=OLgetFrameRef(top.frames,ol_frame);
+if(sFrm.length==tFrm.length) {l=tFrm.lastIndexOf('[');if(l){
+while(sFrm.substring(0,l)!=tFrm.substring(0,l))l=tFrm.lastIndexOf('[',l-1);
+tFrm=tFrm.substr(l);sFrm=sFrm.substr(l);}}var i,k,cnt=0,p='',str=tFrm;
+while((k=str.lastIndexOf('['))!= -1){cnt++;str=str.substring(0,k);}
+for(i=0;i<cnt;i++)p=p+'parent.';OLfnRef=p+'frames'+sFrm+'.';}
+}
+
+OLregCmdLineFunc(OLparseCrossframe);
+
+OLcrossframePI=1;
+OLloaded=1;
diff --git a/httemplate/elements/overlibmws_draggable.js b/httemplate/elements/overlibmws_draggable.js index 14e4a6062..0d25f842e 100644 --- a/httemplate/elements/overlibmws_draggable.js +++ b/httemplate/elements/overlibmws_draggable.js @@ -1,7 +1,7 @@ /*
overlibmws_draggable.js plug-in module - Copyright Foteos Macrides 2002=2005
For support of the DRAGGABLE feature.
- Initial: August 24, 2002 - Last Revised: January 12, 2005
+ Initial: August 24, 2002 - Last Revised: March 2, 2006
See the Change History and Command Reference for overlibmws via:
http://www.macridesweb.com/oltest/
@@ -37,7 +37,7 @@ function OLsetDrgCur(d){if(!OLns4)over.style.cursor=(d?'move':'auto');} function OLgrabEl(e){
var e=(e||event);
-var cKy=(OLns4?e.modifiers&Event.ALT_MASK:(!OLop7?e.altKey:e.ctrlKey));o3_dragging=1;
+var cKy=(OLns4?e.modifiers&Event.ALT_MASK:(e.altKey||(OLop7&&e.ctrlKey)));o3_dragging=1;
if(cKy){OLsetDrgCur(0);document.onmouseup=function(){OLsetDrgCur(1);o3_dragging=0;}
return(OLns4?routeEvent(e):true);}
OLx=(e.pageX||e.clientX+OLfd().scrollLeft);OLy=(e.pageY||e.clientY+OLfd().scrollTop);
diff --git a/httemplate/elements/pager.html b/httemplate/elements/pager.html index 0510d327d..a53300f53 100644 --- a/httemplate/elements/pager.html +++ b/httemplate/elements/pager.html @@ -1,42 +1,55 @@ -<% - - my %opt = @_; - - my $pager = ''; - if ( $opt{'total'} != $opt{'num_rows'} && $opt{'maxrecords'} ) { - unless ( $opt{'offset'} == 0 ) { - $cgi->param('offset', $opt{'offset'} - $opt{'maxrecords'}); -%> - - <A HREF="<%= $cgi->self_url %>"><B><FONT SIZE="+1">Previous</FONT></B></A> - -<% - } - my $page = 0; - for ( my $poff = 0; $poff < $opt{'total'}; $poff += $opt{'maxrecords'} ) { - $page++; - if ( $opt{'offset'} == $poff ) { -%> - - <FONT SIZE="+2"><%= $page %></FONT> - -<% - } else { - $cgi->param('offset', $poff); -%> - - <A HREF="<%= $cgi->self_url %>"><%= $page %></A> - -<% - } - } - unless ( $opt{'offset'} + $opt{'maxrecords'} > $opt{'total'} ) { - $cgi->param('offset', $opt{'offset'} + $opt{'maxrecords'}); -%> - - <A HREF="<%= $cgi->self_url %>"><B><FONT SIZE="+1">Next</FONT></B></A> - -<% - } - } -%> +% my %opt = @_; +% my $pager = ''; +% +% if ( $opt{'total'} != $opt{'num_rows'} && $opt{'maxrecords'} ) { +% +% unless ( $opt{'offset'} == 0 ) { +% $cgi->param('offset', $opt{'offset'} - $opt{'maxrecords'}); + + <A HREF="<% $cgi->self_url %>"><B><FONT SIZE="+1">Previous</FONT></B></A> + +% } +% +% my $page = 0; +% my $prevpage = 0; +% my $over = 0; +% my $step = $opt{total} / 10; # 10 evenly spaced +% for ( my $poff = 0; $poff < $opt{total}; $poff += $opt{maxrecords} ) { +% $page++; +% +% next unless +% $page <= 4 #first four +% || $page >= ( $opt{total} / $opt{maxrecords} ) - 3 #last four +% || abs( ($opt{offset}-$poff) / $opt{maxrecords} ) <= 3 #w/i 3 of current +% || $poff > $over # evenly spaced +% ; +% +% $over += $step if $poff > $over; +% +% if ( $opt{'offset'} == $poff ) { + + <FONT SIZE="+2"><% $page %></FONT> + +% } else { +% $cgi->param('offset', $poff); +% +% if ( $page > $prevpage+1 ) { + ... +% } + + <A HREF="<% $cgi->self_url %>"><% $page %></A> + +% } +% +% $prevpage = $page; +% +% } +% +% unless ( $opt{'offset'} + $opt{'maxrecords'} > $opt{'total'} ) { +% $cgi->param('offset', $opt{'offset'} + $opt{'maxrecords'}); + + <A HREF="<% $cgi->self_url %>"><B><FONT SIZE="+1">Next</FONT></B></A> +% +% } +% +% } diff --git a/httemplate/elements/phonenumber.html b/httemplate/elements/phonenumber.html new file mode 100644 index 000000000..ffbd8c100 --- /dev/null +++ b/httemplate/elements/phonenumber.html @@ -0,0 +1,22 @@ +% +% my( $number, %opt ) = @_; +% my $conf = new FS::Conf; +% ( my $snumber = $number ) =~ s/\D//g; +% + +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/overlibmws.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/overlibmws_iframe.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/overlibmws_draggable.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/iframecontentmws.js"></SCRIPT> +% if ( length($number) ) { + + <% $number %> +% if ( $opt{'callable'} && $conf->config('vonage-username') ) { + + <A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('https://secure.click2callu.com/tpcc/makecall?username=<% $conf->config('vonage-username') %>&password=<% $conf->config('vonage-password') %>&fromnumber=<% $conf->config('vonage-fromnumber')%>&tonumber=1<% $snumber %>', 240, 64, 'call_popup'), CAPTION, 'Initiating call', STICKY, AUTOSTATUSCAP, CLOSECLICK, DRAGGABLE, WIDTH, 240, HEIGHT, 64 ); return false;" TITLE="Call this number"><IMG SRC="<%$fsurl%>images/red_telephone_mimooh_01.png" BORDER=0 ALT="Call this number"></A> +% } +% } else { + + +% } + diff --git a/httemplate/elements/progress-init.html b/httemplate/elements/progress-init.html index 7844f5678..1c96a54ac 100644 --- a/httemplate/elements/progress-init.html +++ b/httemplate/elements/progress-init.html @@ -1,24 +1,26 @@ -<% - my( $formname, $fields, $action, $url_or_message, $key ) = @_; - $key = '' unless defined $key; +% +% my( $formname, $fields, $action, $url_or_message, $key ) = @_; +% $key = '' unless defined $key; +% +% my $url_or_message_link; +% if ( ref($url_or_message) ) { #its a message or something +% $url_or_message_link = +% 'message='. uri_escape( $url_or_message->{'message'} ) +% } else { +% $url_or_message_link = "url=$url_or_message"; +% } +% - my $url_or_message_link; - if ( ref($url_or_message) ) { #its a message or something - $url_or_message_link = - 'message='. uri_escape( $url_or_message->{'message'} ) - } else { - $url_or_message_link = "url=$url_or_message"; - } -%> -<%= include('/elements/xmlhttp.html', +<% include('/elements/xmlhttp.html', 'method' => 'POST', 'url' => $action, 'subs' => [ 'start_job' ], + 'key' => $key, ) %> -<SCRIPT TYPE="text/javascript" SRC="../elements/overlibmws.js"></SCRIPT> -<SCRIPT TYPE="text/javascript" SRC="../elements/overlibmws_iframe.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/overlibmws.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/overlibmws_iframe.js"></SCRIPT> <SCRIPT TYPE="text/javascript"> function OLiframeContent(src, width, height, name) { return ('<iframe src="'+src+'" width="'+width+'" height="'+height+'"' @@ -26,20 +28,22 @@ function OLiframeContent(src, width, height, name) { +'<div>[iframe not supported]</div></iframe>'); } -function <%=$key%>process () { +function <%$key%>process () { - //alert('<%=$key%>process for form <%=$formname%>'); + //alert('<%$key%>process for form <%$formname%>'); - document.<%=$formname%>.submit.disabled=true; + if ( document.<%$formname%>.submit.disabled == false ) { + document.<%$formname%>.submit.disabled=true; + } - overlib( 'Submitting job to server...', WIDTH, 432, HEIGHT, 136, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 ); + overlib( 'Submitting job to server...', WIDTH, 444, HEIGHT, 168, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 ); var Hash = new Array(); var x = 0; var fieldName; - for (var i = 0; i<document.<%=$formname%>.elements.length; i++) { - field = document.<%=$formname%>.elements[i]; - if ( <%= join(' || ', map { "(field.name.indexOf('$_') > -1)" } @$fields ) %> + for (var i = 0; i<document.<%$formname%>.elements.length; i++) { + field = document.<%$formname%>.elements[i]; + if ( <% join(' || ', map { "(field.name.indexOf('$_') > -1)" } @$fields ) %> ) { if ( field.type == 'select-multiple' ) { @@ -53,7 +57,7 @@ function <%=$key%>process () { } } else if ( ( field.type != 'radio' && field.type != 'checkbox' ) || ( ( field.type == 'radio' || field.type == 'checkbox' ) - && document.<%=$formname%>.elements[i].checked + && document.<%$formname%>.elements[i].checked ) ) { @@ -64,17 +68,17 @@ function <%=$key%>process () { } // jsrsPOST = true; - // jsrsExecute( '<%= $action %>', <%=$key%>myCallback, 'start_job', Hash ); + // jsrsExecute( '<% $action %>', <%$key%>myCallback, 'start_job', Hash ); - //alert('start_job( ' + Hash + ', <%=$key%>myCallback )' ); + //alert('start_job( ' + Hash + ', <%$key%>myCallback )' ); //alert('start_job()' ); - start_job( Hash, <%=$key%>myCallback ); + <%$key%>start_job( Hash, <%$key%>myCallback ); } -function <%=$key%>myCallback( jobnum ) { +function <%$key%>myCallback( jobnum ) { - overlib( OLiframeContent('<%=$p%>elements/progress-popup.html?jobnum=' + jobnum + ';<%=$url_or_message_link%>;formname=<%=$formname%>' , 432, 136, 'progress_popup'), CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 ); + overlib( OLiframeContent('<%$p%>elements/progress-popup.html?jobnum=' + jobnum + ';<%$url_or_message_link%>;formname=<%$formname%>' , 444, 168, 'progress_popup'), CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 ); } diff --git a/httemplate/elements/progress-popup.html b/httemplate/elements/progress-popup.html index 200f97d9b..cda704a12 100644 --- a/httemplate/elements/progress-popup.html +++ b/httemplate/elements/progress-popup.html @@ -1,28 +1,29 @@ -<% - my $jobnum = $cgi->param('jobnum'); - my $url = $cgi->param('url'); - my $message = $cgi->param('message'); - my $formname = scalar($cgi->param('formname')); -%> +% +% my $jobnum = $cgi->param('jobnum'); +% my $url = $cgi->param('url'); +% my $message = $cgi->param('message'); +% my $formname = scalar($cgi->param('formname')); +% + <HTML> <HEAD> <TITLE></TITLE> </HEAD> <BODY BGCOLOR="#ccccff" onLoad="refreshStatus()"> -<%= include('/elements/xmlhttp.html', +<% include('/elements/xmlhttp.html', 'url' => $p.'elements/jsrsServer.html', 'subs' => [ 'job_status' ], ) %> -<SCRIPT TYPE="text/javascript" src="../elements/qlib/control.js"></SCRIPT> -<SCRIPT TYPE="text/javascript" src="../elements/qlib/imagelist.js"></SCRIPT> -<SCRIPT TYPE="text/javascript" src="../elements/qlib/progress.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" src="<%$fsurl%>elements/qlib/control.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" src="<%$fsurl%>elements/qlib/imagelist.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" src="<%$fsurl%>elements/qlib/progress.js"></SCRIPT> <SCRIPT TYPE="text/javascript"> function refreshStatus () { - //jsrsExecute( '<%=$p%>elements/jsrsServer.html', updateStatus, 'job_status', '<%= $jobnum %>' ); + //jsrsExecute( '<%$p%>elements/jsrsServer.html', updateStatus, 'job_status', '<% $jobnum %>' ); - job_status( '<%= $jobnum %>', updateStatus ); + job_status( '<% $jobnum %>', updateStatus ); } function updateStatus( status_statustext ) { @@ -37,26 +38,34 @@ function updateStatus( status_statustext ) { document.getElementById("progress_percent").innerHTML = statustext + '%'; bar1.set(statustext); bar1.update; - //jsrsExecute( '<%=$p%>elements/jsrsServer.html', updateStatus, 'job_status', '<%= $jobnum %>' ); - job_status( '<%= $jobnum %>', updateStatus ); + //jsrsExecute( '<%$p%>elements/jsrsServer.html', updateStatus, 'job_status', '<% $jobnum %>' ); + job_status( '<% $jobnum %>', updateStatus ); } else if ( status.indexOf('complete') > -1 ) { -<% if ( $message ) { %> - document.getElementById("progress_message").innerHTML = "<%= $message %>"; +% if ( $message ) { + + document.getElementById("progress_message").innerHTML = "<% $message %>"; document.getElementById("progress_bar").innerHTML = ''; document.getElementById("progress_percent").innerHTML = '<INPUT TYPE="button" VALUE="OK" onClick="parent.nd(1);">'; document.getElementById("progress_jobnum").innerHTML = ''; - parent.document.<%=$formname%>.submit.disabled=false; -<% } elsif ( $url ) { %> - window.top.location.href = '<%= $url %>'; -<% } else { %> + if ( parent.document.<%$formname%>.submit.disabled == true ) { + parent.document.<%$formname%>.submit.disabled=false; + } +% } elsif ( $url ) { + + window.top.location.href = '<% $url %>'; +% } else { + alert('job done but no url or message specified'); -<% } %> +% } + } else if ( status.indexOf('error') > -1 ) { document.getElementById("progress_message").innerHTML = '<FONT SIZE="+1" COLOR="#FF0000">Error: ' + statustext + '</FONT>'; document.getElementById("progress_bar").innerHTML = ''; document.getElementById("progress_percent").innerHTML = '<INPUT TYPE="button" VALUE="OK" onClick="parent.nd(1);">'; document.getElementById("progress_jobnum").innerHTML = ''; - parent.document.<%=$formname%>.submit.disabled=false; + if ( parent.document.<%$formname%>.submit.disabled == true ) { + parent.document.<%$formname%>.submit.disabled=false; + } } else { alert('XXX unknown status returned from server: ' + status); } @@ -64,7 +73,7 @@ function updateStatus( status_statustext ) { } </SCRIPT> - <TABLE> + <TABLE WIDTH="100%"> <TR> <TD ALIGN="center" ID="progress_message"> Server processing job... @@ -73,7 +82,7 @@ function updateStatus( status_statustext ) { <TD ALIGN="center" ID="progress_bar"> <SCRIPT TYPE="text/javascript"> // Create imagelist - SEGS = new QImageList(4, 23, "../images/progressbar-empty.png", "../images/progressbar-full.png"); + SEGS = new QImageList(4, 23, "<%$fsurl%>images/progressbar-empty.png", "<%$fsurl%>images/progressbar-full.png"); // Create bars bar1 = new QProgress(null, "bar1", SEGS, 100); // bar1.set(0); @@ -86,7 +95,7 @@ function updateStatus( status_statustext ) { </TD> </TR><TR> <TD ALIGN="center" ID="progress_jobnum"> - (progress of job #<%= $jobnum %>) + (progress of job #<% $jobnum %>) </TD> </TR> </TABLE> diff --git a/httemplate/elements/search-cust_main.html b/httemplate/elements/search-cust_main.html new file mode 100644 index 000000000..f2b17eacb --- /dev/null +++ b/httemplate/elements/search-cust_main.html @@ -0,0 +1,164 @@ +% +% my( %opt ) = @_; +% $opt{'field_name'} ||= 'custnum'; +% +% my $cust_main = ''; +% if ( $opt{'value'} ) { +% $cust_main = qsearchs( +% 'table' => 'cust_main', +% 'hashref' => { 'custnum' => $opt{'value'} }, +% 'extra_sql' => " AND ". $FS::CurrentUser::CurrentUser->agentnums_sql, +% ); +% } +% + + +<INPUT TYPE="hidden" NAME="<% $opt{'field_name'} %>" VALUE="<% $opt{'value'} %>"> + +<!-- some false laziness w/ misc/batch-cust_pay.html, though not as bad as i'd thought at first... --> + +<INPUT TYPE="text" NAME="<% $opt{'field_name'} %>_search" ID="<% $opt{'field_name'} %>_search" SIZE="32" VALUE="<% $cust_main ? $cust_main->name : '(cust #, name or company)' %>" onFocus="clearhint_<% $opt{'field_name'} %>_search(this);" onClick="clearhint_<% $opt{'field_name'} %>_search(this);" onChange="smart_<% $opt{'field_name'} %>_search(this);"> + +<SELECT NAME="<% $opt{'field_name'} %>_select" ID="<% $opt{'field_name'} %>_select" STYLE="color:#ff0000; display:none" onChange="select_<% $opt{'field_name'} %>(this);"> +</SELECT> + +<% include('/elements/xmlhttp.html', + 'url' => $p. 'misc/xmlhttp-cust_main-search.cgi', + 'subs' => [ 'smart_search' ], + ) +%> + +<SCRIPT TYPE="text/javascript"> + + function clearhint_<% $opt{'field_name'} %>_search (what) { + + what.style.color = '#000000'; + + if ( what.value == '(cust #, name or company)' ) + what.value = ''; + + if ( what.value.indexOf('Customer not found: ') == 0 ) + what.value = what.value.substr(20); + + } + + function smart_<% $opt{'field_name'} %>_search(what) { + + var customer = what.value; + + if ( customer == 'searching...' || customer == '' + || customer.indexOf('Customer not found: ') == 0 ) + return; + + if ( what.getAttribute('magic') == 'nosearch' ) { + what.setAttribute('magic', ''); + return; + } + + //what.value = 'searching...' + what.disabled = true; + what.style.color= '#000000'; + what.style.backgroundColor = '#dddddd'; + + var customer_select = document.getElementById('<% $opt{'field_name'} %>_select'); + + //alert("search for customer " + customer); + + function <% $opt{'field_name'} %>_search_update(customers) { + + //alert('customers returned: ' + customers); + + var customerArray = eval('(' + customers + ')'); + + what.disabled = false; + what.style.backgroundColor = '#ffffff'; + + if ( customerArray.length == 0 ) { + + what.form.<% $opt{'field_name'} %>.value = ''; + + what.value = 'Customer not found: ' + what.value; + what.style.color = '#ff0000'; + + what.style.display = ''; + customer_select.style.display = 'none'; + + } else if ( customerArray.length == 1 ) { + + //alert('one customer found: ' + customerArray[0]); + + what.form.<% $opt{'field_name'} %>.value = customerArray[0][0]; + what.value = customerArray[0][1]; + + what.style.display = ''; + customer_select.style.display = 'none'; + + } else { + + //alert('multiple customers found, have to create select dropdown'); + + //blank the current list + for ( var i = customer_select.length; i >= 0; i-- ) + customer_select.options[i] = null; + + opt(customer_select, '', 'Multiple customers match "' + customer + '" - select one', '#ff0000'); + + //add the multiple customers + for ( var s = 0; s < customerArray.length; s++ ) + opt(customer_select, customerArray[s][0], customerArray[s][1], '#000000'); + + opt(customer_select, 'cancel', '(Edit search string)', '#000000'); + + what.style.display = 'none'; + customer_select.style.display = ''; + + } + + } + + smart_search( customer, <% $opt{'field_name'} %>_search_update ); + + + } + + function select_<% $opt{'field_name'} %> (what) { + + var custnum = what.options[what.selectedIndex].value; + var customer = what.options[what.selectedIndex].text; + + var customer_obj = document.getElementById('<% $opt{'field_name'} %>_search'); + + if ( custnum == '' ) { + //what.style.color = '#ff0000'; + + } else if ( custnum == 'cancel' ) { + + customer_obj.style.color = '#000000'; + + what.style.display = 'none'; + customer_obj.style.display = ''; + customer_obj.focus(); + + } else { + + what.form.<% $opt{'field_name'} %>.value = custnum; + + customer_obj.value = customer; + customer_obj.style.color = '#000000'; + + what.style.display = 'none'; + customer_obj.style.display = ''; + + } + + } + + function opt(what,value,text,color) { + var optionName = new Option(text, value, false, false); + optionName.style.color = color; + var length = what.length; + what.options[length] = optionName; + } + +</SCRIPT> + diff --git a/httemplate/elements/select-access_group.html b/httemplate/elements/select-access_group.html new file mode 100644 index 000000000..299a66a45 --- /dev/null +++ b/httemplate/elements/select-access_group.html @@ -0,0 +1,16 @@ +% +% my( $groupnum, %opt ) = @_; +% +% %opt{'records'} = delete $opt{'access_group'} +% if $opt{'access_group'}; +% +% +<% include( '/elements/select-table.html', + 'table' => 'access_group', + 'name_col' => 'groupname', + 'value' => $groupnum, + 'empty_label' => '(none)', + #'hashref' => { 'disabled' => '' }, + %opt, + ) +%> diff --git a/httemplate/elements/select-agent.html b/httemplate/elements/select-agent.html index c2a5e4bde..3107ff9d4 100644 --- a/httemplate/elements/select-agent.html +++ b/httemplate/elements/select-agent.html @@ -1,24 +1,19 @@ -<% - my( $agentnum, %opt ) = @_; - - my @agents; - if ( $opt{'agents'} ) { - @agents = @{ $opt{'agents'} }; - } else { - @agents = qsearch( 'agent', { disabled=>'' } ); - } - +% +% my( $agentnum, %opt ) = @_; +% +% $opt{'records'} = delete $opt{'agents'} +% if $opt{'agents'}; +% +% +<% include( '/elements/select-table.html', + 'table' => 'agent', + 'name_col' => 'agent', + 'value' => $agentnum || '', + 'empty_label' => 'all', + 'hashref' => { 'disabled' => '' }, + 'extra_sql' => ' AND '. + $FS::CurrentUser::CurrentUser->agentnums_sql. + ' ORDER BY agent', + %opt, + ) %> - -<SELECT NAME="agentnum"> - - <OPTION VALUE="">all</OPTION> - - <% foreach my $agent ( sort { $a->agent cmp $b->agent } @agents ) { %> - - <OPTION VALUE="<%= $agent->agentnum %>"<%= $agentnum == $agent->agentnum ? ' SELECTED' : '' %>><%= $agent->agent %> - - <% } %> - -</SELECT> - diff --git a/httemplate/elements/select-cust-fields.html b/httemplate/elements/select-cust-fields.html new file mode 100644 index 000000000..98feaf85c --- /dev/null +++ b/httemplate/elements/select-cust-fields.html @@ -0,0 +1,24 @@ +% +% my( $cust_fields, %opt ) = @_; +% +% use FS::ConfDefaults; +% $opt{'avail_fields'} ||= [ FS::ConfDefaults->cust_fields_avail() ]; +% +% tie my %hash, 'Tie::IxHash', @{ $opt{'avail_fields'} }; +% +% + + +<SELECT NAME="cust_fields"> + + <OPTION VALUE="">(configured default) +% +% foreach my $value ( keys %hash ) { + + + <OPTION VALUE="<% $value %>"><% $hash{$value} %> +% } + + +</SELECT> + diff --git a/httemplate/elements/select-cust_pkg-status.html b/httemplate/elements/select-cust_pkg-status.html new file mode 100644 index 000000000..71aaa84b6 --- /dev/null +++ b/httemplate/elements/select-cust_pkg-status.html @@ -0,0 +1,21 @@ +<SELECT NAME="status" <% $opt{'onchange'} %>> + + <OPTION VALUE="">all + +% foreach my $option ( @{ $opt{'statuses'} } ) { + <OPTION VALUE="<% $option %>" <% $option eq $status ? 'SELECTED' : '' %>><% $option %> +% } + +</SELECT> +<%init> + my( $status, %opt ) = @_; + + $opt{'statuses'} ||= [ FS::cust_pkg->statuses() ]; # { disabled=>'' } ) + + if ( exists $opt{'onchange'} && $opt{'onchange'} ) { + $opt{'onchange'} = ' onChange="' . $opt{'onchange'}. '"'; + } else { + $opt{'onchange'} = ''; + } + +</%init> diff --git a/httemplate/elements/select-month_year.html b/httemplate/elements/select-month_year.html index a0ea74ddd..34476bc94 100644 --- a/httemplate/elements/select-month_year.html +++ b/httemplate/elements/select-month_year.html @@ -1,50 +1,62 @@ -<% +% +% +% my %opt = @_; +% +% my $prefix = $opt{'prefix'} || ''; +% my $disabled = $opt{'disabled'} || ''; +% my $empty = $opt{'empty_option'} || ''; +% my $start_year = $opt{'start_year'}; +% my $end_year = $opt{'end_year'} || '2037'; +% +% my @mon; +% if ( $opt{'show_month_abbr'} ) { +% @mon = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); +% } else { +% @mon = ( 1 .. 12 ); +% } +% +% my $date = $opt{'selected_date'} || ''; +% $date = '' if $date eq '-'; +% #$date ||= '01-2000' unless $empty; +% +% my $mon = $opt{'selected_mon'} || 0; +% my $year = $opt{'selected_year'} || 0; +% if ( $date ) { +% if ( $date =~ /^(\d{4})-(\d{1,2})-\d{1,2}$/ ) { #PostgreSQL date format +% ( $mon, $year ) = ( $2, $1 ); +% } elsif ( $date =~ /^(\d{1,2})-(\d{1,2}-)?(\d{4}$)/ ) { +% ( $mon, $year ) = ( $1, $3 ); +% } else { +% die "unrecognized expiration date format: $date"; +% } +% } +% +% unless ( $start_year ) { +% my @t = localtime; +% $start_year = $t[5] + 1900; +% } +% $start_year = $year if $start_year > $year && $year > 0; +% +% + + +<SELECT NAME="<% $prefix %>_month" SIZE="1" <% $disabled%>> + +<% $empty ? '<OPTION VALUE="">' : '' %> +% foreach ( 1 .. 12 ) { + + <OPTION<% $_ == $mon ? ' SELECTED' : '' %> VALUE="<% $_ %>"><% $mon[$_-1] %> +% } + + +</SELECT>/<SELECT NAME="<% $prefix %>_year" SIZE="1" <% $disabled%>> + +<% $empty ? '<OPTION VALUE="">' : '' %> +% for ( $start_year .. $end_year ) { + + <OPTION<% $_ == $year ? ' SELECTED' : '' %> VALUE="<% $_ %>"><% $_ %> +% } - my %opt = @_; - - my $prefix = $opt{'prefix'} || ''; - my $disabled = $opt{'disabled'} || ''; - my $empty = $opt{'empty_option'} || ''; - my $date = $opt{'selected_date'} || ''; - $date = '' if $date eq '-'; - #$date ||= '01-2000' unless $empty; - my $start_year = $opt{'start_year'}; - my $end_year = $opt{'end_year'} || '2037'; - - my( $mon, $year ) = (0, 0); - if ( $date ) { - if ( $date =~ /^(\d{4})-(\d{1,2})-\d{1,2}$/ ) { #PostgreSQL date format - ( $mon, $year ) = ( $2, $1 ); - } elsif ( $date =~ /^(\d{1,2})-(\d{1,2}-)?(\d{4}$)/ ) { - ( $mon, $year ) = ( $1, $3 ); - } else { - die "unrecognized expiration date format: $date"; - } - } - - unless ( $start_year ) { - my @t = localtime; - $start_year = $t[5] + 1900; - } - $start_year = $year if $start_year > $year && $year > 0; - -%> - -<SELECT NAME="<%= $prefix %>_month" SIZE="1" <%= $disabled%>> - -<%= $empty ? '<OPTION VALUE="">' : '' %> - -<% for ( 1 .. 12 ) { %> - <OPTION<%= $_ == $mon ? ' SELECTED' : '' %> VALUE="<%= $_ %>"><%= $_ %> -<% } %> - -</SELECT>/<SELECT NAME="<%= $prefix %>_year" SIZE="1" <%= $disabled%>> - -<%= $empty ? '<OPTION VALUE="">' : '' %> - -<% for ( $start_year .. $end_year ) { %> - <OPTION<%= $_ == $year ? ' SELECTED' : '' %> VALUE="<%= $_ %>"><%= $_ %> -<% } %> </SELECT> diff --git a/httemplate/elements/select-part_referral.html b/httemplate/elements/select-part_referral.html new file mode 100644 index 000000000..670b70c7c --- /dev/null +++ b/httemplate/elements/select-part_referral.html @@ -0,0 +1,18 @@ +% +% my( $refnum, %opt ) = @_; +% +% $opt{'records'} = delete $opt{'part_referrals'} +% if $opt{'part_referrals'}; +% +% +<% include( '/elements/select-table.html', + 'table' => 'part_referral', + 'name_col' => 'referral', + 'value' => $refnum, + 'empty_label' => 'Select advertising source', + 'hashref' => { 'disabled' => '' }, + 'extra_sql' => ' AND '. + FS::part_referral->acl_agentnum_sql(1), + %opt, + ) +%> diff --git a/httemplate/elements/select-pkg_class.html b/httemplate/elements/select-pkg_class.html new file mode 100644 index 000000000..8e873ed66 --- /dev/null +++ b/httemplate/elements/select-pkg_class.html @@ -0,0 +1,16 @@ +% my( $classnum, %opt ) = @_; +% +% $opt{'records'} = delete $opt{'pkg_class'} +% if $opt{'pkg_class'}; +% +% #warn "***** select-pkg-class: \n". Dumper(%opt); +% +<% include( '/elements/select-table.html', + 'table' => 'pkg_class', + 'name_col' => 'classname', + 'value' => $classnum, + 'empty_label' => '(none)', + 'hashref' => { 'disabled' => '' }, + %opt, + ) +%> diff --git a/httemplate/elements/select-table.html b/httemplate/elements/select-table.html new file mode 100644 index 000000000..3235ef627 --- /dev/null +++ b/httemplate/elements/select-table.html @@ -0,0 +1,85 @@ +<SELECT NAME="<% $opt{'element_name'} || $key %>" <% $opt{'element_etc'} %>> + +% while ( @pre_options ) { + + <OPTION VALUE="<% shift(@pre_options) %>"><% shift(@pre_options) %> + +% } + + <OPTION VALUE=""><% $opt{'empty_label'} || 'all' %> + +% foreach my $record ( sort { $a->$name_col() cmp $b->$name_col() } @records ) { +% my $matches = 0; +% ref($opt{'value'}) ? (exists($opt{'value'}->{$record->$key()}) and $matches=1) +% : ($opt{'value'} == $record->$key() and $matches=1); + + <OPTION VALUE="<% $record->$key() %>"<% $matches ? ' SELECTED' : '' %>><% $record->$name_col() %> + +% } + +</SELECT> +<%init> + +##required +# 'table' => 'table_name', +# 'name_col' => 'name_column', +# +##strongly recommended (you want your forms to be "sticky" on errors, right?) +# 'value' => 'current_value', +# +##opt +# 'empty_label' => '', #better specify it though, the default might change +# 'hashref' => {}, +# 'extra_sql' => '', +# 'records' => \@records, #instead of hashref +# 'pre_options' => [ 'value' => 'option' ], #before normal options +# 'element_name' => '', #HTML element name, defaults to the name of +# # the primary key column +# 'element_etc' => '', #additional attributes (i.e. "DISABLED") for the +# #<SELECT> element +# 'debug' => 0, #set true to enable + +my( %opt ) = @_; + +warn "elements/select-table.html: \n". Dumper(%opt) + if exists $opt{debug} && $opt{debug}; + +my $key = dbdef->table($opt{table})->primary_key; #? $opt{primary_key} || + +my $name_col = $opt{name_col}; + +$opt{hashref} ||= {}; + +my @records = (); +if ( $opt{records} ) { + @records = @{ $opt{records} }; +} else { + @records = qsearch( { + 'table' => $opt{table}, + 'hashref' => $opt{hashref}, + 'extra_sql' => ( $opt{extra_sql} || '' ), + }); +} + +unless ( ! $opt{value} + or ref($opt{value}) + or ! exists( $opt{hashref}->{disabled} ) #?? + or grep { $opt{value} == $_->$key() } @records + ) { + delete $opt{hashref}->{disabled}; + $opt{hashref}->{$key} = $opt{value}; + my $record = qsearchs( { + 'table' => $opt{table}, + 'hashref' => $opt{hashref}, + 'extra_sql' => ( $opt{extra_sql} || '' ), + }); + push @records, $record if $record; +} + +if ( ref( $opt{value} ) eq 'ARRAY' ) { + $opt{value} = { map { $_ => 1 } @{$opt{value}} }; +} + +my @pre_options = $opt{pre_options} ? @{ $opt{pre_options} } : (); + +</%init> diff --git a/httemplate/elements/select-taxclass.html b/httemplate/elements/select-taxclass.html index e5a1abba1..3c1558b72 100644 --- a/httemplate/elements/select-taxclass.html +++ b/httemplate/elements/select-taxclass.html @@ -1,42 +1,38 @@ -<% - my $conf = new FS::Conf; - my $selected_taxclass = scalar(@_) ? shift : ''; -%> - -<% if ( $conf->exists('enable_taxclasses') ) { %> +% if ( $conf->exists('enable_taxclasses') ) { <SELECT NAME="taxclass"> - <% if ( $conf->exists('require_taxclasses') ) { %> - +% if ( $conf->exists('require_taxclasses') ) { <OPTION VALUE="(select)">Select tax class - - <% } else { %> - +% } else { <OPTION VALUE=""> +% } - <% } %> - - <% - my $sth = dbh->prepare('SELECT DISTINCT taxclass FROM cust_main_county') - or die dbh->errstr; - $sth->execute or die $sth->errstr; - my %taxclasses = map { $_->[0] => 1 } @{$sth->fetchall_arrayref}; - my @taxclasses = grep $_, keys %taxclasses; - %> - - <% foreach my $taxclass ( @taxclasses ) { %> - - <OPTION VALUE="<%= $taxclass %>"<%= $taxclass eq $selected_taxclass ? ' SELECTED' : '' %>><%= $taxclass %> - - <% } %> +% foreach my $taxclass ( @{ $opt{'taxclasses'} } ) { + <OPTION VALUE="<% $taxclass %>"<% $taxclass eq $selected_taxclass ? ' SELECTED' : '' %>><% $taxclass %> +% } </SELECT> -<% } else { %> +% } else { + + <INPUT TYPE="hidden" NAME="taxclass" VALUE="<% $selected_taxclass %>"> + +% } + +<%init> + +my( $selected_taxclass, %opt ) = @_; +my $conf = new FS::Conf; + +unless ( $opt{'taxclasses'} ) { + + my $sth = dbh->prepare('SELECT DISTINCT taxclass FROM cust_main_county') + or die dbh->errstr; + $sth->execute or die $sth->errstr; + my %taxclasses = map { $_->[0] => 1 } @{$sth->fetchall_arrayref}; + @{ $opt{'taxclasses'} } = grep $_, keys %taxclasses; - <INPUT TYPE="hidden" NAME="taxclass" VALUE="<%= $selected_taxclass %>"> - -<% } %> - +} +</%init> diff --git a/httemplate/elements/small_custview.html b/httemplate/elements/small_custview.html index e0c22e0c4..9060d897d 100644 --- a/httemplate/elements/small_custview.html +++ b/httemplate/elements/small_custview.html @@ -1,2 +1,3 @@ -<% my $conf = new FS::Conf; %> -<%= small_custview( shift, shift || scalar($conf->config('countrydefault')), @_ ) %> +% my $conf = new FS::Conf; + +<% small_custview( shift, shift || scalar($conf->config('countrydefault')), @_ ) %> diff --git a/httemplate/elements/table-grid.html b/httemplate/elements/table-grid.html index 80611f511..0f532e86b 100644 --- a/httemplate/elements/table-grid.html +++ b/httemplate/elements/table-grid.html @@ -1,8 +1,21 @@ +% +% my %opt = @_; +% $opt{cellspacing} ||= 0; +% $opt{cellpadding} ||= 0; +% +% + <STYLE TYPE="text/css"> + .grid table { border: solid; empty-cells: show } .grid TH { padding-left: 3px; padding-right: 3px; border: 1px solid #dddddd; border-bottom: dashed 1px black; border-right: none } .grid TD { padding-left: 3px; padding-right: 3px; empty-cells: show; border: 1px solid #cccccc; border-bottom: none; border-right: none } + +.inv table { border: none } +.inv TH { border: none } +.inv TD { border: none } + </STYLE> -<TABLE CLASS="grid" CELLSPACING=0 CELLPADDING=0 BORDER=1 BORDERCOLOR="#000000" STYLE="border: solid 1px black; empty-cells: show"> +<TABLE CLASS="grid" CELLSPACING=<% $opt{cellspacing} %> CELLPADDING=<% $opt{cellpadding} %> BORDER=1 BORDERCOLOR="#000000" STYLE="border: solid 1px black; empty-cells: show"> diff --git a/httemplate/elements/table.html b/httemplate/elements/table.html index 3b6108719..8152b65d8 100644 --- a/httemplate/elements/table.html +++ b/httemplate/elements/table.html @@ -1,8 +1,11 @@ -<% - my $color = shift; - if ( $color ) { -%> - <TABLE BGCOLOR="<%= $color %>" BORDER=1 WIDTH="100%" CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999"> -<% } else { %> +% +% my $color = shift; +% if ( $color ) { +% + + <TABLE BGCOLOR="<% $color %>" BORDER=1 WIDTH="100%" CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999"> +% } else { + <TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999"> -<% } %> +% } + diff --git a/httemplate/elements/tr-input-beginning_ending.html b/httemplate/elements/tr-input-beginning_ending.html index 9fa936bca..9c067dbea 100644 --- a/httemplate/elements/tr-input-beginning_ending.html +++ b/httemplate/elements/tr-input-beginning_ending.html @@ -1,39 +1,63 @@ -<LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2"> -<SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT> -<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> -<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> - +<LINK REL="stylesheet" TYPE="text/css" HREF="<%$fsurl%>elements/calendar-win2k-2.css" TITLE="win2k-2"> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/calendar_stripped.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/calendar-en.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/calendar-setup.js"></SCRIPT> <TR> - <TD ALIGN="right">From: </TD> - <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> + <TD ALIGN="right">From date: </TD> + <TD><INPUT TYPE="text" NAME="<% $opt{prefix} %>beginning" ID="<% $opt{prefix} %>beginning_text" VALUE="" SIZE=<%$size%> MAXLENGTH=<%$maxlength%>> <IMG SRC="<%$fsurl%>images/calendar.png" ID="<% $opt{prefix} %>beginning_button" STYLE="cursor: pointer" TITLE="Select date"><IMG SRC="<%$fsurl%>images/calendar-disabled.png" ID="<% $opt{prefix} %>beginning_disabled" STYLE="display:none"><BR><i>m/d/y<% $time_hint %></i></TD> <SCRIPT TYPE="text/javascript"> Calendar.setup({ - inputField: "beginning_text", - ifFormat: "%m/%d/%Y", - button: "beginning_button", + inputField: "<% $opt{prefix} %>beginning_text", + ifFormat: "%m/%d/%Y<% $time_format %>", + button: "<% $opt{prefix} %>beginning_button", align: "BR" + <% $input_time %> }); </SCRIPT> -</TR> +% unless ( $opt{layout} =~ /^h/i ) { #horizontal + +</TR> <TR> - <TD ALIGN="right">To: </TD> - <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> + +% } + + <TD ALIGN="right">To date: </TD> + <TD><INPUT TYPE="text" NAME="<% $opt{prefix} %>ending" ID="<% $opt{prefix} %>ending_text" VALUE="" SIZE=<%$size%> MAXLENGTH=<%$maxlength%>> <IMG SRC="<%$fsurl%>images/calendar.png" ID="<% $opt{prefix} %>ending_button" STYLE="cursor: pointer" TITLE="Select date"><IMG SRC="<%$fsurl%>images/calendar-disabled.png" ID="<% $opt{prefix} %>ending_disabled" STYLE="display:none"><BR><i>m/d/y<% $time_hint %></i></TD> <SCRIPT TYPE="text/javascript"> Calendar.setup({ - inputField: "ending_text", - ifFormat: "%m/%d/%Y", - button: "ending_button", + inputField: "<% $opt{prefix} %>ending_text", + ifFormat: "%m/%d/%Y<% $time_format %>", + button: "<% $opt{prefix} %>ending_button", align: "BR" + <% $input_time %> }); </SCRIPT> </TR> <TR> <TD></TD> - <TD> + <TD COLSPAN=<% $opt{layout} =~ /^h/i ? 3 : 1 %>> <FONT SIZE="-1">(leave one or both dates blank for an open-ended search)</FONT> </TD> </TR> +<%init> + +my %opt = @_; + +$opt{prefix} = '' unless defined $opt{prefix}; +$opt{prefix} .= '_' if $opt{prefix}; + +my( $input_time, $time_format, $time_hint ) = ( '', '', '' ); +my( $size, $maxlength ) = ( 11, 10 ); +if ( $opt{'input_time'} ) { + $input_time = ', showsTime: true, timeFormat: "12"'; # http://www.dynarch.com/demos/jscalendar/doc/html/reference.html#node_sec_2.3 + $time_format = ' %k:%M:%S'; # http://www.dynarch.com/demos/jscalendar/doc/html/reference.html#node_sec_5.3.5 + $time_hint = ' h:m:s'; + $size = 21; + $maxlength = 27; +} + +</%init> diff --git a/httemplate/elements/tr-input-date-field.html b/httemplate/elements/tr-input-date-field.html new file mode 100644 index 000000000..11581d5bc --- /dev/null +++ b/httemplate/elements/tr-input-date-field.html @@ -0,0 +1,40 @@ + +<LINK REL="stylesheet" TYPE="text/css" HREF="<%$fsurl%>elements/calendar-win2k-2.css" TITLE="win2k-2"> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/calendar_stripped.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/calendar-en.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/calendar-setup.js"></SCRIPT> + +<TR> + <TD ALIGN="right"><% $label %></TD> + <TD> + <INPUT TYPE="text" NAME="<% $name %>" ID="<% $name %>_text" VALUE="<% $value %>"> + <IMG SRC="<%$fsurl%>images/calendar.png" ID="<% $name %>_button" STYLE="cursor: pointer" TITLE="Select date"> + </TD> +</TR> + +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "<% $name %>_text", + ifFormat: "<% $format %>", + button: "<% $name %>_button", + align: "BR" + }); +</SCRIPT> + + +<%init> +my($name, $value, $label, $format, $usedatetime) = @_; + +$format = "%m/%d/%Y" unless $format; +$label = $name unless $label; + +if ($usedatetime) { + my $dt = DateTime->from_epoch(epoch => $value, time_zone => 'floating'); + $value = $dt->strftime($format) + unless $value eq ''; +}else{ + $value = time2str($format, $value); +} + +</%init> + diff --git a/httemplate/elements/tr-input-lessthan_greaterthan.html b/httemplate/elements/tr-input-lessthan_greaterthan.html new file mode 100644 index 000000000..16c2ed9fc --- /dev/null +++ b/httemplate/elements/tr-input-lessthan_greaterthan.html @@ -0,0 +1,13 @@ +<TR> + <TD ALIGN="right"><% $opt{label} %> less than: </TD> + <TD><INPUT TYPE="text" NAME="<% $opt{field} %>_lt" SIZE=7></TD> +</TR> + +<TR> + <TD ALIGN="right"><% $opt{label} %> greater than: </TD> + <TD><INPUT TYPE="text" NAME="<% $opt{field} %>_gt" SIZE=7></TD> +</TR> + +<%init> + my %opt = @_; +</%init> diff --git a/httemplate/elements/tr-select-access_group.html b/httemplate/elements/tr-select-access_group.html new file mode 100644 index 000000000..e443ad26a --- /dev/null +++ b/httemplate/elements/tr-select-access_group.html @@ -0,0 +1,22 @@ +% +% my( $groupnum, %opt ) = @_; +% +% $opt{'access_group'} ||= [ qsearch( 'access_group', {} ) ]; # { disabled=>'' } ) +% +% #warn "***** tr-select-access_group: \n". Dumper(%opt); +% +% if ( scalar(@{ $opt{'access_group'} }) == 0 ) { + + + <INPUT TYPE="hidden" NAME="groupnum" VALUE=""> +% } else { + + + <TR> + <TD ALIGN="right"><% $opt{'label'} || 'Access group' %></TD> + <TD> + <% include( '/elements/select-access_group.html', $groupnum, %opt ) %> + </TD> + </TR> +% } + diff --git a/httemplate/elements/tr-select-agent.html b/httemplate/elements/tr-select-agent.html index 2227262b6..37b1c1e88 100644 --- a/httemplate/elements/tr-select-agent.html +++ b/httemplate/elements/tr-select-agent.html @@ -1,29 +1,34 @@ -<% - my( $agentnum, %opt ) = @_; +% +% my( $agentnum, %opt ) = @_; +% +% my @agents; +% if ( $opt{'agents'} ) { +% #@agents = @{ $opt{'agents'} }; +% #here is the agent virtualization +% my $agentnums_href = $FS::CurrentUser::CurrentUser->agentnums_href; +% @agents = grep $agentnums_href->{$_->agentnum}, @{ $opt{'agents'} }; +% delete $opt{'agents'}; +% } else { +% @agents = $FS::CurrentUser::CurrentUser->agents; +% } +% +% +% if ( scalar(@agents) == 1 ) { - my @agents; - if ( $opt{'agents'} ) { - @agents = @{ $opt{'agents'} }; - } else { - @agents = qsearch( 'agent', { disabled=>'' } ); - } -%> + <INPUT TYPE="hidden" NAME="agentnum" VALUE="<% $agents[0]->agentnum %>"> +% } else { -<% if ( scalar(@agents) == 1 ) { %> - - <INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agents[0]->agentnum %>"> - -<% } else { %> <TR> - <TD ALIGN="right"><%= $opt{'label'} || 'Agent: ' %></TD> + <TD ALIGN="right"><% $opt{'label'} || 'Agent' %></TD> <TD> - <%= include( '/elements/select-agent.html', $agentnum, + <% include( '/elements/select-agent.html', $agentnum, 'agents' => \@agents, + %opt, ) %> </TD> </TR> +% } -<% } %> diff --git a/httemplate/elements/tr-select-cust-fields.html b/httemplate/elements/tr-select-cust-fields.html new file mode 100644 index 000000000..80562fe3d --- /dev/null +++ b/httemplate/elements/tr-select-cust-fields.html @@ -0,0 +1,15 @@ +% +% my( $cust_fields, %opt ) = @_; +% +% use FS::ConfDefaults; +% $opt{'avail_fields'} ||= [ FS::ConfDefaults->cust_fields_avail() ]; +% +% + + +<TR> + <TD ALIGN="right"><% $opt{'label'} || 'Customer fields' %></TD> + <TD> + <% include( '/elements/select-cust-fields.html', $cust_fields, %opt ) %> + </TD> +</TR> diff --git a/httemplate/elements/tr-select-cust_pkg-status.html b/httemplate/elements/tr-select-cust_pkg-status.html new file mode 100644 index 000000000..22ee146cd --- /dev/null +++ b/httemplate/elements/tr-select-cust_pkg-status.html @@ -0,0 +1,14 @@ +% +% my( $status, %opt ) = @_; +% +% $opt{'statuses'} ||= [ FS::cust_pkg->statuses() ]; # { disabled=>'' } ) +% +% + + +<TR> + <TD ALIGN="right"><% $opt{'label'} || 'Status' %></TD> + <TD> + <% include( '/elements/select-cust_pkg-status.html', $status, %opt ) %> + </TD> +</TR> diff --git a/httemplate/elements/tr-select-from_to.html b/httemplate/elements/tr-select-from_to.html new file mode 100644 index 000000000..083243d40 --- /dev/null +++ b/httemplate/elements/tr-select-from_to.html @@ -0,0 +1,52 @@ +% +% +% #my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +% my ($curmon,$curyear) = (localtime(time))[4,5]; +% +% #find first month +% my $syear = 1899+$curyear; +% my $smonth = $curmon+1; +% +% #want 12 month by default, not 13 +% $smonth++; +% if ( $smonth > 12 ) { $smonth-=12; $syear++ } +% +% #find last month +% my $eyear = 1900+$curyear; +% my $emonth = $curmon+1; +% +% my %hash = ( +% 'show_month_abbr' => 1, +% 'start_year' => '1999', +% 'end_year' => '2012', #haha, well... +% @_, +% ); +% +% + + +<TR> + <TD ALIGN="right">From: </TD> + <TD> + <% include('/elements/select-month_year.html', + 'prefix' => 'start', + 'selected_mon' => $smonth, + 'selected_year' => $syear, + %hash, + ) + %> + </TD> +</TR> + +<TR> + <TD ALIGN="right">To: </TD> + <TD> + <% include('/elements/select-month_year.html', + 'prefix' => 'end', + 'selected_mon' => $emonth, + 'selected_year' => $eyear, + %hash, + ) + %> + </TD> +</TR> diff --git a/httemplate/elements/tr-select-part_referral.html b/httemplate/elements/tr-select-part_referral.html new file mode 100644 index 000000000..35c5b8047 --- /dev/null +++ b/httemplate/elements/tr-select-part_referral.html @@ -0,0 +1,30 @@ +% +% my( $refnum, %opt ) = @_; +% +% $opt{'part_referrals'} ||= +% [ FS::part_referral->all_part_referral( 1 ) ]; #1: include global +% +% my $r = qq!<font color="#ff0000">*</font> !; +% +% +% if ( scalar( @{$opt{'part_referrals'}} ) == 0 ) { +% eidiot "You have not created any advertising sources. You must create at least one advertising source before adding a customer. Go to ". popurl(2). "browse/part_referral.html and create one or more advertising sources."; +% } elsif ( scalar( @{$opt{'part_referrals'}} ) == 1 ) { +% + + + <INPUT TYPE="hidden" NAME="refnum" VALUE="<% $opt{'part_referrals'}->[0]->refnum %>"> +% } else { + + + <TR> + <TH ALIGN="right"><%$r%>Advertising source</TH> + <TD> + <% include( '/elements/select-part_referral.html', $refnum, + 'part_referrals' => $opt{'part_referrals'}, + ) + %> + </TD> + </TR> +% } + diff --git a/httemplate/elements/tr-select-pkg_class.html b/httemplate/elements/tr-select-pkg_class.html new file mode 100644 index 000000000..542142466 --- /dev/null +++ b/httemplate/elements/tr-select-pkg_class.html @@ -0,0 +1,20 @@ +% my( $classnum, %opt ) = @_; +% +% $opt{'pkg_class'} ||= [ qsearch( 'pkg_class', { disabled=>'' } ) ]; +% +% #warn "***** tr-select-pkg-class: \n". Dumper(%opt); +% +% if ( scalar(@{ $opt{'pkg_class'} }) == 0 ) { + + <INPUT TYPE="hidden" NAME="classnum" VALUE=""> + +% } else { + + <TR> + <TD ALIGN="right"><% $opt{'label'} || 'Package class' %></TD> + <TD> + <% include( '/elements/select-pkg_class.html', $classnum, %opt ) %> + </TD> + </TR> + +% } diff --git a/httemplate/elements/tr-select-reason.html b/httemplate/elements/tr-select-reason.html new file mode 100755 index 000000000..2f8f3a109 --- /dev/null +++ b/httemplate/elements/tr-select-reason.html @@ -0,0 +1,101 @@ + +<SCRIPT TYPE="text/javascript"> + function sh_add<% $name %>() + { + + if (document.getElementById('<% $name %>').selectedIndex == 0){ + <% $controlledbutton ? $controlledbutton.'.disabled = true;' : ';' %> + }else{ + <% $controlledbutton ? $controlledbutton.'.disabled = false;' : ';' %> + } + +%if ($curuser->access_right($access_right)){ + + if (document.getElementById('<% $name %>').selectedIndex == + (document.getElementById('<% $name %>').length - 1)) { + document.getElementById('new<% $name %>').disabled = false; + document.getElementById('new<% $name %>').style.display = 'inline'; + document.getElementById('new<% $name %>Label').style.display = 'inline'; + document.getElementById('new<% $name %>T').disabled = false; + document.getElementById('new<% $name %>T').style.display = 'inline'; + document.getElementById('new<% $name %>TLabel').style.display = 'inline'; + }else{ + document.getElementById('new<% $name %>').disabled = true; + document.getElementById('new<% $name %>').style.display = 'none'; + document.getElementById('new<% $name %>Label').style.display = 'none'; + document.getElementById('new<% $name %>T').disabled = true; + document.getElementById('new<% $name %>T').style.display = 'none'; + document.getElementById('new<% $name %>TLabel').style.display = 'none'; + } + +%} + + } +</SCRIPT> + +<TR> + <TD ALIGN="right">Reason</TD> + <TD> + <SELECT id="<% $name %>" name="<% $name %>" onFocus="sh_add<% $name %>()" onChange="sh_add<% $name %>()"> +% my @reasons = qsearch( { table =>'reason', +% hashref => {}, +% extra_sql => $extra_sql, +% addl_from => 'LEFT JOIN reason_type ON reason_type.typenum = reason.reason_type', +% }); + <OPTION VALUE="" <% ($init_reason eq "") ? 'SELECTED' : '' %>>Select Reason...</OPTION> +% foreach my $reason (@reasons) { + <OPTION VALUE="<% $reason->reasonnum %>" <% ($init_reason == $reason->reasonnum) ? 'SELECTED' : '' %>><% $reason->reason %></OPTION> +% } +% if ($curuser->access_right($access_right)) { + <OPTION VALUE="-1" <% ($init_reason == -1) ? 'SELECTED' : '' %>>Add new reason</OPTION> +% } +% + </SELECT> + </TD> +</TR> + +<TR> + <TD ALIGN="right"> + <P id="new<% $name %>TLabel" style="display:<% $display %>">Reason Type</P> + </TD> + <TD> + <SELECT id="new<% $name %>T" name="new<% $name %>T" disabled="<% $disabled %>" style="display:<% $display %>"> +% for my $type (qsearch( 'reason_type', { 'class' => $class } )){ + <OPTION VALUE="<% $type->typenum %>" <% ($init_type == $type->typenum) ? 'SELECTED' : '' %>><% $type->type %></OPTION> +% } + </SELECT> + </TD> +</TR> + +<TR> + <TD ALIGN="right"> + <P id="new<% $name %>Label" style="display:<% $display %>">New Reason</P> + </TD> + <TD><INPUT id="new<% $name %>" name="new<% $name %>" type="text" value="<% $init_newreason %>" disabled="<% $disabled %>" style="display:<% $display %>"></TD> +</TR> + +<%init> +my($name, $class, $init_reason, $init_type, $init_newreason, $controlledbutton) = @_; +my($extra_sql, $curuser, $access_right, $display, $disabled); + +if ($class eq 'C') { + $access_right='Add on-the-fly cancel reason'; +}elsif ($class eq 'S') { + $access_right='Add on-the-fly suspend reason'; +}else{ + print "illegal class: $class"; +} + +if ($init_reason == -1){ + $display = 'inline'; + $disabled = 'false'; +}else{ + $display = 'none'; + $disabled = 'true'; +} + +$extra_sql = "WHERE class = '$class' ORDER BY reason_type"; +$curuser = $FS::CurrentUser::CurrentUser; + +</%init> + diff --git a/httemplate/elements/tr-select-taxclass.html b/httemplate/elements/tr-select-taxclass.html new file mode 100644 index 000000000..424d5ad02 --- /dev/null +++ b/httemplate/elements/tr-select-taxclass.html @@ -0,0 +1,32 @@ +% if ( ! $conf->exists('enable_taxclasses') +% || scalar(@{ $opt{'taxclasses'} }) == 0 +% ) { + + <INPUT TYPE="hidden" NAME="taxclass" VALUE="<% $taxclass %>"> + +% } else { + + <TR> + <TD ALIGN="right"><% $opt{'label'} || 'Tax class: ' %></TD> + <TD> + <% include( '/elements/select-taxclass.html', $taxclass, %opt ) %> + </TD> + </TR> + +% } +<%init> + +my( $taxclass, %opt ) = @_; +my $conf = new FS::Conf; + +unless ( $opt{'taxclasses'} ) { + + my $sth = dbh->prepare('SELECT DISTINCT taxclass FROM cust_main_county') + or die dbh->errstr; + $sth->execute or die $sth->errstr; + my %taxclasses = map { $_->[0] => 1 } @{$sth->fetchall_arrayref}; + @{ $opt{'taxclasses'} } = grep $_, keys %taxclasses; + +} + +</%init> diff --git a/httemplate/elements/tr-selectmultiple-part_pkg.html b/httemplate/elements/tr-selectmultiple-part_pkg.html new file mode 100644 index 000000000..bd96d1c3a --- /dev/null +++ b/httemplate/elements/tr-selectmultiple-part_pkg.html @@ -0,0 +1,19 @@ +% +% my( %opt ) = @_; +% + + +<TR> + <TD ALIGN="right"><% $opt{'label'} || 'Packages' %></TD> + <TD> + <% include( '/elements/select-table.html', + 'table' => 'part_pkg', + 'name_col' => 'pkg', + 'value' => '', + 'empty_label' => '(none)', + 'element_etc' => 'multiple', + %opt, + ) + %> + </TD> +</TR> diff --git a/httemplate/elements/xmenu.css b/httemplate/elements/xmenu.css new file mode 100644 index 000000000..97c7da8bb --- /dev/null +++ b/httemplate/elements/xmenu.css @@ -0,0 +1,196 @@ + +.webfx-menu, .webfx-menu * { + /* + Set the box sizing to content box + in the future when IE6 supports box-sizing + there will be an issue to fix the sizes + + There is probably an issue with IE5 mac now + because IE5 uses content-box but the script + assumes all versions of IE uses border-box. + + At the time of this writing mozilla did not support + box-sizing for absolute positioned element. + + Opera only supports content-box + */ + box-sizing: content-box; + -moz-box-sizing: content-box; +} + +.webfx-menu { + position: absolute; + z-index: 100; + visibility: hidden; + border: 1px solid black; + padding: 1px; + background: white; + filter: progid:DXImageTransform.Microsoft.Shadow(color="#777777", Direction=135, Strength=4) + alpha(Opacity=95); + -moz-opacity: 0.95; + /* a drop shadow would be nice in moz/others too... */ +} + +.webfx-menu-empty { + display: block; + border: 1px solid white; + padding: 2px 5px 2px 5px; + font-size: 11px; + /* font-family: Tahoma, Verdan, Helvetica, Sans-Serif; */ + color: black; +} + +.webfx-menu a { + display: block; + /* width: expression(constExpression(ieBox ? "100%": "auto")); /* should be ignored by mz and op */ + width: expression(constExpression(ie ? "98%": "auto")); /* should be ignored by mz and op */ + overflow: visible; + /* padding: 2px 0px 2px 5px; */ + padding: 1px 0px 1px 5px; + font-size: 14px; +/* font-family: Verdana, Arial, Helvetica, sans-serif; */ + font-weight: bold; + text-decoration: none; + vertical-align: center; + color: black; + border: 1px solid white; +} + +.webfx-menu a:visited { + color: black; + border: 1px solid white; +} + +.webfx-menu a:hover { + color: black; + border: 1px solid #7e0079; +} + +.webfx-menu a:hover { + color: black; + /* background: #faf7fa; #f5ebf4; #efdfef; white; #BC79B8; */ + /* background: #ffe6fe; */ + /* background: #ffc2fe; */ + background: #fff2fe; + border: 1px solid #7e0079; /*rgb(120,172,255);#ff8800;*/ +} + +.webfx-menu a .arrow { + float: right; + border: 0; + width: 3px; + margin-right: 3px; + margin-top: 4px; +} + +/* separtor */ +.webfx-menu div { + height: 0; + height: expression(constExpression(ieBox ? "2px" : "0")); + border-top: 1px solid #7e0079; /* rgb(120,172,255); */ + border-bottom: 1px solid rgb(234,242,255); + overflow: hidden; + margin: 2px 0px 2px 0px; + font-size: 0mm; +} + +.webfx-menu-bar { + /* i want a vertical bar */ + display: block; + + /* background: rgb(120,172,255);/*rgb(255,128,0);*/ + /* background: #a097ed; */ + background: #000000; + /* border: 1px solid #7E0079; */ + /* border: 1px solid #000000; */ + /* border: none */ + color: white; + + padding: 2px; + + /* IE5.0 has the wierdest box model for inline elements */ + padding: expression(constExpression(ie50 ? "0px" : "2px")); +} + +.webfx-menu-bar a, +.webfx-menu-bar a:visited { + /* i want a vertical bar */ + display: block; + + /* border: 1px solid black; /*rgb(0,0,0);/*rgb(255,128,0);*/ + /* border: 1px solid black; /* #ffffff; */ + /* border-bottom: 1px solid black; */ + border-bottom: 1px solid white; + /* border-bottom: 1px solid rgb(0,66,174); + /* border-bottom: 1px solid black; + border-bottom: 1px solid black; + border-bottom: 1px solid black; */ + + padding: 1px 5px 1px 5px; + + /* color: black; */ + color: white; + text-decoration: none; + + /* IE5.0 Does not paint borders and padding on inline elements without a height/width */ + height: expression(constExpression(ie50 ? "17px" : "auto")); +} + +.webfx-menu-bar a:link { + color: white; +} + +.webfx-menu-bar a:hover { + /* color: black; */ + color: white; + /* background: rgb(120,172,255); */ + /* background: #BC79B8; */ + background: #7e0079; + /* border-left: 1px solid rgb(234,242,255); + border-right: 1px solid rgb(0,66,174); + border-top: 1px solid rgb(234,242,255); + border-bottom: 1px solid rgb(0,66,174); */ +} + +.webfx-menu-bar a .arrow { + float: right; + border: 0; +/* vertical-align: top; */ + width: 3px; + margin-right: 3px; + margin-top: 4px; +} + +.webfx-menu-bar a:active, .webfx-menu-bar a:focus { + -moz-outline: none; + outline: none; + /* + ie does not support outline but ie55 can hide the outline using + a proprietary property on HTMLElement. Did I say that IE sucks at CSS? + */ + ie-dummy: expression(this.hideFocus=true); + +/* border-left: 1px solid rgb(0,66,174); */ +/* border-right: 1px solid rgb(234,242,255); */ +/* border-top: 1px solid rgb(0,66,174); */ +/* border-bottom: 1px solid rgb(234,242,255); */ +} + +.webfx-menu-title { + color: black; + /* background: #faf7fa; #f5ebf4; #efdfef; white; #BC79B8; */ + background: #7e0079; +/* border: 1px solid #7e0079; /*rgb(120,172,255);#ff8800;*/ + /* padding: 3px 1px 3px 6px; */ + padding: 3px 1px 3px 5px; + display: block; + font-size: 16px; +/* font-family: Verdana, Arial, Helvetica, sans-serif; */ + font-weight: bold; + text-decoration: none; + color: white; +/* border: 1px solid white; */ + border-bottom: 1px solid white; + width: expression(constExpression(ie ? "98%": "auto")); /* should be ignored by mz and op */ +} + diff --git a/httemplate/elements/xmenu.js b/httemplate/elements/xmenu.js new file mode 100644 index 000000000..134265f53 --- /dev/null +++ b/httemplate/elements/xmenu.js @@ -0,0 +1,668 @@ +//<script> +/* + * This script was created by Erik Arvidsson (erik@eae.net) + * for WebFX (http://webfx.eae.net) + * Copyright 2001 + * + * For usage see license at http://webfx.eae.net/license.html + * + * Created: 2001-01-12 + * Updates: 2001-11-20 Added hover mode support and removed Opera focus hacks + * 2001-12-20 Added auto positioning and some properties to support this + * 2002-08-13 toString used ' for attributes. Changed to " to allow in args + */ + +// check browsers +var ua = navigator.userAgent; +var opera = /opera [56789]|opera\/[56789]/i.test(ua); +var ie = !opera && /MSIE/.test(ua); +var ie50 = ie && /MSIE 5\.[01234]/.test(ua); +var ie6 = ie && /MSIE [6789]/.test(ua); +var ieBox = ie && (document.compatMode == null || document.compatMode != "CSS1Compat"); +var moz = !opera && /gecko/i.test(ua); +var nn6 = !opera && /netscape.*6\./i.test(ua); +var khtml = /KHTML/i.test(ua); + +// define the default values + +webfxMenuDefaultWidth = 154; + +webfxMenuDefaultBorderLeft = 1; +webfxMenuDefaultBorderRight = 1; +webfxMenuDefaultBorderTop = 1; +webfxMenuDefaultBorderBottom = 1; + +webfxMenuDefaultPaddingLeft = 1; +webfxMenuDefaultPaddingRight = 1; +webfxMenuDefaultPaddingTop = 1; +webfxMenuDefaultPaddingBottom = 1; + +webfxMenuDefaultShadowLeft = 0; +webfxMenuDefaultShadowRight = ie && !ie50 && /win32/i.test(navigator.platform) ? 4 :0; +webfxMenuDefaultShadowTop = 0; +webfxMenuDefaultShadowBottom = ie && !ie50 && /win32/i.test(navigator.platform) ? 4 : 0; + + +webfxMenuItemDefaultHeight = 18; +webfxMenuItemDefaultText = "Untitled"; +webfxMenuItemDefaultHref = "javascript:void(0)"; + +webfxMenuSeparatorDefaultHeight = 6; + +webfxMenuDefaultEmptyText = "Empty"; + +webfxMenuDefaultUseAutoPosition = nn6 ? false : true; + + + +// other global constants + +webfxMenuImagePath = ""; + +webfxMenuUseHover = opera ? true : false; +webfxMenuHideTime = 500; +webfxMenuShowTime = 200; + + + +var webFXMenuHandler = { + idCounter : 0, + idPrefix : "webfx-menu-object-", + all : {}, + getId : function () { return this.idPrefix + this.idCounter++; }, + overMenuItem : function (oItem) { + if (this.showTimeout != null) + window.clearTimeout(this.showTimeout); + if (this.hideTimeout != null) + window.clearTimeout(this.hideTimeout); + var jsItem = this.all[oItem.id]; + if (webfxMenuShowTime <= 0) + this._over(jsItem); + else if ( jsItem ) + //this.showTimeout = window.setTimeout(function () { webFXMenuHandler._over(jsItem) ; }, webfxMenuShowTime); + // I hate IE5.0 because the piece of shit crashes when using setTimeout with a function object + this.showTimeout = window.setTimeout("webFXMenuHandler._over(webFXMenuHandler.all['" + jsItem.id + "'])", webfxMenuShowTime); + }, + outMenuItem : function (oItem) { + if (this.showTimeout != null) + window.clearTimeout(this.showTimeout); + if (this.hideTimeout != null) + window.clearTimeout(this.hideTimeout); + var jsItem = this.all[oItem.id]; + if (webfxMenuHideTime <= 0) + this._out(jsItem); + else if ( jsItem ) + //this.hideTimeout = window.setTimeout(function () { webFXMenuHandler._out(jsItem) ; }, webfxMenuHideTime); + this.hideTimeout = window.setTimeout("webFXMenuHandler._out(webFXMenuHandler.all['" + jsItem.id + "'])", webfxMenuHideTime); + }, + blurMenu : function (oMenuItem) { + window.setTimeout("webFXMenuHandler.all[\"" + oMenuItem.id + "\"].subMenu.hide();", webfxMenuHideTime); + }, + _over : function (jsItem) { + if (jsItem.subMenu) { + jsItem.parentMenu.hideAllSubs(); + jsItem.subMenu.show(); + } + else + jsItem.parentMenu.hideAllSubs(); + }, + _out : function (jsItem) { + // find top most menu + var root = jsItem; + var m; + if (root instanceof WebFXMenuButton) + m = root.subMenu; + else { + m = jsItem.parentMenu; + while (m.parentMenu != null && !(m.parentMenu instanceof WebFXMenuBar)) + m = m.parentMenu; + } + if (m != null) + m.hide(); + }, + hideMenu : function (menu) { + if (this.showTimeout != null) + window.clearTimeout(this.showTimeout); + if (this.hideTimeout != null) + window.clearTimeout(this.hideTimeout); + + this.hideTimeout = window.setTimeout("webFXMenuHandler.all['" + menu.id + "'].hide()", webfxMenuHideTime); + }, + showMenu : function (menu, src, dir) { + if (this.showTimeout != null) + window.clearTimeout(this.showTimeout); + if (this.hideTimeout != null) + window.clearTimeout(this.hideTimeout); + + if (arguments.length < 3) + dir = "vertical"; + + menu.show(src, dir); + } +}; + +function WebFXMenu() { + this._menuItems = []; + this._subMenus = []; + this.id = webFXMenuHandler.getId(); + this.top = 0; + this.left = 0; + this.shown = false; + this.parentMenu = null; + webFXMenuHandler.all[this.id] = this; +} + +WebFXMenu.prototype.width = webfxMenuDefaultWidth; +WebFXMenu.prototype.emptyText = webfxMenuDefaultEmptyText; +WebFXMenu.prototype.useAutoPosition = webfxMenuDefaultUseAutoPosition; + +WebFXMenu.prototype.borderLeft = webfxMenuDefaultBorderLeft; +WebFXMenu.prototype.borderRight = webfxMenuDefaultBorderRight; +WebFXMenu.prototype.borderTop = webfxMenuDefaultBorderTop; +WebFXMenu.prototype.borderBottom = webfxMenuDefaultBorderBottom; + +WebFXMenu.prototype.paddingLeft = webfxMenuDefaultPaddingLeft; +WebFXMenu.prototype.paddingRight = webfxMenuDefaultPaddingRight; +WebFXMenu.prototype.paddingTop = webfxMenuDefaultPaddingTop; +WebFXMenu.prototype.paddingBottom = webfxMenuDefaultPaddingBottom; + +WebFXMenu.prototype.shadowLeft = webfxMenuDefaultShadowLeft; +WebFXMenu.prototype.shadowRight = webfxMenuDefaultShadowRight; +WebFXMenu.prototype.shadowTop = webfxMenuDefaultShadowTop; +WebFXMenu.prototype.shadowBottom = webfxMenuDefaultShadowBottom; + + + +WebFXMenu.prototype.add = function (menuItem) { + this._menuItems[this._menuItems.length] = menuItem; + if (menuItem.subMenu) { + this._subMenus[this._subMenus.length] = menuItem.subMenu; + menuItem.subMenu.parentMenu = this; + } + + menuItem.parentMenu = this; +}; + +WebFXMenu.prototype.show = function (relObj, sDir) { + if (this.useAutoPosition) + this.position(relObj, sDir); + + var divElement = document.getElementById(this.id); + if ( divElement ) { + + divElement.style.left = opera ? this.left : this.left + "px"; + divElement.style.top = opera ? this.top : this.top + "px"; + divElement.style.visibility = "visible"; + + if ( ie ) { + var shimElement = document.getElementById(this.id + "Shim"); + if ( shimElement ) { + shimElement.style.width = divElement.offsetWidth; + shimElement.style.height = divElement.offsetHeight; + shimElement.style.top = divElement.style.top; + shimElement.style.left = divElement.style.left; + /*shimElement.style.zIndex = divElement.style.zIndex - 1; */ + shimElement.style.display = "block"; + shimElement.style.filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'; + } + } + + } + + this.shown = true; + + if (this.parentMenu) + this.parentMenu.show(); +}; + +WebFXMenu.prototype.hide = function () { + this.hideAllSubs(); + var divElement = document.getElementById(this.id); + if ( divElement ) { + divElement.style.visibility = "hidden"; + if ( ie ) { + var shimElement = document.getElementById(this.id + "Shim"); + if ( shimElement ) { + shimElement.style.display = "none"; + } + } + } + + this.shown = false; +}; + +WebFXMenu.prototype.hideAllSubs = function () { + for (var i = 0; i < this._subMenus.length; i++) { + if (this._subMenus[i].shown) + this._subMenus[i].hide(); + } +}; + +WebFXMenu.prototype.toString = function () { + var top = this.top + this.borderTop + this.paddingTop; + var str = "<div id='" + this.id + "' class='webfx-menu' style='" + + "width:" + (!ieBox ? + this.width - this.borderLeft - this.paddingLeft - this.borderRight - this.paddingRight : + this.width) + "px;" + + (this.useAutoPosition ? + "left:" + this.left + "px;" + "top:" + this.top + "px;" : + "") + + (ie50 ? "filter: none;" : "") + + "'>"; + + if (this._menuItems.length == 0) { + str += "<span class='webfx-menu-empty'>" + this.emptyText + "</span>"; + } + else { + str += '<span class="webfx-menu-title" onmouseover="webFXMenuHandler.overMenuItem(this)"' + + (webfxMenuUseHover ? " onmouseout='webFXMenuHandler.outMenuItem(this)'" : "") + + '>' + this.emptyText + '</span>'; + // str += '<div id="' + this.id + '-title">' + this.emptyText + '</div>'; + // loop through all menuItems + for (var i = 0; i < this._menuItems.length; i++) { + var mi = this._menuItems[i]; + str += mi; + if (!this.useAutoPosition) { + if (mi.subMenu && !mi.subMenu.useAutoPosition) + mi.subMenu.top = top - mi.subMenu.borderTop - mi.subMenu.paddingTop; + top += mi.height; + } + } + + } + + str += "</div>"; + + if ( ie ) { + str += "<iframe id='" + this.id + "Shim' src='javascript:false;' scrolling='no' frameBorder='0' style='position:absolute; top:0px; left: 0px; display:none;'></iframe>"; + } + + for (var i = 0; i < this._subMenus.length; i++) { + this._subMenus[i].left = this.left + this.width - this._subMenus[i].borderLeft; + str += this._subMenus[i]; + } + + return str; +}; +// WebFXMenu.prototype.position defined later + +function WebFXMenuItem(sText, sHref, sToolTip, oSubMenu) { + this.text = sText || webfxMenuItemDefaultText; + this.href = (sHref == null || sHref == "") ? webfxMenuItemDefaultHref : sHref; + this.subMenu = oSubMenu; + if (oSubMenu) + oSubMenu.parentMenuItem = this; + this.toolTip = sToolTip; + this.id = webFXMenuHandler.getId(); + webFXMenuHandler.all[this.id] = this; +}; +WebFXMenuItem.prototype.height = webfxMenuItemDefaultHeight; +WebFXMenuItem.prototype.toString = function () { + return "<a" + + " id='" + this.id + "'" + + " href=\"" + this.href + "\"" + + (this.toolTip ? " title=\"" + this.toolTip + "\"" : "") + + " onmouseover='webFXMenuHandler.overMenuItem(this)'" + + (webfxMenuUseHover ? " onmouseout='webFXMenuHandler.outMenuItem(this)'" : "") + + (this.subMenu ? " unselectable='on' tabindex='-1'" : "") + + ">" + + (this.subMenu ? "<img class='arrow' src=\"" + webfxMenuImagePath + "arrow.right.black.png\">" : "") + + this.text + + "</a>"; +}; + + +function WebFXMenuSeparator() { + this.id = webFXMenuHandler.getId(); + webFXMenuHandler.all[this.id] = this; +}; +WebFXMenuSeparator.prototype.height = webfxMenuSeparatorDefaultHeight; +WebFXMenuSeparator.prototype.toString = function () { + return "<div" + + " id='" + this.id + "'" + + (webfxMenuUseHover ? + " onmouseover='webFXMenuHandler.overMenuItem(this)'" + + " onmouseout='webFXMenuHandler.outMenuItem(this)'" + : + "") + + "></div>" +}; + +function WebFXMenuBar() { + this._parentConstructor = WebFXMenu; + this._parentConstructor(); +} +WebFXMenuBar.prototype = new WebFXMenu; +WebFXMenuBar.prototype.toString = function () { + var str = "<div id='" + this.id + "' class='webfx-menu-bar'>"; + + // loop through all menuButtons + for (var i = 0; i < this._menuItems.length; i++) + str += this._menuItems[i]; + + str += "</div>"; + + for (var i = 0; i < this._subMenus.length; i++) + str += this._subMenus[i]; + + return str; +}; + +function WebFXMenuButton(sText, sHref, sToolTip, oSubMenu) { + this._parentConstructor = WebFXMenuItem; + this._parentConstructor(sText, sHref, sToolTip, oSubMenu); +} +WebFXMenuButton.prototype = new WebFXMenuItem; +WebFXMenuButton.prototype.toString = function () { + return "<a" + + " id='" + this.id + "'" + + " href='" + this.href + "'" + + (this.toolTip ? " title='" + this.toolTip + "'" : "") + + (webfxMenuUseHover ? + (" onmouseover='webFXMenuHandler.overMenuItem(this)'" + + " onmouseout='webFXMenuHandler.outMenuItem(this)'") : + ( + " onfocus='webFXMenuHandler.overMenuItem(this)'" + + (this.subMenu ? + " onblur='webFXMenuHandler.blurMenu(this)'" : + "" + ) + )) + + ">" + + (this.subMenu ? "<img class='arrow' src='" + webfxMenuImagePath + "arrow.right.png'>" : "") + + this.text + + "</a>"; +}; + + + + + +/* Position functions */ + + +function getInnerLeft(el) { + + if (el == null) return 0; + + if (ieBox && el == document.body || !ieBox && el == document.documentElement) return 0; + + return parseInt( getLeft(el) + parseInt(getBorderLeft(el)) ); + +} + + + +function getLeft(el, debug) { + + if (el == null) return 0; + + //if ( debug ) + // alert ( el.offsetLeft + ' - ' + getInnerLeft(el.offsetParent) ); + + return parseInt( el.offsetLeft + parseInt(getInnerLeft(el.offsetParent)) ); + +} + + + +function getInnerTop(el) { + + if (el == null) return 0; + + if (ieBox && el == document.body || !ieBox && el == document.documentElement) return 0; + + return parseInt( getTop(el) + parseInt(getBorderTop(el)) ); + +} + + + +function getTop(el) { + + if (el == null) return 0; + + return parseInt( el.offsetTop + parseInt(getInnerTop(el.offsetParent)) ); + +} + + + +function getBorderLeft(el) { + + return ie ? + + el.clientLeft : + + ( khtml + ? parseInt(document.defaultView.getComputedStyle(el, null).getPropertyValue("border-left-width")) + : parseInt(window.getComputedStyle(el, null).getPropertyValue("border-left-width")) + ); + +} + + + +function getBorderTop(el) { + + return ie ? + + el.clientTop : + + ( khtml + ? parseInt(document.defaultView.getComputedStyle(el, null).getPropertyValue("border-left-width")) + : parseInt(window.getComputedStyle(el, null).getPropertyValue("border-top-width")) + ); + +} + + + +function opera_getLeft(el) { + + if (el == null) return 0; + + return el.offsetLeft + opera_getLeft(el.offsetParent); + +} + + + +function opera_getTop(el) { + + if (el == null) return 0; + + return el.offsetTop + opera_getTop(el.offsetParent); + +} + + + +function getOuterRect(el, debug) { + + return { + + left: (opera ? opera_getLeft(el) : getLeft(el, debug)), + + top: (opera ? opera_getTop(el) : getTop(el)), + + width: el.offsetWidth, + + height: el.offsetHeight + + }; + +} + + + +// mozilla bug! scrollbars not included in innerWidth/height + +function getDocumentRect(el) { + + return { + + left: 0, + + top: 0, + + width: (ie ? + + (ieBox ? document.body.clientWidth : document.documentElement.clientWidth) : + + window.innerWidth + + ), + + height: (ie ? + + (ieBox ? document.body.clientHeight : document.documentElement.clientHeight) : + + window.innerHeight + + ) + + }; + +} + + + +function getScrollPos(el) { + + return { + + left: (ie ? + + (ieBox ? document.body.scrollLeft : document.documentElement.scrollLeft) : + + window.pageXOffset + + ), + + top: (ie ? + + (ieBox ? document.body.scrollTop : document.documentElement.scrollTop) : + + window.pageYOffset + + ) + + }; + +} + + +/* end position functions */ + +WebFXMenu.prototype.position = function (relEl, sDir) { + var dir = sDir; + // find parent item rectangle, piRect + var piRect; + if (!relEl) { + var pi = this.parentMenuItem; + if (!this.parentMenuItem) + return; + + relEl = document.getElementById(pi.id); + if (dir == null) + dir = pi instanceof WebFXMenuButton ? "vertical" : "horizontal"; + //alert('created RelEl from parent: ' + pi.id); + piRect = getOuterRect(relEl, 1); + } + else if (relEl.left != null && relEl.top != null && relEl.width != null && relEl.height != null) { // got a rect + //alert('passed a Rect as RelEl: ' + typeof(relEl)); + + piRect = relEl; + } + else { + //alert('passed an element as RelEl: ' + typeof(relEl)); + piRect = getOuterRect(relEl); + } + + var menuEl = document.getElementById(this.id); + var menuRect = getOuterRect(menuEl); + var docRect = getDocumentRect(); + var scrollPos = getScrollPos(); + var pMenu = this.parentMenu; + + if (dir == "vertical") { + if (piRect.left + menuRect.width - scrollPos.left <= docRect.width) { + //alert('piRect.left: ' + piRect.left); + this.left = piRect.left; + if ( ! ie ) + this.left = this.left + 138; + } else if (docRect.width >= menuRect.width) { + //konq (not safari though) winds up here by accident and positions the menus all weird + //alert('docRect.width + scrollPos.left - menuRect.width'); + + this.left = docRect.width + scrollPos.left - menuRect.width; + } else { + //alert('scrollPos.left: ' + scrollPos.left); + this.left = scrollPos.left; + } + + if (piRect.top + piRect.height + menuRect.height <= docRect.height + scrollPos.top) + + this.top = piRect.top + piRect.height; + + else if (piRect.top - menuRect.height >= scrollPos.top) + + this.top = piRect.top - menuRect.height; + + else if (docRect.height >= menuRect.height) + + this.top = docRect.height + scrollPos.top - menuRect.height; + + else + + this.top = scrollPos.top; + } + else { + if (piRect.top + menuRect.height - this.borderTop - this.paddingTop <= docRect.height + scrollPos.top) + + this.top = piRect.top - this.borderTop - this.paddingTop; + + else if (piRect.top + piRect.height - menuRect.height + this.borderTop + this.paddingTop >= 0) + + this.top = piRect.top + piRect.height - menuRect.height + this.borderBottom + this.paddingBottom + this.shadowBottom; + + else if (docRect.height >= menuRect.height) + + this.top = docRect.height + scrollPos.top - menuRect.height; + + else + + this.top = scrollPos.top; + + + + var pMenuPaddingLeft = pMenu ? pMenu.paddingLeft : 0; + + var pMenuBorderLeft = pMenu ? pMenu.borderLeft : 0; + + var pMenuPaddingRight = pMenu ? pMenu.paddingRight : 0; + + var pMenuBorderRight = pMenu ? pMenu.borderRight : 0; + + + + if (piRect.left + piRect.width + menuRect.width + pMenuPaddingRight + + + pMenuBorderRight - this.borderLeft + this.shadowRight <= docRect.width + scrollPos.left) + + this.left = piRect.left + piRect.width + pMenuPaddingRight + pMenuBorderRight - this.borderLeft; + + else if (piRect.left - menuRect.width - pMenuPaddingLeft - pMenuBorderLeft + this.borderRight + this.shadowRight >= 0) + + this.left = piRect.left - menuRect.width - pMenuPaddingLeft - pMenuBorderLeft + this.borderRight + this.shadowRight; + + else if (docRect.width >= menuRect.width) + + this.left = docRect.width + scrollPos.left - menuRect.width; + + else + + this.left = scrollPos.left; + } +}; diff --git a/httemplate/elements/xmenu.top.css b/httemplate/elements/xmenu.top.css new file mode 100644 index 000000000..75917031b --- /dev/null +++ b/httemplate/elements/xmenu.top.css @@ -0,0 +1,211 @@ + +.webfx-menu, .webfx-menu * { + /* + Set the box sizing to content box + in the future when IE6 supports box-sizing + there will be an issue to fix the sizes + + There is probably an issue with IE5 mac now + because IE5 uses content-box but the script + assumes all versions of IE uses border-box. + + At the time of this writing mozilla did not support + box-sizing for absolute positioned element. + + Opera only supports content-box + */ + box-sizing: content-box; + -moz-box-sizing: content-box; +} + +.webfx-menu { + position: absolute; + z-index: 100; + visibility: hidden; + border: 1px solid black; + padding: 1px; + background: white; + filter: progid:DXImageTransform.Microsoft.Shadow(color="#777777", Direction=135, Strength=4) + alpha(Opacity=95); + -moz-opacity: 0.95; + /* a drop shadow would be nice in moz/others too... */ +} + +.webfx-menu-empty { + display: block; + border: 1px solid white; + padding: 2px 5px 2px 5px; + font-size: 11px; + /* font-family: Tahoma, Verdan, Helvetica, Sans-Serif; */ + color: black; +} + +.webfx-menu a { + display: block; + /* width: expression(constExpression(ieBox ? "100%": "auto")); /* should be ignored by mz and op */ + width: expression(constExpression(ie ? "98%": "auto")); /* should be ignored by mz and op */ + overflow: visible; + /* padding: 2px 0px 2px 5px; */ + padding: 1px 0px 1px 5px; + font-size: 14px; +/* font-family: Verdana, Arial, Helvetica, sans-serif; */ + font-weight: bold; + text-decoration: none; + vertical-align: center; + color: black; + border: 1px solid white; +} + +.webfx-menu a:visited { + color: black; + border: 1px solid white; +} + +.webfx-menu a:hover { + color: black; + border: 1px solid #7e0079; +} + +.webfx-menu a:hover { + color: black; + /* background: #faf7fa; #f5ebf4; #efdfef; white; #BC79B8; */ + /* background: #ffe6fe; */ + /* background: #ffc2fe; */ + background: #fff2fe; + border: 1px solid #7e0079; /*rgb(120,172,255);#ff8800;*/ +} + +.webfx-menu a .arrow { + float: right; + border: 0; + width: 3px; + margin-right: 3px; + margin-top: 4px; +} + +/* separtor */ +.webfx-menu div { + height: 0; + height: expression(constExpression(ieBox ? "2px" : "0")); + border-top: 1px solid #7e0079; /* rgb(120,172,255); */ + border-bottom: 1px solid rgb(234,242,255); + overflow: hidden; + margin: 2px 0px 2px 0px; + font-size: 0mm; +} + +.webfx-menu-bar { + /* background: rgb(120,172,255);/*rgb(255,128,0);*/ + /* background: #a097ed; */ + background: #000000; + /* border: 1px solid #7E0079; */ + /* border: 1px solid #000000; */ + /* border: none */ + color: white; + + padding: 2px; + + /* IE5.0 has the wierdest box model for inline elements */ + padding: expression(constExpression(ie50 ? "0px" : "2px")); +} + +.webfx-menu-bar a, +.webfx-menu-bar a:visited { + /* i want a vertical bar */ + /* display: block; */ + + /* border: 1px solid black; /*rgb(0,0,0);/*rgb(255,128,0);*/ + /* border: 1px solid black; /* #ffffff; */ + /* border-bottom: 1px solid black; */ + /* border-bottom: 1px solid white; */ + /* border-bottom: 1px solid rgb(0,66,174); + /* border-bottom: 1px solid black; + border-bottom: 1px solid black; + border-bottom: 1px solid black; */ + + padding: 1px 5px 1px 5px; + + /* color: black; */ + color: white; + text-decoration: none; + + /* IE5.0 Does not paint borders and padding on inline elements without a height/width */ + height: expression(constExpression(ie50 ? "17px" : "auto")); + + background-color:#333333; + border:1px solid; + border-top-color:#cccccc; + border-left-color:#cccccc; + border-right-color:#aaaaaa; + border-bottom-color:#aaaaaa; + + margin-right: 4px + +} + +.webfx-menu-bar a:link { + color: white; +} + +.webfx-menu-bar a:hover { + /* color: black; */ + color: white; + /* background: rgb(120,172,255); */ + /* background: #BC79B8; */ + background: #7e0079; + /* border-left: 1px solid rgb(234,242,255); + border-right: 1px solid rgb(0,66,174); + border-top: 1px solid rgb(234,242,255); + border-bottom: 1px solid rgb(0,66,174); */ + + border:1px solid; + border-top-color:#cccccc; + border-left-color:#cccccc; + border-right-color:#aaaaaa; + border-bottom-color:#aaaaaa; + +} + +.webfx-menu-bar a .arrow { + /* float: right; */ + border: 0; +/* vertical-align: top; */ +/* width: 3px; */ +/* margin-right: 3px; */ + margin-bottom: 2px; + +} + +.webfx-menu-bar a:active, .webfx-menu-bar a:focus { + -moz-outline: none; + outline: none; + /* + ie does not support outline but ie55 can hide the outline using + a proprietary property on HTMLElement. Did I say that IE sucks at CSS? + */ + ie-dummy: expression(this.hideFocus=true); + +/* border-left: 1px solid rgb(0,66,174); */ +/* border-right: 1px solid rgb(234,242,255); */ +/* border-top: 1px solid rgb(0,66,174); */ +/* border-bottom: 1px solid rgb(234,242,255); */ +} + +.webfx-menu-title { + color: black; + /* background: #faf7fa; #f5ebf4; #efdfef; white; #BC79B8; */ + background: #7e0079; +/* border: 1px solid #7e0079; /*rgb(120,172,255);#ff8800;*/ + /* padding: 3px 1px 3px 6px; */ + padding: 3px 1px 3px 5px; + display: block; + font-size: 16px; +/* font-family: Verdana, Arial, Helvetica, sans-serif; */ + font-weight: bold; + text-decoration: none; + color: white; +/* border: 1px solid white; */ + border-bottom: 1px solid white; + width: expression(constExpression(ie ? "98%": "auto")); /* should be ignored by mz and op */ +} + diff --git a/httemplate/elements/xmenu.top.js b/httemplate/elements/xmenu.top.js new file mode 100644 index 000000000..8d81035a2 --- /dev/null +++ b/httemplate/elements/xmenu.top.js @@ -0,0 +1,671 @@ +//<script> +/* + * This script was created by Erik Arvidsson (erik@eae.net) + * for WebFX (http://webfx.eae.net) + * Copyright 2001 + * + * For usage see license at http://webfx.eae.net/license.html + * + * Created: 2001-01-12 + * Updates: 2001-11-20 Added hover mode support and removed Opera focus hacks + * 2001-12-20 Added auto positioning and some properties to support this + * 2002-08-13 toString used ' for attributes. Changed to " to allow in args + */ + +// check browsers +var ua = navigator.userAgent; +var opera = /opera [56789]|opera\/[56789]/i.test(ua); +var ie = !opera && /MSIE/.test(ua); +var ie50 = ie && /MSIE 5\.[01234]/.test(ua); +var ie6 = ie && /MSIE [6789]/.test(ua); +var ieBox = ie && (document.compatMode == null || document.compatMode != "CSS1Compat"); +var moz = !opera && /gecko/i.test(ua); +var nn6 = !opera && /netscape.*6\./i.test(ua); +var khtml = /KHTML/i.test(ua); + +// define the default values + +webfxMenuDefaultWidth = 154; + +webfxMenuDefaultBorderLeft = 1; +webfxMenuDefaultBorderRight = 1; +webfxMenuDefaultBorderTop = 1; +webfxMenuDefaultBorderBottom = 1; + +webfxMenuDefaultPaddingLeft = 1; +webfxMenuDefaultPaddingRight = 1; +webfxMenuDefaultPaddingTop = 1; +webfxMenuDefaultPaddingBottom = 1; + +webfxMenuDefaultShadowLeft = 0; +webfxMenuDefaultShadowRight = ie && !ie50 && /win32/i.test(navigator.platform) ? 4 :0; +webfxMenuDefaultShadowTop = 0; +webfxMenuDefaultShadowBottom = ie && !ie50 && /win32/i.test(navigator.platform) ? 4 : 0; + + +webfxMenuItemDefaultHeight = 18; +webfxMenuItemDefaultText = "Untitled"; +webfxMenuItemDefaultHref = "javascript:void(0)"; + +webfxMenuSeparatorDefaultHeight = 6; + +webfxMenuDefaultEmptyText = "Empty"; + +webfxMenuDefaultUseAutoPosition = nn6 ? false : true; + + + +// other global constants + +webfxMenuImagePath = ""; + +webfxMenuUseHover = opera ? true : false; +webfxMenuHideTime = 500; +webfxMenuShowTime = 200; + + + +var webFXMenuHandler = { + idCounter : 0, + idPrefix : "webfx-menu-object-", + all : {}, + getId : function () { return this.idPrefix + this.idCounter++; }, + overMenuItem : function (oItem) { + if (this.showTimeout != null) + window.clearTimeout(this.showTimeout); + if (this.hideTimeout != null) + window.clearTimeout(this.hideTimeout); + var jsItem = this.all[oItem.id]; + if (webfxMenuShowTime <= 0) + this._over(jsItem); + else if ( jsItem ) + //this.showTimeout = window.setTimeout(function () { webFXMenuHandler._over(jsItem) ; }, webfxMenuShowTime); + // I hate IE5.0 because the piece of shit crashes when using setTimeout with a function object + this.showTimeout = window.setTimeout("webFXMenuHandler._over(webFXMenuHandler.all['" + jsItem.id + "'])", webfxMenuShowTime); + }, + outMenuItem : function (oItem) { + if (this.showTimeout != null) + window.clearTimeout(this.showTimeout); + if (this.hideTimeout != null) + window.clearTimeout(this.hideTimeout); + var jsItem = this.all[oItem.id]; + if (webfxMenuHideTime <= 0) + this._out(jsItem); + else if ( jsItem ) + //this.hideTimeout = window.setTimeout(function () { webFXMenuHandler._out(jsItem) ; }, webfxMenuHideTime); + this.hideTimeout = window.setTimeout("webFXMenuHandler._out(webFXMenuHandler.all['" + jsItem.id + "'])", webfxMenuHideTime); + }, + blurMenu : function (oMenuItem) { + window.setTimeout("webFXMenuHandler.all[\"" + oMenuItem.id + "\"].subMenu.hide();", webfxMenuHideTime); + }, + _over : function (jsItem) { + if (jsItem.subMenu) { + jsItem.parentMenu.hideAllSubs(); + jsItem.subMenu.show(); + } + else + jsItem.parentMenu.hideAllSubs(); + }, + _out : function (jsItem) { + // find top most menu + var root = jsItem; + var m; + if (root instanceof WebFXMenuButton) + m = root.subMenu; + else { + m = jsItem.parentMenu; + while (m.parentMenu != null && !(m.parentMenu instanceof WebFXMenuBar)) + m = m.parentMenu; + } + if (m != null) + m.hide(); + }, + hideMenu : function (menu) { + if (this.showTimeout != null) + window.clearTimeout(this.showTimeout); + if (this.hideTimeout != null) + window.clearTimeout(this.hideTimeout); + + this.hideTimeout = window.setTimeout("webFXMenuHandler.all['" + menu.id + "'].hide()", webfxMenuHideTime); + }, + showMenu : function (menu, src, dir) { + if (this.showTimeout != null) + window.clearTimeout(this.showTimeout); + if (this.hideTimeout != null) + window.clearTimeout(this.hideTimeout); + + if (arguments.length < 3) + dir = "vertical"; + + menu.show(src, dir); + } +}; + +function WebFXMenu() { + this._menuItems = []; + this._subMenus = []; + this.id = webFXMenuHandler.getId(); + this.top = 0; + this.left = 0; + this.shown = false; + this.parentMenu = null; + webFXMenuHandler.all[this.id] = this; +} + +WebFXMenu.prototype.width = webfxMenuDefaultWidth; +WebFXMenu.prototype.emptyText = webfxMenuDefaultEmptyText; +WebFXMenu.prototype.useAutoPosition = webfxMenuDefaultUseAutoPosition; + +WebFXMenu.prototype.borderLeft = webfxMenuDefaultBorderLeft; +WebFXMenu.prototype.borderRight = webfxMenuDefaultBorderRight; +WebFXMenu.prototype.borderTop = webfxMenuDefaultBorderTop; +WebFXMenu.prototype.borderBottom = webfxMenuDefaultBorderBottom; + +WebFXMenu.prototype.paddingLeft = webfxMenuDefaultPaddingLeft; +WebFXMenu.prototype.paddingRight = webfxMenuDefaultPaddingRight; +WebFXMenu.prototype.paddingTop = webfxMenuDefaultPaddingTop; +WebFXMenu.prototype.paddingBottom = webfxMenuDefaultPaddingBottom; + +WebFXMenu.prototype.shadowLeft = webfxMenuDefaultShadowLeft; +WebFXMenu.prototype.shadowRight = webfxMenuDefaultShadowRight; +WebFXMenu.prototype.shadowTop = webfxMenuDefaultShadowTop; +WebFXMenu.prototype.shadowBottom = webfxMenuDefaultShadowBottom; + + + +WebFXMenu.prototype.add = function (menuItem) { + this._menuItems[this._menuItems.length] = menuItem; + if (menuItem.subMenu) { + this._subMenus[this._subMenus.length] = menuItem.subMenu; + menuItem.subMenu.parentMenu = this; + } + + menuItem.parentMenu = this; +}; + +WebFXMenu.prototype.show = function (relObj, sDir) { + if (this.useAutoPosition) + this.position(relObj, sDir); + + var divElement = document.getElementById(this.id); + if ( divElement ) { + + divElement.style.left = opera ? this.left : this.left + "px"; + divElement.style.top = opera ? this.top : this.top + "px"; + divElement.style.visibility = "visible"; + + if ( ie ) { + var shimElement = document.getElementById(this.id + "Shim"); + if ( shimElement ) { + shimElement.style.width = divElement.offsetWidth; + shimElement.style.height = divElement.offsetHeight; + shimElement.style.top = divElement.style.top; + shimElement.style.left = divElement.style.left; + /*shimElement.style.zIndex = divElement.style.zIndex - 1; */ + shimElement.style.display = "block"; + shimElement.style.filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'; + } + } + + } + + this.shown = true; + + if (this.parentMenu) + this.parentMenu.show(); +}; + +WebFXMenu.prototype.hide = function () { + this.hideAllSubs(); + var divElement = document.getElementById(this.id); + if ( divElement ) { + divElement.style.visibility = "hidden"; + if ( ie ) { + var shimElement = document.getElementById(this.id + "Shim"); + if ( shimElement ) { + shimElement.style.display = "none"; + } + } + } + + this.shown = false; +}; + +WebFXMenu.prototype.hideAllSubs = function () { + for (var i = 0; i < this._subMenus.length; i++) { + if (this._subMenus[i].shown) + this._subMenus[i].hide(); + } +}; + +WebFXMenu.prototype.toString = function () { + var top = this.top + this.borderTop + this.paddingTop; + var str = "<div id='" + this.id + "' class='webfx-menu' style='" + + "width:" + (!ieBox ? + this.width - this.borderLeft - this.paddingLeft - this.borderRight - this.paddingRight : + this.width) + "px;" + + (this.useAutoPosition ? + "left:" + this.left + "px;" + "top:" + this.top + "px;" : + "") + + (ie50 ? "filter: none;" : "") + + "'>"; + + if (this._menuItems.length == 0) { + str += "<span class='webfx-menu-empty'>" + this.emptyText + "</span>"; + } + else { + str += '<span class="webfx-menu-title" onmouseover="webFXMenuHandler.overMenuItem(this)"' + + (webfxMenuUseHover ? " onmouseout='webFXMenuHandler.outMenuItem(this)'" : "") + + '>' + this.emptyText + '</span>'; + // str += '<div id="' + this.id + '-title">' + this.emptyText + '</div>'; + // loop through all menuItems + for (var i = 0; i < this._menuItems.length; i++) { + var mi = this._menuItems[i]; + str += mi; + if (!this.useAutoPosition) { + if (mi.subMenu && !mi.subMenu.useAutoPosition) + mi.subMenu.top = top - mi.subMenu.borderTop - mi.subMenu.paddingTop; + top += mi.height; + } + } + + } + + str += "</div>"; + + if ( ie ) { + str += "<iframe id='" + this.id + "Shim' src='javascript:false;' scrolling='no' frameBorder='0' style='position:absolute; top:0px; left: 0px; display:none;'></iframe>"; + } + + for (var i = 0; i < this._subMenus.length; i++) { + this._subMenus[i].left = this.left + this.width - this._subMenus[i].borderLeft; + str += this._subMenus[i]; + } + + return str; +}; +// WebFXMenu.prototype.position defined later + +function WebFXMenuItem(sText, sHref, sToolTip, oSubMenu) { + this.text = sText || webfxMenuItemDefaultText; + this.href = (sHref == null || sHref == "") ? webfxMenuItemDefaultHref : sHref; + this.subMenu = oSubMenu; + if (oSubMenu) + oSubMenu.parentMenuItem = this; + this.toolTip = sToolTip; + this.id = webFXMenuHandler.getId(); + webFXMenuHandler.all[this.id] = this; +}; +WebFXMenuItem.prototype.height = webfxMenuItemDefaultHeight; +WebFXMenuItem.prototype.toString = function () { + return "<a" + + " id='" + this.id + "'" + + " href=\"" + this.href + "\"" + + (this.toolTip ? " title=\"" + this.toolTip + "\"" : "") + + " onmouseover='webFXMenuHandler.overMenuItem(this)'" + + (webfxMenuUseHover ? " onmouseout='webFXMenuHandler.outMenuItem(this)'" : "") + + (this.subMenu ? " unselectable='on' tabindex='-1'" : "") + + ">" + + (this.subMenu ? "<img class='arrow' src=\"" + webfxMenuImagePath + "arrow.right.black.png\">" : "") + + this.text + + "</a>"; +}; + + +function WebFXMenuSeparator() { + this.id = webFXMenuHandler.getId(); + webFXMenuHandler.all[this.id] = this; +}; +WebFXMenuSeparator.prototype.height = webfxMenuSeparatorDefaultHeight; +WebFXMenuSeparator.prototype.toString = function () { + return "<div" + + " id='" + this.id + "'" + + (webfxMenuUseHover ? + " onmouseover='webFXMenuHandler.overMenuItem(this)'" + + " onmouseout='webFXMenuHandler.outMenuItem(this)'" + : + "") + + "></div>" +}; + +function WebFXMenuBar() { + this._parentConstructor = WebFXMenu; + this._parentConstructor(); +} +WebFXMenuBar.prototype = new WebFXMenu; +WebFXMenuBar.prototype.toString = function () { + var str = "<div id='" + this.id + "' class='webfx-menu-bar'>"; + + // loop through all menuButtons + for (var i = 0; i < this._menuItems.length; i++) + str += this._menuItems[i]; + + str += "</div>"; + + for (var i = 0; i < this._subMenus.length; i++) + str += this._subMenus[i]; + + return str; +}; + +function WebFXMenuButton(sText, sHref, sToolTip, oSubMenu) { + this._parentConstructor = WebFXMenuItem; + this._parentConstructor(sText, sHref, sToolTip, oSubMenu); +} +WebFXMenuButton.prototype = new WebFXMenuItem; +WebFXMenuButton.prototype.toString = function () { + return "<a" + + " id='" + this.id + "'" + + " href='" + this.href + "'" + + (this.toolTip ? " title='" + this.toolTip + "'" : "") + + (webfxMenuUseHover ? + (" onmouseover='webFXMenuHandler.overMenuItem(this)'" + + " onmouseout='webFXMenuHandler.outMenuItem(this)'") : + ( + " onfocus='webFXMenuHandler.overMenuItem(this)'" + + (this.subMenu ? + " onblur='webFXMenuHandler.blurMenu(this)'" : + "" + ) + )) + + ">" + + this.text + + (this.subMenu ? "<img class='arrow' src='" + webfxMenuImagePath + "arrow.down.png'>" : "") + + "</a>"; +}; + + + + + +/* Position functions */ + + +function getInnerLeft(el, debug) { + + if (el == null) return 0; + + if (ieBox && el == document.body || !ieBox && el == document.documentElement) return 0; + + //if ( debug ) + // alert ( 'getInnerLeft: ' + getLeft(el) + ' - ' + getBorderLeft(el) ); + + return parseInt( getLeft(el) + parseInt(getBorderLeft(el)) ); + +} + + + +function getLeft(el, debug) { + + if (el == null) return 0; + + //if ( debug ) + // alert ( el + ': ' + el.offsetLeft + ' - ' + getInnerLeft(el.offsetParent) ); + + return parseInt( el.offsetLeft + parseInt(getInnerLeft(el.offsetParent)) ); + +} + + + +function getInnerTop(el) { + + if (el == null) return 0; + + if (ieBox && el == document.body || !ieBox && el == document.documentElement) return 0; + + return parseInt( getTop(el) + parseInt(getBorderTop(el)) ); + +} + + + +function getTop(el) { + + if (el == null) return 0; + + return parseInt( el.offsetTop + parseInt(getInnerTop(el.offsetParent)) ); + +} + + + +function getBorderLeft(el) { + + return ie ? + + el.clientLeft : + + ( khtml + ? parseInt(document.defaultView.getComputedStyle(el, null).getPropertyValue("border-left-width")) + : parseInt(window.getComputedStyle(el, null).getPropertyValue("border-left-width")) + ); + +} + + + +function getBorderTop(el) { + + return ie ? + + el.clientTop : + + ( khtml + ? parseInt(document.defaultView.getComputedStyle(el, null).getPropertyValue("border-left-width")) + : parseInt(window.getComputedStyle(el, null).getPropertyValue("border-top-width")) + ); + +} + + + +function opera_getLeft(el) { + + if (el == null) return 0; + + return el.offsetLeft + opera_getLeft(el.offsetParent); + +} + + + +function opera_getTop(el) { + + if (el == null) return 0; + + return el.offsetTop + opera_getTop(el.offsetParent); + +} + + + +function getOuterRect(el, debug) { + + return { + + left: (opera ? opera_getLeft(el) : getLeft(el, debug)), + + top: (opera ? opera_getTop(el) : getTop(el)), + + width: el.offsetWidth, + + height: el.offsetHeight + + }; + +} + + + +// mozilla bug! scrollbars not included in innerWidth/height + +function getDocumentRect(el) { + + return { + + left: 0, + + top: 0, + + width: (ie ? + + (ieBox ? document.body.clientWidth : document.documentElement.clientWidth) : + + window.innerWidth + + ), + + height: (ie ? + + (ieBox ? document.body.clientHeight : document.documentElement.clientHeight) : + + window.innerHeight + + ) + + }; + +} + + + +function getScrollPos(el) { + + return { + + left: (ie ? + + (ieBox ? document.body.scrollLeft : document.documentElement.scrollLeft) : + + window.pageXOffset + + ), + + top: (ie ? + + (ieBox ? document.body.scrollTop : document.documentElement.scrollTop) : + + window.pageYOffset + + ) + + }; + +} + + +/* end position functions */ + +WebFXMenu.prototype.position = function (relEl, sDir) { + var dir = sDir; + // find parent item rectangle, piRect + var piRect; + if (!relEl) { + var pi = this.parentMenuItem; + if (!this.parentMenuItem) + return; + + relEl = document.getElementById(pi.id); + if (dir == null) + dir = pi instanceof WebFXMenuButton ? "vertical" : "horizontal"; + //alert('created RelEl from parent: ' + pi.id); + piRect = getOuterRect(relEl, 1); + } + else if (relEl.left != null && relEl.top != null && relEl.width != null && relEl.height != null) { // got a rect + //alert('passed a Rect as RelEl: ' + typeof(relEl)); + + piRect = relEl; + } + else { + //alert('passed an element as RelEl: ' + typeof(relEl)); + piRect = getOuterRect(relEl); + } + + var menuEl = document.getElementById(this.id); + var menuRect = getOuterRect(menuEl); + var docRect = getDocumentRect(); + var scrollPos = getScrollPos(); + var pMenu = this.parentMenu; + + if (dir == "vertical") { + if (piRect.left + menuRect.width - scrollPos.left <= docRect.width) { + //alert('piRect.left: ' + piRect.left); + this.left = piRect.left; +// if ( ! ie ) +// this.left = this.left + 138; + } else if (docRect.width >= menuRect.width) { + //konq (not safari though) winds up here by accident and positions the menus all weird + //alert('docRect.width + scrollPos.left - menuRect.width'); + + this.left = docRect.width + scrollPos.left - menuRect.width; + } else { + //alert('scrollPos.left: ' + scrollPos.left); + this.left = scrollPos.left; + } + + if (piRect.top + piRect.height + menuRect.height <= docRect.height + scrollPos.top) + + this.top = piRect.top + piRect.height; + + else if (piRect.top - menuRect.height >= scrollPos.top) + + this.top = piRect.top - menuRect.height; + + else if (docRect.height >= menuRect.height) + + this.top = docRect.height + scrollPos.top - menuRect.height; + + else + + this.top = scrollPos.top; + } + else { + if (piRect.top + menuRect.height - this.borderTop - this.paddingTop <= docRect.height + scrollPos.top) + + this.top = piRect.top - this.borderTop - this.paddingTop; + + else if (piRect.top + piRect.height - menuRect.height + this.borderTop + this.paddingTop >= 0) + + this.top = piRect.top + piRect.height - menuRect.height + this.borderBottom + this.paddingBottom + this.shadowBottom; + + else if (docRect.height >= menuRect.height) + + this.top = docRect.height + scrollPos.top - menuRect.height; + + else + + this.top = scrollPos.top; + + + + var pMenuPaddingLeft = pMenu ? pMenu.paddingLeft : 0; + + var pMenuBorderLeft = pMenu ? pMenu.borderLeft : 0; + + var pMenuPaddingRight = pMenu ? pMenu.paddingRight : 0; + + var pMenuBorderRight = pMenu ? pMenu.borderRight : 0; + + + + if (piRect.left + piRect.width + menuRect.width + pMenuPaddingRight + + + pMenuBorderRight - this.borderLeft + this.shadowRight <= docRect.width + scrollPos.left) + + this.left = piRect.left + piRect.width + pMenuPaddingRight + pMenuBorderRight - this.borderLeft; + + else if (piRect.left - menuRect.width - pMenuPaddingLeft - pMenuBorderLeft + this.borderRight + this.shadowRight >= 0) + + this.left = piRect.left - menuRect.width - pMenuPaddingLeft - pMenuBorderLeft + this.borderRight + this.shadowRight; + + else if (docRect.width >= menuRect.width) + + this.left = docRect.width + scrollPos.left - menuRect.width; + + else + + this.left = scrollPos.left; + } +}; diff --git a/httemplate/elements/xmlhttp.html b/httemplate/elements/xmlhttp.html index 28130e501..6efc395f7 100644 --- a/httemplate/elements/xmlhttp.html +++ b/httemplate/elements/xmlhttp.html @@ -1,14 +1,16 @@ -<% - my ( %opt ) = @_; +% +% my ( %opt ) = @_; +% +% my $url = $opt{'url'}; +% my $method = exists($opt{'method'}) ? $opt{'method'} : 'GET'; +% #my @subs = @{ $opt{'subs'}; +% my $key = exists($opt{'key'}) ? $opt{'key'} : ''; +% +% $url .= ( ($url =~ /\?/) ? '&' : '?' ) +% if $method eq 'GET'; +% +% - my $url = $opt{'url'}; - my $method = exists($opt{'method'}) ? $opt{'method'} : 'GET'; - #my @subs = @{ $opt{'subs'}; - - $url .= ( ($url =~ /\?/) ? '&' : '?' ) - if $method eq 'GET'; - -%> <SCRIPT TYPE="text/javascript"> @@ -30,22 +32,22 @@ return A; } +% foreach my $func ( @{$opt{'subs'}} ) { +% +% my $furl = $url; +% $furl =~ s/\"/\\\\\"/; #javascript escape +% +% - <% foreach my $func ( @{$opt{'subs'}} ) { - - my $furl = $url; - $furl =~ s/\"/\\\\\"/; #javascript escape - - %> - function <%=$func%>() { + function <%$key%><%$func%>() { // count args; build URL - var url = "<%=$furl%>"; - var a = <%=$func%>.arguments; + var url = "<%$furl%>"; + var a = <%$key%><%$func%>.arguments; var args; var len; - var content = 'sub=<%= uri_escape($func) %>'; + var content = 'sub=<% uri_escape($func) %>'; if ( a && typeof a == 'object' && a[0].constructor == Array ) { args = a[0]; len = args.length @@ -57,14 +59,14 @@ content = content + "&arg=" + escape(args[i]); content = content.replace( /[+]/g, '%2B'); // fix unescaped plus signs - if ( '<%=$method%>' == 'GET' ) { + if ( '<%$method%>' == 'GET' ) { url = url + content; } - //alert('<%=$method%> ' + url); + //alert('<%$method%> ' + url); var xmlhttp = rs_init_object(); - xmlhttp.open("<%=$method%>", url, true); + xmlhttp.open("<%$method%>", url, true); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState != 4) @@ -88,7 +90,7 @@ } } - if ( '<%=$method%>' == 'POST' ) { + if ( '<%$method%>' == 'POST' ) { xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttp.send(content); @@ -103,7 +105,7 @@ //rs_debug("x_$func_name url = " + url); //rs_debug("x_$func_name waiting.."); } +% } - <% } %> </SCRIPT> |