Changeset 12525 for trunk/themes/default/js/ui/jquery.ui.datepicker.js
- Timestamp:
- Oct 28, 2011, 3:25:54 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/themes/default/js/ui/jquery.ui.datepicker.js
r9559 r12525 1 1 /* 2 * jQuery UI Datepicker 1.8.1 02 * jQuery UI Datepicker 1.8.16 3 3 * 4 4 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) … … 13 13 (function( $, undefined ) { 14 14 15 $.extend($.ui, { datepicker: { version: "1.8.1 0" } });15 $.extend($.ui, { datepicker: { version: "1.8.16" } }); 16 16 17 17 var PROP_NAME = 'datepicker'; 18 18 var dpuuid = new Date().getTime(); 19 var instActive; 19 20 20 21 /* Date picker manager. … … 105 106 constrainInput: true, // The input is constrained by the current date format 106 107 showButtonPanel: false, // True to show button panel, false to not show it 107 autoSize: false // True to size the input for the date format, false to leave as is 108 autoSize: false, // True to size the input for the date format, false to leave as is 109 disabled: false // The initial disabled state 108 110 }; 109 111 $.extend(this._defaults, this.regional['']); 110 this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>');112 this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')); 111 113 } 112 114 … … 114 116 /* Class name added to elements to indicate already configured with a date picker. */ 115 117 markerClassName: 'hasDatepicker', 118 119 //Keep track of the maximum number of rows displayed (see #7043) 120 maxRows: 4, 116 121 117 122 /* Debug logging (if enabled). */ … … 174 179 inline: inline, // is datepicker inline or not 175 180 dpDiv: (!inline ? this.dpDiv : // presentation div 176 $('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))};181 bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))}; 177 182 }, 178 183 … … 194 199 this._autoSize(inst); 195 200 $.data(target, PROP_NAME, inst); 201 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 202 if( inst.settings.disabled ) { 203 this._disableDatepicker( target ); 204 } 196 205 }, 197 206 … … 273 282 this._updateDatepicker(inst); 274 283 this._updateAlternate(inst); 275 inst.dpDiv.show(); 284 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 285 if( inst.settings.disabled ) { 286 this._disableDatepicker( target ); 287 } 288 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 289 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 290 inst.dpDiv.css( "display", "block" ); 276 291 }, 277 292 … … 364 379 var inline = $target.children('.' + this._inlineClass); 365 380 inline.children().removeClass('ui-state-disabled'); 381 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 382 removeAttr("disabled"); 366 383 } 367 384 this._disabledInputs = $.map(this._disabledInputs, … … 387 404 var inline = $target.children('.' + this._inlineClass); 388 405 inline.children().addClass('ui-state-disabled'); 406 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). 407 attr("disabled", "disabled"); 389 408 } 390 409 this._disabledInputs = $.map(this._disabledInputs, … … 445 464 } 446 465 var date = this._getDateDatepicker(target, true); 466 var minDate = this._getMinMaxDate(inst, 'min'); 467 var maxDate = this._getMinMaxDate(inst, 'max'); 447 468 extendRemove(inst.settings, settings); 469 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 470 if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined) 471 inst.settings.minDate = this._formatDate(inst, minDate); 472 if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined) 473 inst.settings.maxDate = this._formatDate(inst, maxDate); 448 474 this._attachments($(target), inst); 449 475 this._autoSize(inst); 450 this._setDateDatepicker(target, date); 476 this._setDate(inst, date); 477 this._updateAlternate(inst); 451 478 this._updateDatepicker(inst); 452 479 } … … 505 532 if (sel[0]) 506 533 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); 534 var onSelect = $.datepicker._get(inst, 'onSelect'); 535 if (onSelect) { 536 var dateStr = $.datepicker._formatDate(inst); 537 538 // trigger custom callback 539 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); 540 } 507 541 else 508 542 $.datepicker._hideDatepicker(); … … 592 626 593 627 /* Pop-up the date picker for a given input field. 628 If false returned from beforeShow event handler do not show. 594 629 @param input element - the input field attached to the date picker or 595 630 event - if triggered by focus */ … … 602 637 var inst = $.datepicker._getInst(input); 603 638 if ($.datepicker._curInst && $.datepicker._curInst != inst) { 639 if ( $.datepicker._datepickerShowing ) { 640 $.datepicker._triggerOnClose($.datepicker._curInst); 641 } 604 642 $.datepicker._curInst.dpDiv.stop(true, true); 605 643 } 606 644 var beforeShow = $.datepicker._get(inst, 'beforeShow'); 607 extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {})); 645 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; 646 if(beforeShowSettings === false){ 647 //false 648 return; 649 } 650 extendRemove(inst.settings, beforeShowSettings); 608 651 inst.lastVal = null; 609 652 $.datepicker._lastInput = input; … … 641 684 var duration = $.datepicker._get(inst, 'duration'); 642 685 var postProcess = function() { 643 $.datepicker._datepickerShowing = true;644 686 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only 645 687 if( !! cover.length ){ … … 650 692 }; 651 693 inst.dpDiv.zIndex($(input).zIndex()+1); 694 $.datepicker._datepickerShowing = true; 652 695 if ($.effects && $.effects[showAnim]) 653 696 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); … … 665 708 _updateDatepicker: function(inst) { 666 709 var self = this; 710 self.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 667 711 var borders = $.datepicker._getBorders(inst.dpDiv); 712 instActive = inst; // for delegate hover events 668 713 inst.dpDiv.empty().append(this._generateHTML(inst)); 669 714 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only … … 671 716 cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) 672 717 } 673 inst.dpDiv.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a') 674 .bind('mouseout', function(){ 675 $(this).removeClass('ui-state-hover'); 676 if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); 677 if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); 678 }) 679 .bind('mouseover', function(){ 680 if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) { 681 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); 682 $(this).addClass('ui-state-hover'); 683 if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); 684 if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover'); 685 } 686 }) 687 .end() 688 .find('.' + this._dayOverClass + ' a') 689 .trigger('mouseover') 690 .end(); 718 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover(); 691 719 var numMonths = this._getNumberOfMonths(inst); 692 720 var cols = numMonths[1]; 693 721 var width = 17; 722 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); 694 723 if (cols > 1) 695 724 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); 696 else697 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');698 725 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + 699 726 'Class']('ui-datepicker-multi'); … … 710 737 setTimeout(function(){ 711 738 //assure that inst.yearshtml didn't change. 712 if( origyearshtml === inst.yearshtml ){739 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ 713 740 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); 714 741 } … … 760 787 var position = $(obj).offset(); 761 788 return [position.left, position.top]; 789 }, 790 791 /* Trigger custom callback of onClose. */ 792 _triggerOnClose: function(inst) { 793 var onClose = this._get(inst, 'onClose'); 794 if (onClose) 795 onClose.apply((inst.input ? inst.input[0] : null), 796 [(inst.input ? inst.input.val() : ''), inst]); 762 797 }, 763 798 … … 782 817 if (!showAnim) 783 818 postProcess(); 784 var onClose = this._get(inst, 'onClose'); 785 if (onClose) 786 onClose.apply((inst.input ? inst.input[0] : null), 787 [(inst.input ? inst.input.val() : ''), inst]); // trigger custom callback 819 $.datepicker._triggerOnClose(inst); 788 820 this._datepickerShowing = false; 789 821 this._lastInput = null; … … 853 885 var target = $(id); 854 886 var inst = this._getInst(target[0]); 855 inst._selectingMonthYear = false;856 887 inst['selected' + (period == 'M' ? 'Month' : 'Year')] = 857 888 inst['draw' + (period == 'M' ? 'Month' : 'Year')] = … … 859 890 this._notifyChange(inst); 860 891 this._adjustDate(target); 861 },862 863 /* Restore input focus after not changing month/year. */864 _clickMonthYear: function(id) {865 var target = $(id);866 var inst = this._getInst(target[0]);867 if (inst.input && inst._selectingMonthYear) {868 setTimeout(function() {869 inst.input.focus();870 }, 0);871 }872 inst._selectingMonthYear = !inst._selectingMonthYear;873 892 }, 874 893 … … 1001 1020 // Extract a name from the string value and convert to an index 1002 1021 var getName = function(match, shortNames, longNames) { 1003 var names = (lookAhead(match) ? longNames : shortNames); 1004 for (var i = 0; i < names.length; i++) { 1005 if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) { 1006 iValue += names[i].length; 1007 return i + 1; 1022 var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { 1023 return [ [k, v] ]; 1024 }).sort(function (a, b) { 1025 return -(a[1].length - b[1].length); 1026 }); 1027 var index = -1; 1028 $.each(names, function (i, pair) { 1029 var name = pair[1]; 1030 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) { 1031 index = pair[0]; 1032 iValue += name.length; 1033 return false; 1008 1034 } 1009 } 1010 throw 'Unknown name at position ' + iValue; 1035 }); 1036 if (index != -1) 1037 return index + 1; 1038 else 1039 throw 'Unknown name at position ' + iValue; 1011 1040 }; 1012 1041 // Confirm that a literal character matches the string value … … 1065 1094 } 1066 1095 } 1096 if (iValue < value.length){ 1097 throw "Extra/unparsed characters found in date: " + value.substring(iValue); 1098 } 1067 1099 if (year == -1) 1068 1100 year = new Date().getFullYear(); … … 1083 1115 var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); 1084 1116 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) 1085 throw 'Invalid date'; // E.g. 31/02/ *1117 throw 'Invalid date'; // E.g. 31/02/00 1086 1118 return date; 1087 1119 }, … … 1176 1208 case 'o': 1177 1209 output += formatNumber('o', 1178 (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3);1210 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); 1179 1211 break; 1180 1212 case 'm': … … 1451 1483 for (var row = 0; row < numMonths[0]; row++) { 1452 1484 var group = ''; 1485 this.maxRows = 4; 1453 1486 for (var col = 0; col < numMonths[1]; col++) { 1454 1487 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); … … 1485 1518 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); 1486 1519 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; 1487 var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate 1520 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate 1521 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) 1522 this.maxRows = numRows; 1488 1523 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); 1489 1524 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows … … 1555 1590 monthHtml += '<select class="ui-datepicker-month" ' + 1556 1591 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' + 1557 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +1558 1592 '>'; 1559 1593 for (var month = 0; month < 12; month++) { … … 1569 1603 html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); 1570 1604 // year selection 1571 inst.yearshtml = ''; 1572 if (secondary || !changeYear) 1573 html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; 1574 else { 1575 // determine range of years to display 1576 var years = this._get(inst, 'yearRange').split(':'); 1577 var thisYear = new Date().getFullYear(); 1578 var determineYear = function(value) { 1579 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : 1580 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : 1581 parseInt(value, 10))); 1582 return (isNaN(year) ? thisYear : year); 1583 }; 1584 var year = determineYear(years[0]); 1585 var endYear = Math.max(year, determineYear(years[1] || '')); 1586 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 1587 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 1588 inst.yearshtml += '<select class="ui-datepicker-year" ' + 1589 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' + 1590 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + 1591 '>'; 1592 for (; year <= endYear; year++) { 1593 inst.yearshtml += '<option value="' + year + '"' + 1594 (year == drawYear ? ' selected="selected"' : '') + 1595 '>' + year + '</option>'; 1596 } 1597 inst.yearshtml += '</select>'; 1598 //when showing there is no need for later update 1599 if( ! $.browser.mozilla ){ 1605 if ( !inst.yearshtml ) { 1606 inst.yearshtml = ''; 1607 if (secondary || !changeYear) 1608 html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; 1609 else { 1610 // determine range of years to display 1611 var years = this._get(inst, 'yearRange').split(':'); 1612 var thisYear = new Date().getFullYear(); 1613 var determineYear = function(value) { 1614 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : 1615 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : 1616 parseInt(value, 10))); 1617 return (isNaN(year) ? thisYear : year); 1618 }; 1619 var year = determineYear(years[0]); 1620 var endYear = Math.max(year, determineYear(years[1] || '')); 1621 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); 1622 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); 1623 inst.yearshtml += '<select class="ui-datepicker-year" ' + 1624 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' + 1625 '>'; 1626 for (; year <= endYear; year++) { 1627 inst.yearshtml += '<option value="' + year + '"' + 1628 (year == drawYear ? ' selected="selected"' : '') + 1629 '>' + year + '</option>'; 1630 } 1631 inst.yearshtml += '</select>'; 1632 1600 1633 html += inst.yearshtml; 1601 1634 inst.yearshtml = null; 1602 } else {1603 // will be replaced later with inst.yearshtml1604 html += '<select class="ui-datepicker-year"><option value="' + drawYear + '" selected="selected">' + drawYear + '</option></select>';1605 1635 } 1606 1636 } … … 1706 1736 } 1707 1737 }); 1738 1739 /* 1740 * Bind hover events for datepicker elements. 1741 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 1742 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 1743 */ 1744 function bindHover(dpDiv) { 1745 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; 1746 return dpDiv.bind('mouseout', function(event) { 1747 var elem = $( event.target ).closest( selector ); 1748 if ( !elem.length ) { 1749 return; 1750 } 1751 elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" ); 1752 }) 1753 .bind('mouseover', function(event) { 1754 var elem = $( event.target ).closest( selector ); 1755 if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) || 1756 !elem.length ) { 1757 return; 1758 } 1759 elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); 1760 elem.addClass('ui-state-hover'); 1761 if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover'); 1762 if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover'); 1763 }); 1764 } 1708 1765 1709 1766 /* jQuery extend now ignores nulls! */ … … 1758 1815 $.datepicker.initialized = false; 1759 1816 $.datepicker.uuid = new Date().getTime(); 1760 $.datepicker.version = "1.8.1 0";1817 $.datepicker.version = "1.8.16"; 1761 1818 1762 1819 // Workaround for #4055
Note: See TracChangeset
for help on using the changeset viewer.