/** * DatePickerControl.v.1.1.7 * * Transform your input text control into a date-picker control. * * By Hugo Ortega_Hernandez - hugorteg _no_spam_ at gmail dot com * * Last version of this code: http://dali.mty.itesm.mx/~hugo/js/datepickercontrol/ * * Features: * + Automatic input control conversion with a single attribute * in the 'input' tag or a special 'id' attribute format. * + Multiple date formats. * + Layered calendar, without pop-up window. * + Mouse and keyboard navigation. * + Variable first day of week. * + Min and Max dates. * + Easy i18n. * + CSS support. * * License: LGPL http://www.gnu.org/licenses/lgpl.html * (i.e., use this code as you wish, just keep it free) * Provided as is, without any warranty. * Feel free to use this code, but don't remove this disclaimer please. * * If you're going to use this library, please send me an email, and * would be great if you include a photo of your city :) * (se habla español) * * Credits: * * Functions to calculate days of a year and to generate the calendar code by: * Kedar R. Bhave - softricks at hotmail dot com * http://www.softricks.com * = Modified by Hugo Ortega_H: * + CSS style * + Remove non useful code (original version with pop-up window) * + Clean job :-) (so hard!) * + Add support for layered calendar * + Many other stuff. * * Other code functions and lines to calculate objects' size & location by: * Mircho Mirev - mo at momche dot net * * First day of week code by: * Massimiliano Ciancio - massimiliano at ciancio dot net * * * Veracruz & Monterrey, Mexico, 2005-2009. */ //----------------------------------------------------------------------------- // Some parameters for style and behaviour... // Is better to use global parameters to avoid problems with updates, // but if you want to override default values, here are the variables :-) // (see index.html to see how to use global parameters) DatePickerControl.defaultFormat = "DD-MM-YYYY"; DatePickerControl.submitFormat = ""; DatePickerControl.offsetY = 1; DatePickerControl.offsetX = 0; DatePickerControl.todayText = "dzisiaj"; DatePickerControl.buttonTitle = "Otwórz Kalendarz..."; DatePickerControl.buttonPosition = "in"; // or "out" DatePickerControl.buttonOffsetX = 0; // See below for some considerations about DatePickerControl.buttonOffsetY = 0; // that values (for IE) DatePickerControl.closeOnTodayBtn = true; // close if today button is pressed? DatePickerControl.defaultTodaySel = false; // If true and content is blank, today date will be selected DatePickerControl.autoShow = false; // Auto show the calendar when the input grab the focus. DatePickerControl.firstWeekDay = 1; // First day of week: 0=Sunday, 1=Monday, ..., 6=Saturday DatePickerControl.weekend = [0,6]; // Sunday and Saturday as weekend (maybe a 3-day weekend in France :D , I love it!...) DatePickerControl.weekNumber = false; // Display or not the week number DatePickerControl.Months = ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień']; // ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; // ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]; // ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]; // ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]; DatePickerControl.Days = // ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"]; // ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; // ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"]; // ["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"]; // ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"]; ['Nd', 'Pn', 'Wt', 'Śr', 'Czw', 'Pt', 'Sb']; //----------------------------------------------------------------------------- // Specific patches DatePickerControl.useTrickyBG = false; // Some people ask me about IE strange behaviour... well, here's the patch // IE returns object position with one pixel more // Patches for IE?, I can't believe! // There area a LOT of problems with IE, because if you change, for example, // the body margin, all control's positions are wrong... agghh... I hate IE... // this is why all my projects have a technical requirement: Mozilla family :-) if (navigator.userAgent.indexOf("MSIE") > 1){ DatePickerControl.useTrickyBG = true; DatePickerControl.offsetY = 0; DatePickerControl.offsetX = -1; DatePickerControl.buttonOffsetX = -4; DatePickerControl.buttonOffsetY = -2; // but if document have xhtml dtd, things are different... :S if (document.getElementsByTagName("html")[0].getAttribute("xmlns") != null){ DatePickerControl.offsetY = 16; DatePickerControl.offsetX = 10; DatePickerControl.buttonOffsetX = 8; DatePickerControl.buttonOffsetY = 14; } } //----------------------------------------------------------------------------- // Some constants and internal stuff DatePickerControl.editIdPrefix = "DPC_"; // The prefix for edit's id DatePickerControl.displayed = false; // Is the calendar layer displayed? DatePickerControl.HIDE_TIMEOUT = 200; // Time in ms for hide the calendar layer DatePickerControl.hideTimeout = null; // The timeout identifier DatePickerControl.buttonIdPrefix = "CALBUTTON"; // The prefix for the calendar button's id DatePickerControl.dayIdPrefix = "CALDAY"; // The prefix for the calendar days frames' id DatePickerControl.currentDay = 1; // The current day of current month of current year :-) DatePickerControl.originalValue = ""; // The original value of edit control DatePickerControl.calFrameId = "calendarframe"; // The id for the calendar layer DatePickerControl.submitByKey = false; // Is submitting by keyboard? DatePickerControl.dayOfWeek = 0; // The current day of current week ... DatePickerControl.firstFocused = false; // Is the first time that the current edit control is focused? DatePickerControl.hideCauseBlur = false; // Was the calendar close by onblur event? DatePickerControl.onSubmitAsigned = false; // Is form's onSubmit event asigned? DatePickerControl.minDate = null; // The minimum date for the current datepicker DatePickerControl.maxDate = null; // The maximum date for the current datepicker DatePickerControl.DOMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // Non-leap year month days DatePickerControl.lDOMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // Leap year month days //----------------------------------------------------------------------------- // The fun :-) //----------------------------------------------------------------------------- /** * Constructor (or something like that). */ function DatePickerControl() { } //----------------------------------------------------------------------------- /** * Creates the calendar's div element and the button into the input-texts with * attibute datepicker="true" or id="DPC_foo_[format]" */ DatePickerControl.init = function() { // try to create the DatePickerControl.container: if (!document.getElementById("CalendarPickerControl")){ // but first, take a look for global parameters: this.setGlobalParams(); this.calBG = null; if (this.useTrickyBG){ // Creates a tricky bg to hide the select controls (IE bug). // We use a iframe element, because is one of the elements that can // stay on top of select controls. // I don't like this solution, but IE is a pseudo-browser for developers this.calBG = document.createElement("iframe"); this.calBG.id = "CalendarPickerControlBG"; this.calBG.style.zIndex = "49999"; // below calcontainer this.calBG.style.position = "absolute"; this.calBG.style.display = "none"; this.calBG.style.border = "0px solid transparent"; document.body.appendChild(this.calBG); } this.calContainer = document.createElement("div"); this.calContainer.id = "CalendarPickerControl"; this.calContainer.style.zIndex = "50000"; this.calContainer.style.position = "absolute"; this.calContainer.style.display = "none"; document.body.appendChild(this.calContainer); if (this.calContainer.addEventListener){ this.calContainer.addEventListener("click", DPC_onContainerClick, false); window.addEventListener("resize", DPC_onWindowResize, false); } else if (this.calContainer.attachEvent){ this.calContainer.attachEvent("onclick", DPC_onContainerClick); window.attachEvent("onresize", DPC_onWindowResize); } } // looking for input controls that will be transformed into DatePickerControl's. var inputControls = document.getElementsByTagName("input"); var inputsLength = inputControls.length; for (i=0; i 6) ? 0 : parseInt(obj.value); obj = document.getElementById("DPC_WEEKEND_DAYS"); if (obj) eval("this.weekend = " + obj.value); obj = document.getElementById("DPC_AUTO_SHOW"); if (obj) this.autoShow = obj.value == "true"; obj = document.getElementById("DPC_DEFAULT_TODAY"); if (obj) this.defaultTodaySel = obj.value == "true"; obj = document.getElementById("DPC_CALENDAR_OFFSET_X"); if (obj) this.offsetX = parseInt(obj.value); obj = document.getElementById("DPC_CALENDAR_OFFSET_Y"); if (obj) this.offsetY = parseInt(obj.value); obj = document.getElementById("DPC_TODAY_TEXT"); if (obj) this.todayText = obj.value; obj = document.getElementById("DPC_BUTTON_TITLE"); if (obj) this.buttonTitle = obj.value; obj = document.getElementById("DPC_BUTTON_POSITION"); if (obj) this.buttonPosition = obj.value; obj = document.getElementById("DPC_BUTTON_OFFSET_X"); if (obj) this.buttonOffsetX = parseInt(obj.value); obj = document.getElementById("DPC_BUTTON_OFFSET_Y"); if (obj) this.buttonOffsetY = parseInt(obj.value); obj = document.getElementById("DPC_WEEK_NUMBER"); if (obj) this.weekNumber = obj.value == "true"; obj = document.getElementById("DPC_MONTH_NAMES"); if (obj) eval("this.Months = " + obj.value); obj = document.getElementById("DPC_DAY_NAMES"); if (obj) eval("this.Days = " + obj.value); } //----------------------------------------------------------------------------- /** * Wrapper for init() */ function DPC_autoInit() { DatePickerControl.init(); } if (window.addEventListener){ window.addEventListener("load", DPC_autoInit, false); } else if (window.attachEvent){ window.attachEvent("onload", DPC_autoInit); } //----------------------------------------------------------------------------- /** * Creates the calendar button for a text-input control and assign some attributes. * @param input The associated text-input to create the button. * @param useId Specify if you want to use the Id of input control to obtain the format * @return true is the control has been created, otherwise false */ DatePickerControl.createButton = function(input, useId) { var newid = this.buttonIdPrefix + input.id; if (document.getElementById(newid)) return false; // if exists previously.... // set the date format var fmt = ""; if (useId){ // get the format from the control's id var arr = input.id.split("_"); var last = arr[arr.length-1]; // a not so beauty validation :S if ((last.indexOf("-")>0 || last.indexOf("/")>0 || last.indexOf(".")>0) && last.indexOf("YY") >= 0 && last.indexOf("D") >= 0 && last.indexOf("M") >= 0){ // is a format fmt = last; } else{ fmt = this.defaultFormat; } } else{ // get the format from pseudo-attibute fmt = input.getAttribute("datepicker_format"); if (!fmt){ fmt = this.defaultFormat; } } input.setAttribute("datepicker_format", fmt); input.setAttribute("maxlength", fmt.length); // some new methods for datepickers input.setMinDate = function(d){this.setAttribute("datepicker_min", d);} input.setMaxDate = function(d){this.setAttribute("datepicker_max", d);} // Creates the button /* var calButton = document.createElement("div"); calButton.id = newid; calButton.title = this.buttonTitle; // Set some attributes to remember the text-input associated // with this button and its format: calButton.setAttribute("datepicker_inputid", input.id); calButton.setAttribute("datepicker_format", fmt); // Add the event listeners: if(calButton.addEventListener){ calButton.addEventListener("click", DPC_onButtonClick, false); } else if (calButton.attachEvent){ calButton.attachEvent("onclick", DPC_onButtonClick); } // add first to have access to the size properties // if is possible, add to the input's parent node // just in case we need to hide the button automatically if (input.parentNode){ input.parentNode.appendChild(calButton); } else{ document.body.appendChild(calButton); } // Set the style and position: var nTop = getObject.getSize("offsetTop", input); var nLeft = getObject.getSize("offsetLeft", input); calButton.className = "calendarbutton"; calButton.style.zIndex = 10000; calButton.style.cursor = "pointer"; calButton.style.top = (nTop + Math.floor((input.offsetHeight-calButton.offsetHeight)/2) + this.buttonOffsetY) + "px"; var btnOffX = Math.floor((input.offsetHeight - calButton.offsetHeight) / 2); if (this.buttonPosition == "in"){ calButton.style.left = (nLeft + input.offsetWidth - calButton.offsetWidth - btnOffX + this.buttonOffsetX) + "px"; } else{ // "out" calButton.style.left = (nLeft + input.offsetWidth + btnOffX + this.buttonOffsetX) + "px"; } */ var calButton = document.createElement('img'); calButton.id = newid; calButton.title = this.buttonTitle; // Set some attributes to remember the text-input associated // with this button and its format: calButton.setAttribute("datepicker_inputid", input.id); calButton.setAttribute("datepicker_format", fmt); // Add the event listeners: if (calButton.addEventListener){ calButton.addEventListener("click", DPC_onButtonClick, false); } else if (calButton.attachEvent){ calButton.attachEvent("onclick", DPC_onButtonClick); } // Set the style and position: calButton.className = "calendarbutton"; calButton.style.position = "relative"; calButton.style.cursor = "pointer"; calButton.style.verticalAlign = "bottom"; calButton.style.height = input.offsetHeight; calButton.src = "/wps/themes/html/Kreatywny/_img/date_calendar.gif"; if (this.buttonPosition == "in"){ // calButton.style.left = "-" + calButton.offsetWidth; } var theParent = input.parentNode; var noBreak = document.createElement('nobr'); var spacer = document.createElement('span'); spacer.innerHTML = " "; var sibling = null; if (input.nextSibling){ sibling = input.nextSibling; } theParent.removeChild(input); noBreak.appendChild(input); noBreak.appendChild(spacer); noBreak.appendChild(calButton); noBreak.appendChild(spacer.cloneNode(true)); if (sibling){ theParent.insertBefore(noBreak, sibling); } else{ theParent.appendChild(noBreak); } // everything is ok return true; } //----------------------------------------------------------------------------- /** * Show the calendar */ DatePickerControl.show = function() { if (!this.displayed){ var input = this.inputControl; if (input == null) return; if (input.disabled) return; // just in case ;) var top = getObject.getSize("offsetTop", input); var left = getObject.getSize("offsetLeft", input); var calframe = document.getElementById(this.calFrameId); this.calContainer.style.top = top + input.offsetHeight + this.offsetY + "px"; this.calContainer.style.left = left + this.offsetX + "px"; this.calContainer.style.display = "none"; this.calContainer.style.visibility = "visible"; this.calContainer.style.display = "block"; this.calContainer.style.height = calframe.offsetHeight; if (this.calBG){ // the ugly patch for IE this.calBG.style.top = this.calContainer.style.top; this.calBG.style.left = this.calContainer.style.left; this.calBG.style.display = "none"; this.calBG.style.visibility = "visible"; this.calBG.style.display = "block"; this.calBG.style.width = this.calContainer.offsetWidth; if (calframe){ this.calBG.style.height = calframe.offsetHeight; } } this.displayed = true; input.focus(); } } //----------------------------------------------------------------------------- /** * Hide the calendar */ DatePickerControl.hide = function() { if (this.displayed){ this.calContainer.style.visibility = "hidden"; this.calContainer.style.left = -1000; // some problems with overlaped controls this.calContainer.style.top = -1000; if (this.calBG){ // the ugly patch for IE this.calBG.style.visibility = "hidden"; this.calBG.style.left = -1000; this.calBG.style.top = -1000; } this.inputControl.value = this.originalValue; this.displayed = false; } } //----------------------------------------------------------------------------- /** * Gets the name of a numbered month */ DatePickerControl.getMonthName = function(monthNumber) { return this.Months[monthNumber]; } //----------------------------------------------------------------------------- /** * Obtains the days of a given month and year */ DatePickerControl.getDaysOfMonth = function(monthNo, p_year) { if (this.isLeapYear(p_year)){ return this.lDOMonth[monthNo]; } else{ return this.DOMonth[monthNo]; } } //----------------------------------------------------------------------------- /** * Will return an 1-D array with 1st element being the calculated month * and second being the calculated year after applying the month increment/decrement * as specified by 'incr' parameter. 'incr' will normally have 1/-1 to navigate thru * the months. */ DatePickerControl.calcMonthYear = function(p_Month, p_Year, incr) { var ret_arr = new Array(); if (incr == -1) { if (p_Month == 0) { ret_arr[0] = 11; ret_arr[1] = parseInt(p_Year) - 1; } else { ret_arr[0] = parseInt(p_Month) - 1; ret_arr[1] = parseInt(p_Year); } } else if (incr == 1) { if (p_Month == 11) { ret_arr[0] = 0; ret_arr[1] = parseInt(p_Year) + 1; } else { ret_arr[0] = parseInt(p_Month) + 1; ret_arr[1] = parseInt(p_Year); } } return ret_arr; } //----------------------------------------------------------------------------- /** * Gets the DatePickerControl HTML code */ DatePickerControl.getAllCode = function() { var vCode = ""; vCode += ""; vCode += this.getHeaderCode(); vCode += this.getDaysHeaderCode(); vCode += this.getDaysCode(); vCode += "
"; return vCode; } //----------------------------------------------------------------------------- /** * The title and nav buttons */ DatePickerControl.getHeaderCode = function() { var prevMMYYYY = this.calcMonthYear(this.month, this.year, -1); var prevMM = prevMMYYYY[0]; var prevYYYY = prevMMYYYY[1]; var nextMMYYYY = this.calcMonthYear(this.month, this.year, 1); var nextMM = nextMMYYYY[0]; var nextYYYY = nextMMYYYY[1]; var gNow = new Date(); var vCode = ""; var numberCols = this.weekNumber ? 8 : 7; vCode += ""; vCode += this.monthName + "  "; vCode += "«"; vCode += " " + this.year + " "; vCode += "»"; vCode += ""; vCode += ""; vCode += ""; vCode += ""; vCode += ""; vCode += ""; vCode += ""; vCode += ""; return vCode; } //----------------------------------------------------------------------------- /** * The days' name headers */ DatePickerControl.getDaysHeaderCode = function() { var vCode = ""; vCode = vCode + ""; if (this.weekNumber){ vCode += " " } for (i=this.firstWeekDay; i"; } vCode = vCode + ""; return vCode; } //----------------------------------------------------------------------------- /** * The days numbers code */ DatePickerControl.getDaysCode = function() { var vDate = new Date(); vDate.setDate(1); vDate.setMonth(this.month); vDate.setFullYear(this.year); var vFirstDay = vDate.getDay(); var vDay = 1; var vLastDay = this.getDaysOfMonth(this.month, this.year); var vOnLastDay = 0; var vCode = ""; this.dayOfWeek = vFirstDay; var prevm = this.month == 0 ? 11 : this.month-1; var prevy = this.prevm == 11 ? this.year - 1 : this.year; prevmontdays = this.getDaysOfMonth(prevm, prevy); vFirstDay = (vFirstDay == 0 && this.firstWeekDay) ? 7 : vFirstDay; if (this.weekNumber){ var week = this.getWeekNumber(this.year, this.month, 1); } vCode += ""; if (this.weekNumber){ vCode += "" + week + ""; } // Write the last days of previous month for (i=this.firstWeekDay; i" + (prevmontdays-vFirstDay+i+1) + ""; } // Write rest of the 1st week for (j=vFirstDay-this.firstWeekDay; j<7; j++) { if (this.isInRange(vDay)){ classname = this.getDayClass(vDay, j); vCode += "" + vDay + ""; } else{ vCode += "" + vDay + ""; } vDay++; } vCode = vCode + ""; // Write the rest of the weeks for (k=2; k<7; k++){ vCode = vCode + ""; if (this.weekNumber){ week++; if (week >= 53) week = 1; vCode += "" + week + ""; } for (j=0; j<7; j++){ if (this.isInRange(vDay)){ classname = this.getDayClass(vDay, j); vCode += "" + vDay + ""; } else{ vCode += "" + vDay + ""; } vDay++; if (vDay > vLastDay){ vOnLastDay = 1; break; } } if (j == 6) vCode += ""; if (vOnLastDay == 1) break; } // Fill up the rest of last week for (m=1; m<(7-j); m++){ vCode += "" + m + ""; } return vCode; } //----------------------------------------------------------------------------- /** * Get the class according if is 'today', the 'current' date at the control, * a 'weekend' day, or a 'normal' day. * @param vday The number of the day in the current month and year * @param dayofweek The number of the day within the week (0..6) */ DatePickerControl.getDayClass = function(vday, dayofweek) { var gNow = new Date(); var vNowDay = gNow.getDate(); var vNowMonth = gNow.getMonth(); var vNowYear = gNow.getFullYear(); if (vday == vNowDay && this.month == vNowMonth && this.year == vNowYear){ return "today"; } else{ // transform the day acording the specified firts day of week var realdayofweek = (7 + dayofweek + this.firstWeekDay) % 7; for (i=0; i=0 || strdate.indexOf("-")>=0 || strdate.indexOf(".")>=0) return aDate; // validate all other stuff var data = strdate.split("@"); if (data.length != 3) return aDate; for (i=0; i<3; i++){ data[i] = parseFloat(data[i]); if (isNaN(data[i])) return aDate; } aDate.setDate(1); if (format.substring(0,1).toUpperCase() == "D"){ aDate.setFullYear(this.yearTwo2Four(data[2])); aDate.setMonth(data[1]-1); aDate.setDate(data[0]); } else if (format.substring(0,1).toUpperCase() == "Y"){ aDate.setFullYear(this.yearTwo2Four(data[0])); aDate.setMonth(data[1]-1); aDate.setDate(data[2]); } else if (format.substring(0,1).toUpperCase() == "M"){ aDate.setFullYear(this.yearTwo2Four(data[2])); aDate.setMonth(data[0]-1); aDate.setDate(data[1]); } return aDate; } //----------------------------------------------------------------------------- /** * Transform a two digits year into a four digits year. * All year from 30 to 99 are trated as 19XX, year before * 30 are trated as 20XX */ DatePickerControl.yearTwo2Four = function(year) { if (year < 99){ if (year >= 30){ year += 1900; } else{ year += 2000; } } return year; } //----------------------------------------------------------------------------- /** * Writes the specified date in the control and close the calendar. */ DatePickerControl.writeDate = function(day) { var d = this.formatData(day); this.inputControl.value = d; this.originalValue = d; this.hide(); if (DatePickerControl.onSelect) DatePickerControl.onSelect(this.inputControl.id); this.firstFocused = true; this.inputControl.focus(); if (this.inputControl.id.indexOf("spec", 0)!=-1 ) { przejdzDoDnia(d); } this.inputControl.blur(); } //----------------------------------------------------------------------------- /** * Writes the current date in the control */ DatePickerControl.writeCurrentDate = function() { if(this.currentDay!="zostawpuste") { var d = this.formatData(this.currentDay); this.inputControl.value = d; } } //----------------------------------------------------------------------------- /** * Creates and write the calendar's code * @param m The month to build * @param y The year to build */ DatePickerControl.build = function(m, y) { var bkm = this.month; var bky = this.year; var calframe = document.getElementById(this.calFrameId); if (m==null){ var now = new Date(); this.month = now.getMonth(); this.year = now.getFullYear(); } else{ this.month = m; this.year = y; } // validate range if (!this.isInRange(null)){ this.month = bkm; this.year = bky; } if (!this.isInRange(this.currentDay)){ if (this.minDate && this.currentDay < this.minDate.getDate()) this.currentDay = this.minDate.getDate(); if (this.maxDate && this.currentDay > this.maxDate.getDate()) this.currentDay = this.maxDate.getDate(); } this.monthName = this.Months[this.month]; var code = this.getAllCode(); writeLayer(this.calContainer.id, null, code); if (this.calContainer && calframe) this.calContainer.style.height = calframe.offsetHeight; this.firstFocused = true; this.inputControl.focus(); this.selectDay(this.currentDay); } //----------------------------------------------------------------------------- /** * Build the prev month calendar */ DatePickerControl.buildPrev = function() { if (!this.displayed) return; var prevMMYYYY = this.calcMonthYear(this.month, this.year, -1); var prevMM = prevMMYYYY[0]; var prevYYYY = prevMMYYYY[1]; this.build(prevMM, prevYYYY); } //----------------------------------------------------------------------------- /** * Build the next month calendar */ DatePickerControl.buildNext = function() { if (!this.displayed) return; var nextMMYYYY = this.calcMonthYear(this.month, this.year, 1); var nextMM = nextMMYYYY[0]; var nextYYYY = nextMMYYYY[1]; this.build(nextMM, nextYYYY); } //----------------------------------------------------------------------------- /** * Today button action */ DatePickerControl.selectToday = function() { var now = new Date(); var today = now.getDate(); if (!this.isInRange(today)) return; if (this.closeOnTodayBtn){ this.currentDay = today; this.writeDate(this.currentDay); } else{ this.selectDay(today); } } //----------------------------------------------------------------------------- /** * Select a specific day */ DatePickerControl.selectDay = function(day) { if (!this.displayed) return; if (!this.isInRange(day)){ return; } var n = this.currentDay; var max = this.getDaysOfMonth(this.month, this.year); if (day > max) return; var newDayObject = document.getElementById(this.dayIdPrefix+day); var currentDayObject = document.getElementById(this.dayIdPrefix+this.currentDay); if (currentDayObject){ currentDayObject.className = currentDayObject.getAttribute("class_orig"); } if (newDayObject){ newDayObject.className = "current"; this.currentDay = day; this.writeCurrentDate(); } } //----------------------------------------------------------------------------- /** * Select the prev week day * @param decr Use 1 for yesterday or 7 for prev week */ DatePickerControl.selectPrevDay = function(decr) { if (!this.displayed) return; var n = this.currentDay; var max = this.getDaysOfMonth(this.month, this.year); var prev = n - decr; if ( prev <= 0 ){ if (decr == 7){ n = (n + this.dayOfWeek) + 28 - this.dayOfWeek; n--; prev = n > max ? n-7 : n; } else{ prev = max; } } this.selectDay(prev); } //----------------------------------------------------------------------------- /** * Select the next week day * @param decr Use 1 for tomorrow or 7 for next week */ DatePickerControl.selectNextDay = function(incr) { if (!this.displayed) return; var n = this.currentDay; var max = this.getDaysOfMonth(this.month, this.year); var next = n + incr; if ( next > max ){ if (incr == 7){ n = ((n + this.dayOfWeek) % 7) - this.dayOfWeek; next = n < 0 ? n+7 : n; next++; } else{ next = 1; } } this.selectDay(next); } //----------------------------------------------------------------------------- /** * Show the calendar for an edit control */ DatePickerControl.showForEdit = function(edit) { if (this.displayed) return; if (edit == null) return; if (edit.disabled) return; this.inputControl = edit; this.originalValue = edit.value; this.setupRange(); // the format var format = this.inputControl.getAttribute("datepicker_format"); if (format == null) format = this.defaultFormat; this.format = format; // build with the current date in the control? if (this.validate(edit.value, format)){ var date = this.getDateFromControl(); this.currentDate = date; this.build(date.getMonth(), date.getFullYear()); this.currentDay = date.getDate(); } else{ edit.value = ""; this.originalValue = ""; this.currentDate = null; if (this.defaultTodaySel){ this.currentDay = new Date().getDate(); } else{ this.currentDay = "zostawpuste"; } this.build(null, null); } var currentDayObject = document.getElementById(this.dayIdPrefix+this.currentDay); if (currentDayObject) currentDayObject.className = "current"; this.writeCurrentDate(); // and finally this.show(); } //----------------------------------------------------------------------------- /** * Determine if a given day (with current month and year) is in range * according to the min and max limit. * @param day The number of the day; if null then the current month is validated. */ DatePickerControl.isInRange = function(day) { if (!this.minDate && !this.maxDate) return true; if (day){ var aDate = new Date(); aDate.setFullYear(this.year); aDate.setMonth(this.month); aDate.setDate(day); if (this.minDate){ if (this.compareDates(aDate, this.minDate) < 0) return false; } if (this.maxDate){ if (this.compareDates(aDate, this.maxDate) > 0) return false; } } else{ // validate only the month. var currentym = parseInt(this.year.toString() + (this.month < 10 ? "0"+this.month.toString() : this.month.toString())); var m; if (this.minDate){ m = this.minDate.getMonth(); var minym = parseInt(this.minDate.getFullYear().toString() + (m < 10 ? "0"+m.toString() : m.toString())); if (currentym < minym) return false; } if (this.maxDate){ m = this.maxDate.getMonth(); var maxym = parseInt(this.maxDate.getFullYear().toString() + (m < 10 ? "0"+m.toString() : m.toString())); if (currentym > maxym) return false; } } return true; } //----------------------------------------------------------------------------- /** * */ DatePickerControl.setupRange = function() { // get the date range var edit = this.inputControl; var format = edit.getAttribute("datepicker_format"); var min = edit.getAttribute("datepicker_min"); this.minDate = min ? this.getDateFromString(min, format) : null; var max = edit.getAttribute("datepicker_max"); this.maxDate = max ? this.getDateFromString(max, format) : null; if (this.maxDate && this.minDate){ if (this.maxDate.getTime() < this.minDate.getTime()){ var tmp = this.maxDate; this.maxDate = this.minDate; this.minDate = tmp; } } } //----------------------------------------------------------------------------- /** * Compare two dates. We cannot use Date getTime() mehtod in some specific cases, * so we use a trick with the string year+month+day transformed in a number. * @return '<0' if d1 < d2 '0' if d1 = d2 '>0' if d1 > d2 */ DatePickerControl.compareDates = function(d1, d2) { var m = d1.getMonth(); var d = d1.getDate(); var s1 = d1.getFullYear().toString() + (m<10 ? "0"+m.toString() : m.toString()) + (d<10 ? "0"+d.toString() : d.toString()); m = d2.getMonth(); d = d2.getDate(); var s2 = d2.getFullYear().toString() + (m<10 ? "0"+m.toString() : m.toString()) + (d<10 ? "0"+d.toString() : d.toString()); var n1 = parseInt(s1); var n2 = parseInt(s2); return n1-n2; } //----------------------------------------------------------------------------- /** * Validate a string according to a date format. * Portions of code from: http://www.rgagnon.com/jsdetails/js-0063.html * @param strdate The string with the date. * @param format The format to validate. * @return true if succesfull or false otherwise */ DatePickerControl.validate = function(strdate, format) { var dateRegExp; var separator; var d, m, y; var od = this.currentDay, om = this.month, oy = this.year; if (strdate == "") return false; // use the correct regular expresion... if (format.substring(0,1).toUpperCase() == "D"){ dateRegExp = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{2,4}$/ } else if (format.substring(0,1).toUpperCase() == "Y"){ dateRegExp = /^\d{2,4}(\-|\/|\.)\d{1,2}\1\d{1,2}$/ } else if (format.substring(0,1).toUpperCase() == "M"){ dateRegExp = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{2,4}$/ } // is ok at least with the format? if (!dateRegExp.test(strdate)){ return false; } // chek for a valid day month day combination separator = (strdate.indexOf("/") > 1) ? "/" : ((strdate.indexOf("-") > 1) ? "-" : "."); var datearray = strdate.split(separator); // get the number of date elements if (format.substring(0,1).toUpperCase() == "D"){ d = parseFloat(datearray[0]); m = parseFloat(datearray[1]); y = parseFloat(datearray[2]); } else if (format.substring(0,1).toUpperCase() == "Y"){ d = parseFloat(datearray[2]); m = parseFloat(datearray[1]); y = parseFloat(datearray[0]); } else if (format.substring(0,1).toUpperCase() == "M"){ d = parseFloat(datearray[1]); m = parseFloat(datearray[0]); y = parseFloat(datearray[2]); } // is a valid month? if (m<1 || m>12) return false; //check if month value and day value agree if (d > this.getDaysOfMonth(m-1, y)) return false; // ok, date is valid... but is it in range? this.month = m; this.year = y; var res = this.isInRange(d); this.month = om; this.year = oy; return res; } //----------------------------------------------------------------------------- /** * Check if a year is leap: * 1.Years evenly divisible by four are normally leap years, except for... * 2.Years also evenly divisible by 100 are not leap years, except for... * 3.Years also evenly divisible by 400 are leap years. * @return true if the year is leap or false otherwise. */ DatePickerControl.isLeapYear = function(year) { if ((year % 4) == 0){ if ((year % 100) == 0 && (year % 400) != 0){ return false; } return true; } return false; } //----------------------------------------------------------------------------- /** * Click event for calendar button */ function DPC_onButtonClick(event){DatePickerControl.onButtonClick(event);} DatePickerControl.onButtonClick = function(event) { if (!this.displayed){ // get the button if (event == null) event = window.event; var button = (event.srcElement) ? event.srcElement : event.originalTarget; // gets the associated input: var input = document.getElementById(button.getAttribute("datepicker_inputid")); this.showForEdit(input); } else{ this.hide(); } } //----------------------------------------------------------------------------- /** * Click event for calendar layer. */ function DPC_onContainerClick(event){DatePickerControl.onContainerClick(event);} DatePickerControl.onContainerClick = function(event) { if (event == null) event = window.event; if (this.hideTimeout){ clearTimeout(this.hideTimeout); this.hideTimeout = null; } this.inputControl.focus(); return false; } //----------------------------------------------------------------------------- /** * Key-up event for edit controls as date-pickers */ function DPC_onEditControlKeyUp(event){DatePickerControl.onEditControlKeyUp(event);} DatePickerControl.onEditControlKeyUp = function(event) { if (event == null) event = window.event; var edit = event.srcElement ? event.srcElement : event.originalTarget; var kc = event.charCode ? event.charCode : event.which ? event.which : event.keyCode; //alert(event.keyCode); switch (kc){ case 37: // left arrow key this.selectPrevDay(1); break; case 38: // up arrow key this.selectPrevDay(7); break; case 39: // right arrow key this.selectNextDay(1); break; case 40: // down arrow key if (!this.displayed){ this.showForEdit(edit); } else{ this.selectNextDay(7); break; } break; case 27: // escape key this.hide(); break; case 33: // repag key if ((event.modifiers & Event.SHIFT_MASK) || (event.shiftKey)){ this.build(this.month, parseInt(this.year)-1); } else{ this.buildPrev(); } break; case 34: // avpag key if ((event.modifiers & Event.SHIFT_MASK) || (event.shiftKey)){ this.build(this.month, parseInt(this.year)+1); } else{ this.buildNext(); } break; case 13: // enter-key (forms without submit buttons) if (this.displayed && this.currentDay > 0 && this.submitByKey){ this.writeDate(this.currentDay); } break; } return false; } //----------------------------------------------------------------------------- /** * Key-down event for edit controls as date-pickers */ function DPC_onEditControlKeyDown(event){DatePickerControl.onEditControlKeyDown(event);} DatePickerControl.onEditControlKeyDown = function(event) { if (event == null) event = window.event; var edit = event.srcElement ? event.srcElement : event.originalTarget; var kc = event.charCode ? event.charCode : event.which ? event.which : event.keyCode; //alert(event.keyCode); if ( kc >= 65 && kc <= 90 ){ // letters if (event.stopPropagation) event.stopPropagation(); if (event.preventDefault) event.preventDefault(); event.returnValue = false; event.cancelBubble = true; return false; } switch (kc){ case 13: // enter key this.submitByKey = true; break; case 9: // tab key case 32: // space-bar key if (this.displayed && this.currentDay > 0){ this.writeDate(this.currentDay); } break; } } //----------------------------------------------------------------------------- /** * Key-press event for edit controls as date-pickers */ function DPC_onEditControlKeyPress(event){DatePickerControl.onEditControlKeyPress(event);} DatePickerControl.onEditControlKeyPress = function(event) { if (event == null) event = window.event; var edit = event.srcElement ? event.srcElement : event.originalTarget; var kc = event.charCode ? event.charCode : event.which ? event.which : event.keyCode; if (!((kc < 32) || (kc > 44 && kc < 58))){ if (event.stopPropagation) event.stopPropagation(); if (event.preventDefault) event.preventDefault(); event.returnValue = false; event.cancelBubble = true; return false; } } //----------------------------------------------------------------------------- /** * Blur event for edit controls as date-pickers */ function DPC_onEditControlBlur(event){DatePickerControl.onEditControlBlur(event);} DatePickerControl.onEditControlBlur = function(event) { if (event == null) event = window.event; if (!this.hideTimeout){ this.hideTimeout = setTimeout("DatePickerControl.hide()", this.HIDE_TIMEOUT); } this.firstFocused = false; this.hideCauseBlur = true; } //----------------------------------------------------------------------------- /** * Change event for edit controls as date-pickers */ function DPC_onEditControlChange(event){DatePickerControl.onEditControlChange(event);} DatePickerControl.onEditControlChange = function(event) { if (event == null) event = window.event; var edit = (event.srcElement) ? event.srcElement : event.originalTarget; if (edit.value == "") return; var format = edit.getAttribute("datepicker_format"); if (!this.validate(edit.value, format)){ setTimeout("e = document.getElementById('"+edit.id+"'); e.value=''; e.focus()", 10); } } //----------------------------------------------------------------------------- /** * Focus event for edit controls as date-pickers */ function DPC_onEditControlFocus(event){DatePickerControl.onEditControlFocus(event);} DatePickerControl.onEditControlFocus = function(event) { if (event == null) event = window.event; var edit = (event.srcElement) ? event.srcElement : event.originalTarget; this.inputControl = edit; this.originalValue = edit.value; this.setupRange(); if ((!this.displayed || this.hideCauseBlur) && this.autoShow && !this.firstFocused){ clearTimeout(this.hideTimeout); this.hideTimeout = null; this.firstFocused = true; if (this.hideCauseBlur){ this.hideCauseBlur = false; this.hide(); } this.showForEdit(edit); } else if (this.inputControl && this.inputControl.id != edit.id){ this.hide(); } else if (this.hideTimeout){ clearTimeout(this.hideTimeout); this.hideTimeout = null; } } //----------------------------------------------------------------------------- /** * Form's submit event */ function DPC_onFormSubmit(event){DatePickerControl.onFormSubmit(event);} DatePickerControl.onFormSubmit = function(event) { if (this.submitByKey){ this.submitByKey = false; if (this.displayed && this.currentDay > 0){ this.writeDate(this.currentDay); if (event == null) event = window.event; var theForm = (event.srcElement) ? event.srcElement : event.originalTarget; if (event.stopPropagation) event.stopPropagation(); if (event.preventDefault) event.preventDefault(); event.returnValue = false; event.cancelBubble = true; return false; } } this.reformatOnSubmit(); } //----------------------------------------------------------------------------- /** * Reformat all dates to the current onSubmit date format */ DatePickerControl.reformatOnSubmit = function() { if (this.submitFormat == "") return true; var inputControls = document.getElementsByTagName("input"); var inputsLength = inputControls.length; var i; for (i=0; i= 0){ res = res.replace("YYYY", thedate.getFullYear()); } else{ res = res.replace("YY", thedate.getFullYear()); } editctrl.value = res; } } } return true; } //----------------------------------------------------------------------------- /** * Replacement for submit method of the form. */ function DPC_formSubmit() { var res = DatePickerControl.reformatOnSubmit(); if (this.submitOrig){ res = this.submitOrig(); } return res; } //----------------------------------------------------------------------------- /** * Window resize event. */ function DPC_onWindowResize(event){DatePickerControl.onWindowResize(event);} DatePickerControl.onWindowResize = function(event) { this.relocate(); //this.relocateButtons(); } //----------------------------------------------------------------------------- /** * Relocate buttons */ DatePickerControl.relocateButtons = function() { return; var divElements = document.getElementsByTagName("div"); for (key in divElements){ if (divElements[key].id && divElements[key].id.indexOf(this.buttonIdPrefix) == 0){ var calButton = divElements[key]; if (calButton.style.display == 'none') continue; var input = document.getElementById(calButton.getAttribute("datepicker_inputid")); if (input.style.display == 'none' || input.offsetTop == 0) continue; var nTop = getObject.getSize("offsetTop", input); var nLeft = getObject.getSize("offsetLeft", input); calButton.style.top = (nTop + Math.floor((input.offsetHeight-calButton.offsetHeight)/2) + this.buttonOffsetY) + "px"; var btnOffX = Math.floor((input.offsetHeight - calButton.offsetHeight) / 2); if (this.buttonPosition == "in"){ calButton.style.left = (nLeft + input.offsetWidth - calButton.offsetWidth - btnOffX + this.buttonOffsetX) + "px"; } else{ // "out" calButton.style.left = (nLeft + input.offsetWidth + btnOffX + this.buttonOffsetX) + "px"; } } } } //----------------------------------------------------------------------------- /** * Relocate the calendar's frame */ DatePickerControl.relocate = function() { if (this.displayed){ var input = this.inputControl; if (input == null) return; var top = getObject.getSize("offsetTop", input); var left = getObject.getSize("offsetLeft", input); this.calContainer.style.top = top + input.offsetHeight + this.offsetY + "px"; this.calContainer.style.left = left + this.offsetX + "px"; if (this.calBG){ // the ugly patch for IE this.calBG.style.top = this.calContainer.style.top; this.calBG.style.left = this.calContainer.style.left; } } } //----------------------------------------------------------------------------- /** * Gets the number of the week on the year for the given year, month, day. */ DatePickerControl.getWeekNumber = function(year, month, day) { var when = new Date(year,month,day); var newYear = new Date(year,0,1); var offset = 7 + 1 - newYear.getDay(); if (offset == 8) offset = 1; var daynum = ((Date.UTC(y2k(year),when.getMonth(),when.getDate(),0,0,0) - Date.UTC(y2k(year),0,1,0,0,0)) /1000/60/60/24) + 1; var weeknum = Math.floor((daynum-offset+7)/7); if (weeknum == 0) { year--; var prevNewYear = new Date(year,0,1); var prevOffset = 7 + 1 - prevNewYear.getDay(); if (prevOffset == 2 || prevOffset == 8) weeknum = 53; else weeknum = 52; } return weeknum; } function y2k(number) { return (number < 1000) ? number + 1900 : number; } //----------------------------------------------------------------------------- // Following 2 functions by: Mircho Mirev function getObject(sId) { if (bw.dom){ this.hElement = document.getElementById(sId); this.hStyle = this.hElement.style; } else if (bw.ns4){ this.hElement = document.layers[sId]; this.hStyle = this.hElement; } else if (bw.ie){ this.hElement = document.all[sId]; this.hStyle = this.hElement.style; } } getObject.getSize = function(sParam, hLayer) { nPos = 0; while ((hLayer.tagName) && !( /(body|html)/i.test(hLayer.tagName))){ nPos += eval('hLayer.' + sParam); if (sParam == 'offsetTop'){ if (hLayer.clientTop){ nPos += hLayer.clientTop; } } if (sParam == 'offsetLeft'){ if (hLayer.clientLeft){ nPos += hLayer.clientLeft; } } hLayer = hLayer.offsetParent; } return nPos; } //----------------------------------------------------------------------------- /** * Based on code by: Peter Todorov */ function writeLayer(ID, parentID, sText) { if (document.layers){ var oLayer; if(parentID){ oLayer = eval('document.' + parentID + '.document.' + ID + '.document'); } else{ oLayer = document.layers[ID].document; } oLayer.open(); oLayer.write(sText); oLayer.close(); } else if(document.all){ document.all[ID].innerHTML = sText; } else{ document.getElementById(ID).innerHTML = sText; } } //-------------------------------------------------------------- // function przejdzDoDnia(data) { var dataformatted = new Date(data); document.getElementById("wybranaData").value = konwerujDate(data); document.getElementById("wybierzDate").submit(); } function konwerujDate(data){ var yyyyMMdd = /^\d{4}-\d{2}-\d{2}$/; var ddMMyyyy = /^\d{2}-\d{2}-\d{4}$/; if(data.match(yyyyMMdd)){ return data; } else if(data.match(ddMMyyyy)){ return data.substring(6,10)+"-"+data.substring(3,5)+"-"+data.substring(0,2) } return "invalid format"; } // Compartir es la ďż˝nica manera de perdurar // EOF /*! * jQuery JavaScript Library v1.3.2 * http://jquery.com/ * * Copyright (c) 2009 John Resig * Dual licensed under the MIT and GPL licenses. * http://docs.jquery.com/License * * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) * Revision: 6246 */ (function(){ var // Will speed up references to window, and allows munging its name. window = this, // Will speed up references to undefined, and allows munging its name. undefined, // Map over jQuery in case of overwrite _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$, jQuery = window.jQuery = window.$ = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context ); }, // A simple way to check for HTML strings or ID strings // (both of which we optimize for) quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/, // Is it a simple selector isSimple = /^.[^:#\[\.,]*$/; jQuery.fn = jQuery.prototype = { init: function( selector, context ) { // Make sure that a selection was provided selector = selector || document; // Handle $(DOMElement) if ( selector.nodeType ) { this[0] = selector; this.length = 1; this.context = selector; return this; } // Handle HTML strings if ( typeof selector === "string" ) { // Are we dealing with HTML string or an ID? var match = quickExpr.exec( selector ); // Verify a match, and that no context was specified for #id if ( match && (match[1] || !context) ) { // HANDLE: $(html) -> $(array) if ( match[1] ) selector = jQuery.clean( [ match[1] ], context ); // HANDLE: $("#id") else { var elem = document.getElementById( match[3] ); // Handle the case where IE and Opera return items // by name instead of ID if ( elem && elem.id != match[3] ) return jQuery().find( selector ); // Otherwise, we inject the element directly into the jQuery object var ret = jQuery( elem || [] ); ret.context = document; ret.selector = selector; return ret; } // HANDLE: $(expr, [context]) // (which is just equivalent to: $(content).find(expr) } else return jQuery( context ).find( selector ); // HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) return jQuery( document ).ready( selector ); // Make sure that old selector state is passed along if ( selector.selector && selector.context ) { this.selector = selector.selector; this.context = selector.context; } return this.setArray(jQuery.isArray( selector ) ? selector : jQuery.makeArray(selector)); }, // Start with an empty selector selector: "", // The current version of jQuery being used jquery: "1.3.2", // The number of elements contained in the matched element set size: function() { return this.length; }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { return num === undefined ? // Return a 'clean' array Array.prototype.slice.call( this ) : // Return just the object this[ num ]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems, name, selector ) { // Build a new jQuery matched element set var ret = jQuery( elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; ret.context = this.context; if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector; else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")"; // Return the newly-formed element set return ret; }, // Force the current matched set of elements to become // the specified array of elements (destroying the stack in the process) // You should use pushStack() in order to do this, but maintain the stack setArray: function( elems ) { // Resetting the length to 0, then using the native Array push // is a super-fast way to populate an object with array-like properties this.length = 0; Array.prototype.push.apply( this, elems ); return this; }, // Execute a callback for every element in the matched set. // (You can seed the arguments with an array of args, but this is // only used internally.) each: function( callback, args ) { return jQuery.each( this, callback, args ); }, // Determine the position of an element within // the matched set of elements index: function( elem ) { // Locate the position of the desired element return jQuery.inArray( // If it receives a jQuery object, the first element is used elem && elem.jquery ? elem[0] : elem , this ); }, attr: function( name, value, type ) { var options = name; // Look for the case where we're accessing a style value if ( typeof name === "string" ) if ( value === undefined ) return this[0] && jQuery[ type || "attr" ]( this[0], name ); else { options = {}; options[ name ] = value; } // Check to see if we're setting style values return this.each(function(i){ // Set all the styles for ( name in options ) jQuery.attr( type ? this.style : this, name, jQuery.prop( this, options[ name ], type, i, name ) ); }); }, css: function( key, value ) { // ignore negative width and height values if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) value = undefined; return this.attr( key, value, "curCSS" ); }, text: function( text ) { if ( typeof text !== "object" && text != null ) return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); var ret = ""; jQuery.each( text || this, function(){ jQuery.each( this.childNodes, function(){ if ( this.nodeType != 8 ) ret += this.nodeType != 1 ? this.nodeValue : jQuery.fn.text( [ this ] ); }); }); return ret; }, wrapAll: function( html ) { if ( this[0] ) { // The elements to wrap the target around var wrap = jQuery( html, this[0].ownerDocument ).clone(); if ( this[0].parentNode ) wrap.insertBefore( this[0] ); wrap.map(function(){ var elem = this; while ( elem.firstChild ) elem = elem.firstChild; return elem; }).append(this); } return this; }, wrapInner: function( html ) { return this.each(function(){ jQuery( this ).contents().wrapAll( html ); }); }, wrap: function( html ) { return this.each(function(){ jQuery( this ).wrapAll( html ); }); }, append: function() { return this.domManip(arguments, true, function(elem){ if (this.nodeType == 1) this.appendChild( elem ); }); }, prepend: function() { return this.domManip(arguments, true, function(elem){ if (this.nodeType == 1) this.insertBefore( elem, this.firstChild ); }); }, before: function() { return this.domManip(arguments, false, function(elem){ this.parentNode.insertBefore( elem, this ); }); }, after: function() { return this.domManip(arguments, false, function(elem){ this.parentNode.insertBefore( elem, this.nextSibling ); }); }, end: function() { return this.prevObject || jQuery( [] ); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: [].push, sort: [].sort, splice: [].splice, find: function( selector ) { if ( this.length === 1 ) { var ret = this.pushStack( [], "find", selector ); ret.length = 0; jQuery.find( selector, this[0], ret ); return ret; } else { return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){ return jQuery.find( selector, elem ); })), "find", selector ); } }, clone: function( events ) { // Do the clone var ret = this.map(function(){ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { // IE copies events bound via attachEvent when // using cloneNode. Calling detachEvent on the // clone will also remove the events from the orignal // In order to get around this, we use innerHTML. // Unfortunately, this means some modifications to // attributes in IE that are actually only stored // as properties will not be copied (such as the // the name attribute on an input). var html = this.outerHTML; if ( !html ) { var div = this.ownerDocument.createElement("div"); div.appendChild( this.cloneNode(true) ); html = div.innerHTML; } return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0]; } else return this.cloneNode(true); }); // Copy the events from the original to the clone if ( events === true ) { var orig = this.find("*").andSelf(), i = 0; ret.find("*").andSelf().each(function(){ if ( this.nodeName !== orig[i].nodeName ) return; var events = jQuery.data( orig[i], "events" ); for ( var type in events ) { for ( var handler in events[ type ] ) { jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); } } i++; }); } // Return the cloned set return ret; }, filter: function( selector ) { return this.pushStack( jQuery.isFunction( selector ) && jQuery.grep(this, function(elem, i){ return selector.call( elem, i ); }) || jQuery.multiFilter( selector, jQuery.grep(this, function(elem){ return elem.nodeType === 1; }) ), "filter", selector ); }, closest: function( selector ) { var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null, closer = 0; return this.map(function(){ var cur = this; while ( cur && cur.ownerDocument ) { if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) { jQuery.data(cur, "closest", closer); return cur; } cur = cur.parentNode; closer++; } }); }, not: function( selector ) { if ( typeof selector === "string" ) // test special case where just one selector is passed in if ( isSimple.test( selector ) ) return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector ); else selector = jQuery.multiFilter( selector, this ); var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; return this.filter(function() { return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; }); }, add: function( selector ) { return this.pushStack( jQuery.unique( jQuery.merge( this.get(), typeof selector === "string" ? jQuery( selector ) : jQuery.makeArray( selector ) ))); }, is: function( selector ) { return !!selector && jQuery.multiFilter( selector, this ).length > 0; }, hasClass: function( selector ) { return !!selector && this.is( "." + selector ); }, val: function( value ) { if ( value === undefined ) { var elem = this[0]; if ( elem ) { if( jQuery.nodeName( elem, 'option' ) ) return (elem.attributes.value || {}).specified ? elem.value : elem.text; // We need to handle select boxes special if ( jQuery.nodeName( elem, "select" ) ) { var index = elem.selectedIndex, values = [], options = elem.options, one = elem.type == "select-one"; // Nothing was selected if ( index < 0 ) return null; // Loop through all the selected options for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { var option = options[ i ]; if ( option.selected ) { // Get the specifc value for the option value = jQuery(option).val(); // We don't need an array for one selects if ( one ) return value; // Multi-Selects return an array values.push( value ); } } return values; } // Everything else, we just grab the value return (elem.value || "").replace(/\r/g, ""); } return undefined; } if ( typeof value === "number" ) value += ''; return this.each(function(){ if ( this.nodeType != 1 ) return; if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) ) this.checked = (jQuery.inArray(this.value, value) >= 0 || jQuery.inArray(this.name, value) >= 0); else if ( jQuery.nodeName( this, "select" ) ) { var values = jQuery.makeArray(value); jQuery( "option", this ).each(function(){ this.selected = (jQuery.inArray( this.value, values ) >= 0 || jQuery.inArray( this.text, values ) >= 0); }); if ( !values.length ) this.selectedIndex = -1; } else this.value = value; }); }, html: function( value ) { return value === undefined ? (this[0] ? this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") : null) : this.empty().append( value ); }, replaceWith: function( value ) { return this.after( value ).remove(); }, eq: function( i ) { return this.slice( i, +i + 1 ); }, slice: function() { return this.pushStack( Array.prototype.slice.apply( this, arguments ), "slice", Array.prototype.slice.call(arguments).join(",") ); }, map: function( callback ) { return this.pushStack( jQuery.map(this, function(elem, i){ return callback.call( elem, i, elem ); })); }, andSelf: function() { return this.add( this.prevObject ); }, domManip: function( args, table, callback ) { if ( this[0] ) { var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), first = fragment.firstChild; if ( first ) for ( var i = 0, l = this.length; i < l; i++ ) callback.call( root(this[i], first), this.length > 1 || i > 0 ? fragment.cloneNode(true) : fragment ); if ( scripts ) jQuery.each( scripts, evalScript ); } return this; function root( elem, cur ) { return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ? (elem.getElementsByTagName("tbody")[0] || elem.appendChild(elem.ownerDocument.createElement("tbody"))) : elem; } } }; // Give the init function the jQuery prototype for later instantiation jQuery.fn.init.prototype = jQuery.fn; function evalScript( i, elem ) { if ( elem.src ) jQuery.ajax({ url: elem.src, async: false, dataType: "script" }); else jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); if ( elem.parentNode ) elem.parentNode.removeChild( elem ); } function now(){ return +new Date; } jQuery.extend = jQuery.fn.extend = function() { // copy reference to target object var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction(target) ) target = {}; // extend jQuery itself if only one argument is passed if ( length == i ) { target = this; --i; } for ( ; i < length; i++ ) // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) // Extend the base object for ( var name in options ) { var src = target[ name ], copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) continue; // Recurse if we're merging object values if ( deep && copy && typeof copy === "object" && !copy.nodeType ) target[ name ] = jQuery.extend( deep, // Never move original objects, clone them src || ( copy.length != null ? [ ] : { } ) , copy ); // Don't bring in undefined values else if ( copy !== undefined ) target[ name ] = copy; } // Return the modified object return target; }; // exclude the following css properties to add px var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, // cache defaultView defaultView = document.defaultView || {}, toString = Object.prototype.toString; jQuery.extend({ noConflict: function( deep ) { window.$ = _$; if ( deep ) window.jQuery = _jQuery; return jQuery; }, // See test/unit/core.js for details concerning isFunction. // Since version 1.3, DOM methods and functions like alert // aren't supported. They return false on IE (#2968). isFunction: function( obj ) { return toString.call(obj) === "[object Function]"; }, isArray: function( obj ) { return toString.call(obj) === "[object Array]"; }, // check if an element is in a (or is an) XML document isXMLDoc: function( elem ) { return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument ); }, // Evalulates a script in a global context globalEval: function( data ) { if ( data && /\S/.test(data) ) { // Inspired by code by Andrea Giammarchi // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html var head = document.getElementsByTagName("head")[0] || document.documentElement, script = document.createElement("script"); script.type = "text/javascript"; if ( jQuery.support.scriptEval ) script.appendChild( document.createTextNode( data ) ); else script.text = data; // Use insertBefore instead of appendChild to circumvent an IE6 bug. // This arises when a base node is used (#2709). head.insertBefore( script, head.firstChild ); head.removeChild( script ); } }, nodeName: function( elem, name ) { return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); }, // args is for internal usage only each: function( object, callback, args ) { var name, i = 0, length = object.length; if ( args ) { if ( length === undefined ) { for ( name in object ) if ( callback.apply( object[ name ], args ) === false ) break; } else for ( ; i < length; ) if ( callback.apply( object[ i++ ], args ) === false ) break; // A special, fast, case for the most common use of each } else { if ( length === undefined ) { for ( name in object ) if ( callback.call( object[ name ], name, object[ name ] ) === false ) break; } else for ( var value = object[0]; i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} } return object; }, prop: function( elem, value, type, i, name ) { // Handle executable functions if ( jQuery.isFunction( value ) ) value = value.call( elem, i ); // Handle passing in a number to a CSS property return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ? value + "px" : value; }, className: { // internal only, use addClass("class") add: function( elem, classNames ) { jQuery.each((classNames || "").split(/\s+/), function(i, className){ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) elem.className += (elem.className ? " " : "") + className; }); }, // internal only, use removeClass("class") remove: function( elem, classNames ) { if (elem.nodeType == 1) elem.className = classNames !== undefined ? jQuery.grep(elem.className.split(/\s+/), function(className){ return !jQuery.className.has( classNames, className ); }).join(" ") : ""; }, // internal only, use hasClass("class") has: function( elem, className ) { return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; } }, // A method for quickly swapping in/out CSS properties to get correct calculations swap: function( elem, options, callback ) { var old = {}; // Remember the old values, and insert the new ones for ( var name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } callback.call( elem ); // Revert the old values for ( var name in options ) elem.style[ name ] = old[ name ]; }, css: function( elem, name, force, extra ) { if ( name == "width" || name == "height" ) { var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; function getWH() { val = name == "width" ? elem.offsetWidth : elem.offsetHeight; if ( extra === "border" ) return; jQuery.each( which, function() { if ( !extra ) val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; if ( extra === "margin" ) val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0; else val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; }); } if ( elem.offsetWidth !== 0 ) getWH(); else jQuery.swap( elem, props, getWH ); return Math.max(0, Math.round(val)); } return jQuery.curCSS( elem, name, force ); }, curCSS: function( elem, name, force ) { var ret, style = elem.style; // We need to handle opacity special in IE if ( name == "opacity" && !jQuery.support.opacity ) { ret = jQuery.attr( style, "opacity" ); return ret == "" ? "1" : ret; } // Make sure we're using the right name for getting the float value if ( name.match( /float/i ) ) name = styleFloat; if ( !force && style && style[ name ] ) ret = style[ name ]; else if ( defaultView.getComputedStyle ) { // Only "float" is needed here if ( name.match( /float/i ) ) name = "float"; name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); var computedStyle = defaultView.getComputedStyle( elem, null ); if ( computedStyle ) ret = computedStyle.getPropertyValue( name ); // We should always get a number back from opacity if ( name == "opacity" && ret == "" ) ret = "1"; } else if ( elem.currentStyle ) { var camelCase = name.replace(/\-(\w)/g, function(all, letter){ return letter.toUpperCase(); }); ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; // From the awesome hack by Dean Edwards // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 // If we're not dealing with a regular pixel number // but a number that has a weird ending, we need to convert it to pixels if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { // Remember the original values var left = style.left, rsLeft = elem.runtimeStyle.left; // Put in the new values to get a computed value out elem.runtimeStyle.left = elem.currentStyle.left; style.left = ret || 0; ret = style.pixelLeft + "px"; // Revert the changed values style.left = left; elem.runtimeStyle.left = rsLeft; } } return ret; }, clean: function( elems, context, fragment ) { context = context || document; // !context.createElement fails in IE with an error but returns typeof 'object' if ( typeof context.createElement === "undefined" ) context = context.ownerDocument || context[0] && context[0].ownerDocument || document; // If a single string is passed in and it's a single tag // just do a createElement and skip the rest if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) { var match = /^<(\w+)\s*\/?>$/.exec(elems[0]); if ( match ) return [ context.createElement( match[1] ) ]; } var ret = [], scripts = [], div = context.createElement("div"); jQuery.each(elems, function(i, elem){ if ( typeof elem === "number" ) elem += ''; if ( !elem ) return; // Convert html string into DOM nodes if ( typeof elem === "string" ) { // Fix "XHTML"-style tags in all browsers elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? all : front + ">"; }); // Trim whitespace, otherwise indexOf won't work as expected var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase(); var wrap = // option or optgroup !tags.indexOf("", "" ] || !tags.indexOf("", "" ] || tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && [ 1, "", "
" ] || !tags.indexOf("", "" ] || // matched above (!tags.indexOf("", "" ] || !tags.indexOf("", "" ] || // IE can't serialize and