diff --git a/MonthPicker.js b/MonthPicker.js index 459cfbc..091279a 100644 --- a/MonthPicker.js +++ b/MonthPicker.js @@ -1,7 +1,7 @@ /* https://github.com/KidSysco/jquery-ui-month-picker/ -Version 2.6.1 +Version 2.6.2 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,6 +16,7 @@ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. */ ; (function ($, window, document) { + 'use strict'; var _speeds = $.fx.speeds; var _eventsNs = '.MonthPicker'; var _disabledClass = 'month-picker-disabled'; @@ -42,6 +43,14 @@ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. MaxMonth: '_setMaxMonth' }; + function _toMonth(date) { + return date.getMonth() + (date.getFullYear() * 12); + } + + function _toYear(month) { + return Math.floor(month / 12); + } + // This test must be run before any rererence is made to jQuery. // In case the user didn't load jQuery or jQuery UI the plugin // will fail before it get's to this test + there is no reason @@ -294,7 +303,7 @@ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. var me = this, Month = 'Month'; $.each(['Min', 'Max'], function(i, type) { me["_set" + type + Month] = function(val) { - if ((me['_' + type + Month] = this._toDate(val)) === false) { + if ((me['_' + type + Month] = this._toMonth(val)) === false) { alert(_badMinMaxVal.replace(/%/, type).replace(/_/, val)); } }; @@ -366,8 +375,8 @@ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. this._validationMessage.hide(); }, - Toggle: function () { - return this._visible ? this.Close() : this.Open(); + Toggle: function (event) { + return this._visible ? this.Close(event) : this.Open(event); }, Open: function (event) { @@ -689,8 +698,8 @@ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. var _minDate = this._MinMonth; var _maxDate = this._MaxMonth; - _minYear = _minDate ? _minDate.getFullYear() : 0; - _maxYear = _maxDate ? _maxDate.getFullYear() : 0; + var _minYear = _minDate ? _toYear(_minDate) : 0; + var _maxYear = _maxDate ? _toYear(_maxDate) : 0; this._prevButton .attr('title', this._i18n('prev5Years')) @@ -725,7 +734,7 @@ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. _onMonthClick: function(event) { this._chooseMonth(event.data.month); - this.Close(); + this.Close(event); }, _onYearClick: function(event) { @@ -754,10 +763,10 @@ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. _ajustYear: function(_opts) { var _year = _opts.StartYear || this.GetSelectedYear() || new Date().getFullYear(); if (this._MinMonth !== null) { - _year = Math.max(this._MinMonth.getFullYear(), _year); + _year = Math.max(_toYear(this._MinMonth), _year); } if (this._MaxMonth !== null) { - _year = Math.min(this._MaxMonth.getFullYear(), _year); + _year = Math.min(_toYear(this._MaxMonth), _year); } this._setPickerYear( _year ); @@ -768,37 +777,32 @@ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. var _minDate = this._MinMonth, _maxDate = this._MaxMonth; - this._prevButton.button('option', 'disabled', _minDate && _curYear == _minDate.getFullYear()); - this._nextButton.button('option', 'disabled', _maxDate && _curYear == _maxDate.getFullYear()); + this._prevButton.button('option', 'disabled', _minDate && _curYear == _toYear(_minDate)); + this._nextButton.button('option', 'disabled', _maxDate && _curYear == _toYear(_maxDate)); for (var i = 0; i < 12; i++) { // Disable the button if the month is not between the // min and max interval. + var _currMonth = ((_curYear * 12) + i); $(this._buttons[i]).button('option', 'disabled', ( - (_minDate && new Date(_curYear, i, 1) < _minDate) || - (_maxDate && new Date(_curYear, i, 0) > _maxDate) + (_minDate && _currMonth < _minDate) || + (_maxDate && _currMonth > _maxDate) )); } }, - _toDate: function(_val) { + _toMonth: function(_val) { if (_val === null) { return _val; } else if (_val instanceof Date) { - _val = new Date(_val.getTime()); - _val.setDate( 0 ); - - return _val; + return _toMonth(_val); } else if ($.isNumeric(_val)) { - var _date = new Date; - _date.setMonth( _date.getMonth() + parseInt(_val, 10) ); - _date.setDate( 0 ); - return _date; + return _toMonth(new Date) + parseInt(_val, 10); } - + var _date = this._parseMonth(_val); if (_date) { - return _date; + return _toMonth(_date); } return this._parsePeriod(_val); @@ -814,19 +818,15 @@ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. _json = _json.replace(/m/i, '":"m"'); try { - var _rev = JSON.parse( '{"' + _json.replace(/ /g, ',"') + '}' ), - obj = {}; + var _rev = JSON.parse( '{"' + _json.replace(/ /g, ',"') + '}' ), obj = {}; for (var key in _rev) { obj[ _rev[key] ] = key; } - var _date = new Date; - - _date.setFullYear( _date.getFullYear() + (parseInt(obj.y, 10) || 0) ); - _date.setMonth( _date.getMonth() + (parseInt(obj.m, 10) || 0) ); - _date.setDate( 0 ); - return _date; + var _month = _toMonth(new Date); + _month += (parseInt(obj.m, 10) || 0); + return _month + (parseInt(obj.y, 10) || 0) * 12; } catch (e) { return false; } @@ -834,5 +834,5 @@ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. }); // Added in version 2.4. - $.MonthPicker.VERSION = '2.6.1'; + $.MonthPicker.VERSION = '2.6.2'; }(jQuery, window, document)); diff --git a/MonthPicker.min.js b/MonthPicker.min.js index 0e072d6..6aa3a30 100644 --- a/MonthPicker.min.js +++ b/MonthPicker.min.js @@ -1 +1 @@ -!function(a,b,c){function d(b){return a(''+b.i18n.buttonText+"").button({text:!1,icons:{primary:b.ButtonIcon}})}function e(a,b){a.button("option",{icons:{primary:"ui-icon-circle-triangle-"+(b?"w":"e")}})}var f=a.fx.speeds,g=".MonthPicker",h={my:"left top+1",at:"left bottom"},i={my:"right top+1",at:"right bottom"},j="MonthPicker Setup Error: ",k=j+"The jQuery UI position plug-in must be loaded in order to specify a position.",l=j+"Unsupported % option value, supported (case sensitive) values are: ",m=j+'"_" is not a valid %Month value.',n={Animation:["slideToggle","fadeToggle","none"],ShowAnim:["fadeIn","slideDown","none"],HideAnim:["fadeOut","slideUp","none"]},o={ValidationErrorMessage:"_createValidationMessage",Disabled:"_setDisabledState",ShowIcon:"_showIcon",Button:"_createButton",ShowOn:"_updateFieldEvents",IsRTL:"_setRTL",StartYear:"_setPickerYear",MinMonth:"_setMinMonth",MaxMonth:"_setMaxMonth"};if(!(a&&a.ui&&a.ui.button&&a.ui.datepicker))return alert(j+"The jQuery UI button and datepicker plug-ins must be loaded before MonthPicker is called."),!1;var p=a.noop,q=a.datepicker,r=null,s=!!a.ui.position;a.MonthPicker={i18n:{year:"Year",prevYear:"Previous Year",nextYear:"Next Year",next5Years:"Jump Forward 5 Years",prev5Years:"Jump Back 5 Years",nextLabel:"Next",prevLabel:"Prev",buttonText:"Open Month Chooser",jumpYears:"Jump Years",months:["Jan.","Feb.","Mar.","Apr.","May","June","July","Aug.","Sep.","Oct.","Nov.","Dec."]}};var t='
';a.widget("KidSysco.MonthPicker",{options:{i18n:{},IsRTL:!1,Position:null,StartYear:null,ShowIcon:!0,UseInputMask:!1,ValidationErrorMessage:null,Disabled:!1,MonthFormat:"mm/yy",Animation:"fadeToggle",ShowAnim:null,HideAnim:null,ShowOn:null,MinMonth:null,MaxMonth:null,Duration:"normal",Button:d,OnAfterSetDisabled:p,ButtonIcon:"ui-icon-calculator",OnBeforeMenuOpen:p,OnAfterMenuOpen:p,OnBeforeMenuClose:p,OnAfterMenuClose:p,OnAfterNextYear:p,OnAfterNextYears:p,OnAfterPreviousYear:p,OnAfterPreviousYears:p,OnAfterChooseMonth:p,OnAfterChooseYear:p,OnAfterChooseYears:p,OnAfterChooseMonths:p},_monthPickerButton:a(),_validationMessage:a(),_destroy:function(){var b=this.element;jQuery.mask&&this.options.UseInputMask&&(b.unmask(),this.GetSelectedDate()||b.val("")),b.removeClass("month-year-input").off(g),a(c).off("click"+g+this.uuid),this._monthPickerMenu.remove();var d=this._monthPickerButton.off("click"+g);this._removeOldBtn&&d.remove(),this._validationMessage.remove()},_setOption:function(b,c){switch(b){case"i18n":c=a.extend({},c);break;case"Position":if(!s)return void alert(k);case"MonthFormat":var d=this.GetSelectedDate();d&&this.element.val(this.FormatMonth(d,c))}return b in n&&-1===n[b].indexOf(c)?void alert(l.replace(/%/,b)+n[b]):(this._super(b,c),void(o[b]?this[o[b]](c):0))},_create:function(){var b=this.element,c=this.options;if(!b.is("input")||-1===["text","month",void 0].indexOf(b.attr("type"))){var d=j+"MonthPicker can only be called on text or month inputs.";return alert(d+" \n\nSee console (developer tools) for more details."),console.error(d+"\n Caused by:"),console.log(b[0]),!1}if(!a.mask&&c.UseInputMask)return alert(j+"The UseInputMask option is set but the Digital Bush Input Mask jQuery Plugin is not loaded. Get the plugin from http://digitalbush.com/"),!1;if(null!==c.Position&&!s)return alert(k),!1;for(var e in n)if(null!==c[e]&&-1===n[e].indexOf(c[e]))return alert(l.replace(/%/,e)+n[e]),!1;this._isMonthInputType="month"===b.attr("type"),this._isMonthInputType&&(this.options.MonthFormat=this.MonthInputFormat,b.css("width","auto")),b.addClass("month-year-input");var f=this._monthPickerMenu=a('
');a(t).appendTo(f),a("body").append(f),a(".year-title",f).text(this._i18n("year")),a(".year-container-all",f).attr("title",this._i18n("jumpYears")),this._createValidationMessage(),this._yearContainer=a(".year",f),this._prevButton=a(".previous-year button",f).button({text:!1}),this._nextButton=a(".next-year button",f).button({text:!1}),this._setRTL(c.IsRTL),a(".ui-button-icon-primary",this._nextButton).text(this._i18n("nextLabel")),a(".ui-button-icon-primary",this._prevButton).text(this._i18n("prevLabel"));for(var h=a(".month-picker-month-table",f),i=0;12>i;i++){var o=i%3?o:a("").appendTo(h);o.append('')}this._buttons=a("button",h).button(),a(".year-container-all",f).click(a.proxy(this._showYearsClickHandler,this)),f.on("click"+g,function(a){return!1});var p=this,q="Month";a.each(["Min","Max"],function(a,b){p["_set"+b+q]=function(a){(p["_"+b+q]=this._toDate(a))===!1&&alert(m.replace(/%/,b).replace(/_/,a))},p._setOption(b+q,p.options[b+q])}),this._setUseInputMask(),this._setDisabledState(),this._updateFieldEvents(),this.Destroy=this.destroy},_i18n:function(b){return this.options.i18n[b]||a.MonthPicker.i18n[b]},GetSelectedDate:function(){return this._parseMonth()},GetSelectedYear:function(){var a=this.GetSelectedDate();return a?a.getFullYear():NaN},GetSelectedMonth:function(){var a=this.GetSelectedDate();return a?a.getMonth()+1:NaN},Validate:function(){var a=this.GetSelectedDate();return null===this.options.ValidationErrorMessage||this.options.Disabled||this._validationMessage[a?"hide":"show"](),a},GetSelectedMonthYear:function(){var a=this.Validate();return a?a.getMonth()+1+"/"+a.getFullYear():null},Disable:function(){this._setOption("Disabled",!0)},Enable:function(){this._setOption("Disabled",!1)},ClearAllCallbacks:function(){for(var a in this.options)0===a.indexOf("On")&&(this.options[a]=p)},Clear:function(){this.element.val(""),this._validationMessage.hide()},Toggle:function(){return this._visible?this.Close():this.Open()},Open:function(b){if(!this.options.Disabled&&!this._visible){var d=this.element,e=this.options;if(b=b||new a.Event,e.OnBeforeMenuOpen.call(d[0],b)===!1||b.isDefaultPrevented())return!1;this._visible=!0,this._ajustYear(e),r&&r.Close(b),r=this;var f=this._monthPickerMenu;this._showMonths(),a(c).on("click"+g+this.uuid,a.proxy(this.Close,this)).on("keydown"+g+this.uuid,a.proxy(this._keyDown,this)),d.off("blur"+g).focus();var h=e.ShowAnim||e.Animation,i="none"===h;f[i?"show":h]({duration:i?0:this._duration(),start:a.proxy(this._position,this,f),complete:a.proxy(e.OnAfterMenuOpen,d[0])})}return!1},Close:function(b){if(this._visible){var d=this._monthPickerMenu,e=this.options,f=this.element;if(b=b||new a.Event,e.OnBeforeMenuClose.call(f[0],b)===!1||b.isDefaultPrevented())return;this._visible=!1,r=null,a(c).off("keydown"+g+this.uuid).off("click"+g+this.uuid),this.Validate(),f.on("blur"+g,a.proxy(this.Validate,this));var h=a.proxy(e.OnAfterMenuClose,f[0]),i=e.HideAnim||e.Animation;"none"===i?d.hide(0,h):d[i](this._duration(),h)}},SetDisabled:function(a,b){try{b.button("option","disabled",a)}catch(c){b.prop("disabled",a)}},MonthInputFormat:"yy-mm",ParseMonth:function(a,b){try{return q.parseDate("dd"+b,"01"+a)}catch(c){return null}},FormatMonth:function(a,b){try{return q.formatDate(b,a)||null}catch(c){return null}},_parseMonth:function(a){return this.ParseMonth(a||this.element.val(),this.options.MonthFormat)},_formatMonth:function(a){return this.FormatMonth(a||this._parseMonth(),this.options.MonthFormat)},_showIcon:function(){var a=this._monthPickerButton;a.length?a[this.options.ShowIcon?"show":"hide"]():this._createButton(),this._updateFieldEvents()},_createButton:function(){if(this.options.ShowIcon){var b=this._monthPickerButton.off(g),d=this.options.Button,e=this.element;a.isFunction(d)&&(d=d.call(e[0],a.extend(!0,{i18n:a.MonthPicker.i18n},this.options)));var f=!1;this._monthPickerButton=(d instanceof a?d:a(d)).each(function(){a.contains(c.body,this)||(f=!0,a(this).insertAfter(e))}).on("click"+g,a.proxy(this.Toggle,this)),this._removeOldBtn&&b.remove(),this._removeOldBtn=f}},_updateFieldEvents:function(){this.element.off("click"+g),"both"!==this.options.ShowOn&&this._monthPickerButton.length||this.element.on("click"+g,a.proxy(this.Open,this))},_createValidationMessage:function(){var b=this.options.ValidationErrorMessage,c=this.element;if(-1===[null,""].indexOf(b)){var d=a(''+b+""),e=this._monthPickerButton;this._validationMessage=d.insertAfter(e.length?e:c),c.on("blur"+g,a.proxy(this.Validate,this))}else this._validationMessage.remove()},_setRTL:function(a){e(this._prevButton,!a),e(this._nextButton,a)},_keyDown:function(){var b=a.ui.keyCode;switch(event.keyCode){case b.ENTER:this._chooseMonth((new Date).getMonth()+1),this.Close();break;case b.ESCAPE:this.Close()}},_duration:function(){var b=this.options.Duration;return a.isNumeric(b)?b:b in f?f[b]:f._default},_position:s?function(b){var c=this.options.IsRTL?i:h,d=a.extend(c,this.options.Position);return b.position(a.extend({of:this.element},d))}:function(a){var b=this.element,c={top:b.offset().top+b.height()+7+"px"};return this.options.IsRTL?c.left=b.offset().left-a.width()+b.width()+7+"px":c.left=b.offset().left+"px",a.css(c)},_setUseInputMask:function(){if(!this._isMonthInputType)try{this.options.UseInputMask?this.element.mask(this._formatMonth(new Date).replace(/\d/g,9)):this.element.unmask()}catch(a){}},_setDisabledState:function(){var a=this.options.Disabled;this.element[0].disabled=a,this.element[a?"addClass":"removeClass"]("disabled"),a&&this._validationMessage.hide(),this.Close(),this._createButton(),this.SetDisabled(a,this._monthPickerButton),this.options.OnAfterSetDisabled.call(this.element[0],a)},_getPickerYear:function(){return parseInt(this._yearContainer.text(),10)},_setPickerYear:function(a){this._yearContainer.text(a||(new Date).getFullYear())},_chooseMonth:function(a){var b=new Date(this._getPickerYear(),a-1);this.element.val(this._formatMonth(b)).blur(),this.options.OnAfterChooseMonth.call(this.element[0])},_chooseYear:function(a){this._setPickerYear(a),this._showMonths(),this.options.OnAfterChooseYear.call(this.element[0])},_showMonths:function(){var b=this._i18n("months");this._prevButton.attr("title",this._i18n("prevYear")).off("click"+g).on("click"+g,a.proxy(this._addToYear,this,-1)),this._nextButton.attr("title",this._i18n("nextYear")).off("click"+g).on("click"+g,a.proxy(this._addToYear,this,1)),a(".year-container-all",this._monthPickerMenu).css("cursor","pointer"),this._buttons.off(g);var c=this,d=a.proxy(c._onMonthClick,c);a.each(b,function(b,e){a(c._buttons[b]).on("click"+g,{month:b+1},d).button("option","label",e)}),this._enableMonthButtons()},_showYearsClickHandler:function(){this._showYears(),this.options.OnAfterChooseYears.call(this.element[0])},_showYears:function(){var b=this._getPickerYear(),c=-4,d=b+c,e=5,f=this._MinMonth,h=this._MaxMonth;_minYear=f?f.getFullYear():0,_maxYear=h?h.getFullYear():0,this._prevButton.attr("title",this._i18n("prev5Years")).off("click"+g).on("click"+g,a.proxy(this._addToYears,this,-e)).button("option","disabled",_minYear&&d-1<_minYear),this._nextButton.attr("title",this._i18n("next5Years")).off("click"+g).on("click"+g,a.proxy(this._addToYears,this,e)).button("option","disabled",_maxYear&&d+12-1>_maxYear),a(".year-container-all",this._monthPickerMenu).css("cursor","default"),this._buttons.off(g);for(var i=a.proxy(this._onYearClick,this),j=0;12>j;j++){var k=b+c,l=a(this._buttons[j]);l.on("click"+g,{year:k},i).button("option","label",k),a(this._buttons[j]).button("option","disabled",_minYear&&k<_minYear||_maxYear&&k>_maxYear),c++}},_onMonthClick:function(a){this._chooseMonth(a.data.month),this.Close()},_onYearClick:function(a){this._chooseYear(a.data.year)},_addToYear:function(a){var b=this._yearContainer;b.text(parseInt(b.text())+a,10),this.element.focus(),this._enableMonthButtons(),this.options["OnAfter"+(a>0?"Next":"Previous")+"Year"].call(this.element[0])},_addToYears:function(a){var b=this._yearContainer;b.text(parseInt(b.text())+a,10),this._showYears(),this.element.focus(),this.options["OnAfter"+(a>0?"Next":"Previous")+"Years"].call(this.element[0])},_ajustYear:function(a){var b=a.StartYear||this.GetSelectedYear()||(new Date).getFullYear();null!==this._MinMonth&&(b=Math.max(this._MinMonth.getFullYear(),b)),null!==this._MaxMonth&&(b=Math.min(this._MaxMonth.getFullYear(),b)),this._setPickerYear(b)},_enableMonthButtons:function(){var b=this._getPickerYear(),c=this._MinMonth,d=this._MaxMonth;this._prevButton.button("option","disabled",c&&b==c.getFullYear()),this._nextButton.button("option","disabled",d&&b==d.getFullYear());for(var e=0;12>e;e++)a(this._buttons[e]).button("option","disabled",c&&new Date(b,e,1)d)},_toDate:function(b){if(null===b)return b;if(b instanceof Date)return b=new Date(b.getTime()),b.setDate(0),b;if(a.isNumeric(b)){var c=new Date;return c.setMonth(c.getMonth()+parseInt(b,10)),c.setDate(0),c}var c=this._parseMonth(b);return c?c:this._parsePeriod(b)},_parsePeriod:function(a,b){var c=a.trim();c=c.replace(/y/i,'":"y"'),c=c.replace(/m/i,'":"m"');try{var d=JSON.parse('{"'+c.replace(/ /g,',"')+"}"),e={};for(var f in d)e[d[f]]=f;var g=new Date;return g.setFullYear(g.getFullYear()+(parseInt(e.y,10)||0)),g.setMonth(g.getMonth()+(parseInt(e.m,10)||0)),g.setDate(0),g}catch(h){return!1}}}),a.MonthPicker.VERSION="2.6.1"}(jQuery,window,document); \ No newline at end of file +!function(a,b,c){"use strict";function d(a){return a.getMonth()+12*a.getFullYear()}function e(a){return Math.floor(a/12)}function f(b){return a(''+b.i18n.buttonText+"").button({text:!1,icons:{primary:b.ButtonIcon}})}function g(a,b){a.button("option",{icons:{primary:"ui-icon-circle-triangle-"+(b?"w":"e")}})}var h=a.fx.speeds,i=".MonthPicker",j={my:"left top+1",at:"left bottom"},k={my:"right top+1",at:"right bottom"},l="MonthPicker Setup Error: ",m=l+"The jQuery UI position plug-in must be loaded in order to specify a position.",n=l+"Unsupported % option value, supported (case sensitive) values are: ",o=l+'"_" is not a valid %Month value.',p={Animation:["slideToggle","fadeToggle","none"],ShowAnim:["fadeIn","slideDown","none"],HideAnim:["fadeOut","slideUp","none"]},q={ValidationErrorMessage:"_createValidationMessage",Disabled:"_setDisabledState",ShowIcon:"_showIcon",Button:"_createButton",ShowOn:"_updateFieldEvents",IsRTL:"_setRTL",StartYear:"_setPickerYear",MinMonth:"_setMinMonth",MaxMonth:"_setMaxMonth"};if(!(a&&a.ui&&a.ui.button&&a.ui.datepicker))return alert(l+"The jQuery UI button and datepicker plug-ins must be loaded before MonthPicker is called."),!1;var r=a.noop,s=a.datepicker,t=null,u=!!a.ui.position;a.MonthPicker={i18n:{year:"Year",prevYear:"Previous Year",nextYear:"Next Year",next5Years:"Jump Forward 5 Years",prev5Years:"Jump Back 5 Years",nextLabel:"Next",prevLabel:"Prev",buttonText:"Open Month Chooser",jumpYears:"Jump Years",months:["Jan.","Feb.","Mar.","Apr.","May","June","July","Aug.","Sep.","Oct.","Nov.","Dec."]}};var v='
';a.widget("KidSysco.MonthPicker",{options:{i18n:{},IsRTL:!1,Position:null,StartYear:null,ShowIcon:!0,UseInputMask:!1,ValidationErrorMessage:null,Disabled:!1,MonthFormat:"mm/yy",Animation:"fadeToggle",ShowAnim:null,HideAnim:null,ShowOn:null,MinMonth:null,MaxMonth:null,Duration:"normal",Button:f,OnAfterSetDisabled:r,ButtonIcon:"ui-icon-calculator",OnBeforeMenuOpen:r,OnAfterMenuOpen:r,OnBeforeMenuClose:r,OnAfterMenuClose:r,OnAfterNextYear:r,OnAfterNextYears:r,OnAfterPreviousYear:r,OnAfterPreviousYears:r,OnAfterChooseMonth:r,OnAfterChooseYear:r,OnAfterChooseYears:r,OnAfterChooseMonths:r},_monthPickerButton:a(),_validationMessage:a(),_destroy:function(){var b=this.element;jQuery.mask&&this.options.UseInputMask&&(b.unmask(),this.GetSelectedDate()||b.val("")),b.removeClass("month-year-input").off(i),a(c).off("click"+i+this.uuid),this._monthPickerMenu.remove();var d=this._monthPickerButton.off("click"+i);this._removeOldBtn&&d.remove(),this._validationMessage.remove()},_setOption:function(b,c){switch(b){case"i18n":c=a.extend({},c);break;case"Position":if(!u)return void alert(m);case"MonthFormat":var d=this.GetSelectedDate();d&&this.element.val(this.FormatMonth(d,c))}return b in p&&-1===p[b].indexOf(c)?void alert(n.replace(/%/,b)+p[b]):(this._super(b,c),void(q[b]?this[q[b]](c):0))},_create:function(){var b=this.element,c=this.options;if(!b.is("input")||-1===["text","month",void 0].indexOf(b.attr("type"))){var d=l+"MonthPicker can only be called on text or month inputs.";return alert(d+" \n\nSee console (developer tools) for more details."),console.error(d+"\n Caused by:"),console.log(b[0]),!1}if(!a.mask&&c.UseInputMask)return alert(l+"The UseInputMask option is set but the Digital Bush Input Mask jQuery Plugin is not loaded. Get the plugin from http://digitalbush.com/"),!1;if(null!==c.Position&&!u)return alert(m),!1;for(var e in p)if(null!==c[e]&&-1===p[e].indexOf(c[e]))return alert(n.replace(/%/,e)+p[e]),!1;this._isMonthInputType="month"===b.attr("type"),this._isMonthInputType&&(this.options.MonthFormat=this.MonthInputFormat,b.css("width","auto")),b.addClass("month-year-input");var f=this._monthPickerMenu=a('
');a(v).appendTo(f),a("body").append(f),a(".year-title",f).text(this._i18n("year")),a(".year-container-all",f).attr("title",this._i18n("jumpYears")),this._createValidationMessage(),this._yearContainer=a(".year",f),this._prevButton=a(".previous-year button",f).button({text:!1}),this._nextButton=a(".next-year button",f).button({text:!1}),this._setRTL(c.IsRTL),a(".ui-button-icon-primary",this._nextButton).text(this._i18n("nextLabel")),a(".ui-button-icon-primary",this._prevButton).text(this._i18n("prevLabel"));for(var g=a(".month-picker-month-table",f),h=0;12>h;h++){var j=h%3?j:a("").appendTo(g);j.append('')}this._buttons=a("button",g).button(),a(".year-container-all",f).click(a.proxy(this._showYearsClickHandler,this)),f.on("click"+i,function(a){return!1});var k=this,q="Month";a.each(["Min","Max"],function(a,b){k["_set"+b+q]=function(a){(k["_"+b+q]=this._toMonth(a))===!1&&alert(o.replace(/%/,b).replace(/_/,a))},k._setOption(b+q,k.options[b+q])}),this._setUseInputMask(),this._setDisabledState(),this._updateFieldEvents(),this.Destroy=this.destroy},_i18n:function(b){return this.options.i18n[b]||a.MonthPicker.i18n[b]},GetSelectedDate:function(){return this._parseMonth()},GetSelectedYear:function(){var a=this.GetSelectedDate();return a?a.getFullYear():NaN},GetSelectedMonth:function(){var a=this.GetSelectedDate();return a?a.getMonth()+1:NaN},Validate:function(){var a=this.GetSelectedDate();return null===this.options.ValidationErrorMessage||this.options.Disabled||this._validationMessage[a?"hide":"show"](),a},GetSelectedMonthYear:function(){var a=this.Validate();return a?a.getMonth()+1+"/"+a.getFullYear():null},Disable:function(){this._setOption("Disabled",!0)},Enable:function(){this._setOption("Disabled",!1)},ClearAllCallbacks:function(){for(var a in this.options)0===a.indexOf("On")&&(this.options[a]=r)},Clear:function(){this.element.val(""),this._validationMessage.hide()},Toggle:function(a){return this._visible?this.Close(a):this.Open(a)},Open:function(b){if(!this.options.Disabled&&!this._visible){var d=this.element,e=this.options;if(b=b||new a.Event,e.OnBeforeMenuOpen.call(d[0],b)===!1||b.isDefaultPrevented())return!1;this._visible=!0,this._ajustYear(e),t&&t.Close(b),t=this;var f=this._monthPickerMenu;this._showMonths(),a(c).on("click"+i+this.uuid,a.proxy(this.Close,this)).on("keydown"+i+this.uuid,a.proxy(this._keyDown,this)),d.off("blur"+i).focus();var g=e.ShowAnim||e.Animation,h="none"===g;f[h?"fadeIn":g]({duration:h?0:this._duration(),start:a.proxy(this._position,this,f),complete:a.proxy(e.OnAfterMenuOpen,d[0])})}return!1},Close:function(b){if(this._visible){var d=this._monthPickerMenu,e=this.options,f=this.element;if(b=b||new a.Event,e.OnBeforeMenuClose.call(f[0],b)===!1||b.isDefaultPrevented())return;this._visible=!1,t=null,a(c).off("keydown"+i+this.uuid).off("click"+i+this.uuid),this.Validate(),f.on("blur"+i,a.proxy(this.Validate,this));var g=a.proxy(e.OnAfterMenuClose,f[0]),h=e.HideAnim||e.Animation;"none"===h?d.hide(0,g):d[h](this._duration(),g)}},SetDisabled:function(a,b){try{b.button("option","disabled",a)}catch(c){b.prop("disabled",a)}},MonthInputFormat:"yy-mm",ParseMonth:function(a,b){try{return s.parseDate("dd"+b,"01"+a)}catch(c){return null}},FormatMonth:function(a,b){try{return s.formatDate(b,a)||null}catch(c){return null}},_parseMonth:function(a){return this.ParseMonth(a||this.element.val(),this.options.MonthFormat)},_formatMonth:function(a){return this.FormatMonth(a||this._parseMonth(),this.options.MonthFormat)},_showIcon:function(){var a=this._monthPickerButton;a.length?a[this.options.ShowIcon?"show":"hide"]():this._createButton(),this._updateFieldEvents()},_createButton:function(){if(this.options.ShowIcon){var b=this._monthPickerButton.off(i),d=this.options.Button,e=this.element;a.isFunction(d)&&(d=d.call(e[0],a.extend(!0,{i18n:a.MonthPicker.i18n},this.options)));var f=!1;this._monthPickerButton=(d instanceof a?d:a(d)).each(function(){a.contains(c.body,this)||(f=!0,a(this).insertAfter(e))}).on("click"+i,a.proxy(this.Toggle,this)),this._removeOldBtn&&b.remove(),this._removeOldBtn=f}},_updateFieldEvents:function(){this.element.off("click"+i),"both"!==this.options.ShowOn&&this._monthPickerButton.length||this.element.on("click"+i,a.proxy(this.Open,this))},_createValidationMessage:function(){var b=this.options.ValidationErrorMessage,c=this.element;if(-1===[null,""].indexOf(b)){var d=a(''+b+""),e=this._monthPickerButton;this._validationMessage=d.insertAfter(e.length?e:c),c.on("blur"+i,a.proxy(this.Validate,this))}else this._validationMessage.remove()},_setRTL:function(a){g(this._prevButton,!a),g(this._nextButton,a)},_keyDown:function(){var b=a.ui.keyCode;switch(event.keyCode){case b.ENTER:this._chooseMonth((new Date).getMonth()+1),this.Close();break;case b.ESCAPE:this.Close()}},_duration:function(){var b=this.options.Duration;return a.isNumeric(b)?b:b in h?h[b]:h._default},_position:u?function(b){var c=this.options.IsRTL?k:j,d=a.extend(c,this.options.Position);return b.position(a.extend({of:this.element},d))}:function(a){var b=this.element,c={top:b.offset().top+b.height()+7+"px"};return this.options.IsRTL?c.left=b.offset().left-a.width()+b.width()+7+"px":c.left=b.offset().left+"px",a.css(c)},_setUseInputMask:function(){if(!this._isMonthInputType)try{this.options.UseInputMask?this.element.mask(this._formatMonth(new Date).replace(/\d/g,9)):this.element.unmask()}catch(a){}},_setDisabledState:function(){var a=this.options.Disabled;this.element[0].disabled=a,this.element[a?"addClass":"removeClass"]("disabled"),a&&this._validationMessage.hide(),this.Close(),this._createButton(),this.SetDisabled(a,this._monthPickerButton),this.options.OnAfterSetDisabled.call(this.element[0],a)},_getPickerYear:function(){return parseInt(this._yearContainer.text(),10)},_setPickerYear:function(a){this._yearContainer.text(a||(new Date).getFullYear())},_chooseMonth:function(a){var b=new Date(this._getPickerYear(),a-1);this.element.val(this._formatMonth(b)).blur(),this.options.OnAfterChooseMonth.call(this.element[0])},_chooseYear:function(a){this._setPickerYear(a),this._showMonths(),this.options.OnAfterChooseYear.call(this.element[0])},_showMonths:function(){var b=this._i18n("months");this._prevButton.attr("title",this._i18n("prevYear")).off("click"+i).on("click"+i,a.proxy(this._addToYear,this,-1)),this._nextButton.attr("title",this._i18n("nextYear")).off("click"+i).on("click"+i,a.proxy(this._addToYear,this,1)),a(".year-container-all",this._monthPickerMenu).css("cursor","pointer"),this._buttons.off(i);var c=this,d=a.proxy(c._onMonthClick,c);a.each(b,function(b,e){a(c._buttons[b]).on("click"+i,{month:b+1},d).button("option","label",e)}),this._enableMonthButtons()},_showYearsClickHandler:function(){this._showYears(),this.options.OnAfterChooseYears.call(this.element[0])},_showYears:function(){var b=this._getPickerYear(),c=-4,d=b+c,f=5,g=this._MinMonth,h=this._MaxMonth,j=g?e(g):0,k=h?e(h):0;this._prevButton.attr("title",this._i18n("prev5Years")).off("click"+i).on("click"+i,a.proxy(this._addToYears,this,-f)).button("option","disabled",j&&j>d-1),this._nextButton.attr("title",this._i18n("next5Years")).off("click"+i).on("click"+i,a.proxy(this._addToYears,this,f)).button("option","disabled",k&&d+12-1>k),a(".year-container-all",this._monthPickerMenu).css("cursor","default"),this._buttons.off(i);for(var l=a.proxy(this._onYearClick,this),m=0;12>m;m++){var n=b+c,o=a(this._buttons[m]);o.on("click"+i,{year:n},l).button("option","label",n),a(this._buttons[m]).button("option","disabled",j&&j>n||k&&n>k),c++}},_onMonthClick:function(a){this._chooseMonth(a.data.month),this.Close(a)},_onYearClick:function(a){this._chooseYear(a.data.year)},_addToYear:function(a){var b=this._yearContainer;b.text(parseInt(b.text())+a,10),this.element.focus(),this._enableMonthButtons(),this.options["OnAfter"+(a>0?"Next":"Previous")+"Year"].call(this.element[0])},_addToYears:function(a){var b=this._yearContainer;b.text(parseInt(b.text())+a,10),this._showYears(),this.element.focus(),this.options["OnAfter"+(a>0?"Next":"Previous")+"Years"].call(this.element[0])},_ajustYear:function(a){var b=a.StartYear||this.GetSelectedYear()||(new Date).getFullYear();null!==this._MinMonth&&(b=Math.max(e(this._MinMonth),b)),null!==this._MaxMonth&&(b=Math.min(e(this._MaxMonth),b)),this._setPickerYear(b)},_enableMonthButtons:function(){var b=this._getPickerYear(),c=this._MinMonth,d=this._MaxMonth;this._prevButton.button("option","disabled",c&&b==e(c)),this._nextButton.button("option","disabled",d&&b==e(d));for(var f=0;12>f;f++){var g=12*b+f;a(this._buttons[f]).button("option","disabled",c&&c>g||d&&g>d)}},_toMonth:function(b){if(null===b)return b;if(b instanceof Date)return d(b);if(a.isNumeric(b))return d(new Date)+parseInt(b,10);var c=this._parseMonth(b);return c?d(c):this._parsePeriod(b)},_parsePeriod:function(a,b){var c=a.trim();c=c.replace(/y/i,'":"y"'),c=c.replace(/m/i,'":"m"');try{var e=JSON.parse('{"'+c.replace(/ /g,',"')+"}"),f={};for(var g in e)f[e[g]]=g;var h=d(new Date);return h+=parseInt(f.m,10)||0,h+12*(parseInt(f.y,10)||0)}catch(i){return!1}}}),a.MonthPicker.VERSION="2.6.2"}(jQuery,window,document); \ No newline at end of file diff --git a/README.md b/README.md index f9846fb..7d5ffe2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

The jQuery UI Month Picker Version 2.6.1

+

The jQuery UI Month Picker Version 2.6.2

The jQuery UI Month Picker Plugin is designed to allow user input for only a month and year when only that input is required. Clicking on the year, allows the user to jump ahead or back 5 years at a time. Clicking anywhere on the page, except on the month picker menu itself, will cause the month picker to hide. The Month Picker has lots of options @@ -141,7 +141,7 @@ However this is not supported and might stop working in future releases i

Set the option upon init. -

$('.selector').MonthPicker({ ShowIcon: true });
+
$('.selector').MonthPicker({ Disabled: true });
Get or set the option, after init.
@@ -276,8 +276,8 @@ $('.selector').MonthPicker({
 
Create a button with different images for enabled and disabled state. -
-$('.selector').MonthPicker({ 
+
+$('.selector').MonthPicker({
     Button: function(opts) {
 	    var src = 'images/calendar_' + (opts.Disabled ? 'disabled' : 'enabled') + '.gif';
 	    return '<img src="' + src + '" title="Select date" />';
@@ -987,11 +987,11 @@ $('.selector').MonthPicker('option', 'OnAfterChooseYear', function(){ ... } );
     
     Get or set the callback function, after init. 
     
-    //getter
-    var disabled = $('.selector').MonthPicker('option', 'OnAfterChooseYears');
-    
-    //setter
-    $('.selector').MonthPicker('option', 'OnAfterChooseYears', function(){ ... } );
+//getter
+var disabled = $('.selector').MonthPicker('option', 'OnAfterChooseYears');
+
+//setter
+$('.selector').MonthPicker('option', 'OnAfterChooseYears', function(){ ... } );
     

diff --git a/demo/Demo.min.js b/demo/Demo.min.js index b5fd7be..6a07b0e 100644 --- a/demo/Demo.min.js +++ b/demo/Demo.min.js @@ -1 +1 @@ -!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b,c=navigator.userAgent,d=/iphone/i.test(c),e=/chrome/i.test(c),f=/android/i.test(c);a.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},autoclear:!0,dataName:"rawMaskFn",placeholder:"_"},a.fn.extend({caret:function(a,b){var c;return 0===this.length||this.is(":hidden")?void 0:"number"==typeof a?(b="number"==typeof b?b:a,this.each(function(){this.setSelectionRange?this.setSelectionRange(a,b):this.createTextRange&&(c=this.createTextRange(),c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",a),c.select())})):(this[0].setSelectionRange?(a=this[0].selectionStart,b=this[0].selectionEnd):document.selection&&document.selection.createRange&&(c=document.selection.createRange(),a=0-c.duplicate().moveStart("character",-1e5),b=a+c.text.length),{begin:a,end:b})},unmask:function(){return this.trigger("unmask")},mask:function(c,g){var h,i,j,k,l,m,n,o;if(!c&&this.length>0){h=a(this[0]);var p=h.data(a.mask.dataName);return p?p():void 0}return g=a.extend({autoclear:a.mask.autoclear,placeholder:a.mask.placeholder,completed:null},g),i=a.mask.definitions,j=[],k=n=c.length,l=null,a.each(c.split(""),function(a,b){"?"==b?(n--,k=a):i[b]?(j.push(new RegExp(i[b])),null===l&&(l=j.length-1),k>a&&(m=j.length-1)):j.push(null)}),this.trigger("unmask").each(function(){function h(){if(g.completed){for(var a=l;m>=a;a++)if(j[a]&&C[a]===p(a))return;g.completed.call(B)}}function p(a){return g.placeholder.charAt(a=0&&!j[a];);return a}function s(a,b){var c,d;if(!(0>a)){for(c=a,d=q(b);n>c;c++)if(j[c]){if(!(n>d&&j[c].test(C[d])))break;C[c]=C[d],C[d]=p(d),d=q(d)}z(),B.caret(Math.max(l,a))}}function t(a){var b,c,d,e;for(b=a,c=p(a);n>b;b++)if(j[b]){if(d=q(b),e=C[b],C[b]=c,!(n>d&&j[d].test(e)))break;c=e}}function u(){var a=B.val(),b=B.caret();if(o&&o.length&&o.length>a.length){for(A(!0);b.begin>0&&!j[b.begin-1];)b.begin--;if(0===b.begin)for(;b.beging)&&g&&13!==g){if(i.end-i.begin!==0&&(y(i.begin,i.end),s(i.begin,i.end-1)),c=q(i.begin-1),n>c&&(d=String.fromCharCode(g),j[c].test(d))){if(t(c),C[c]=d,z(),e=q(c),f){var k=function(){a.proxy(a.fn.caret,B,e)()};setTimeout(k,0)}else B.caret(e);i.begin<=m&&h()}b.preventDefault()}}}function y(a,b){var c;for(c=a;b>c&&n>c;c++)j[c]&&(C[c]=p(c))}function z(){B.val(C.join(""))}function A(a){var b,c,d,e=B.val(),f=-1;for(b=0,d=0;n>b;b++)if(j[b]){for(C[b]=p(b);d++e.length){y(b+1,n);break}}else C[b]===e.charAt(d)&&d++,k>b&&(f=b);return a?z():k>f+1?g.autoclear||C.join("")===D?(B.val()&&B.val(""),y(0,n)):z():(z(),B.val(B.val().substring(0,f+1))),k?b:l}var B=a(this),C=a.map(c.split(""),function(a,b){return"?"!=a?i[a]?p(b):a:void 0}),D=C.join(""),E=B.val();B.data(a.mask.dataName,function(){return a.map(C,function(a,b){return j[b]&&a!=p(b)?a:null}).join("")}),B.one("unmask",function(){B.off(".mask").removeData(a.mask.dataName)}).on("focus.mask",function(){if(!B.prop("readonly")){clearTimeout(b);var a;E=B.val(),a=A(),b=setTimeout(function(){B.get(0)===document.activeElement&&(z(),a==c.replace("?","").length?B.caret(0,a):B.caret(a))},10)}}).on("blur.mask",v).on("keydown.mask",w).on("keypress.mask",x).on("input.mask paste.mask",function(){B.prop("readonly")||setTimeout(function(){var a=A(!0);B.caret(a),h()},0)}),e&&f&&B.off("input.mask").on("input.mask",u),A()})}})}),function(a,b,c){function d(b){return a(''+b.i18n.buttonText+"").button({text:!1,icons:{primary:b.ButtonIcon}})}function e(a,b){a.button("option",{icons:{primary:"ui-icon-circle-triangle-"+(b?"w":"e")}})}var f=a.fx.speeds,g=".MonthPicker",h={my:"left top+1",at:"left bottom"},i={my:"right top+1",at:"right bottom"},j="MonthPicker Setup Error: ",k=j+"The jQuery UI position plug-in must be loaded in order to specify a position.",l=j+"Unsupported % option value, supported (case sensitive) values are: ",m=j+'"_" is not a valid %Month value.',n={Animation:["slideToggle","fadeToggle","none"],ShowAnim:["fadeIn","slideDown","none"],HideAnim:["fadeOut","slideUp","none"]},o={ValidationErrorMessage:"_createValidationMessage",Disabled:"_setDisabledState",ShowIcon:"_showIcon",Button:"_createButton",ShowOn:"_updateFieldEvents",IsRTL:"_setRTL",StartYear:"_setPickerYear",MinMonth:"_setMinMonth",MaxMonth:"_setMaxMonth"};if(!(a&&a.ui&&a.ui.button&&a.ui.datepicker))return alert(j+"The jQuery UI button and datepicker plug-ins must be loaded before MonthPicker is called."),!1;var p=a.noop,q=a.datepicker,r=null,s=!!a.ui.position;a.MonthPicker={i18n:{year:"Year",prevYear:"Previous Year",nextYear:"Next Year",next5Years:"Jump Forward 5 Years",prev5Years:"Jump Back 5 Years",nextLabel:"Next",prevLabel:"Prev",buttonText:"Open Month Chooser",jumpYears:"Jump Years",months:["Jan.","Feb.","Mar.","Apr.","May","June","July","Aug.","Sep.","Oct.","Nov.","Dec."]}};var t='
';a.widget("KidSysco.MonthPicker",{options:{i18n:{},IsRTL:!1,Position:null,StartYear:null,ShowIcon:!0,UseInputMask:!1,ValidationErrorMessage:null,Disabled:!1,MonthFormat:"mm/yy",Animation:"fadeToggle",ShowAnim:null,HideAnim:null,ShowOn:null,MinMonth:null,MaxMonth:null,Duration:"normal",Button:d,OnAfterSetDisabled:p,ButtonIcon:"ui-icon-calculator",OnBeforeMenuOpen:p,OnAfterMenuOpen:p,OnBeforeMenuClose:p,OnAfterMenuClose:p,OnAfterNextYear:p,OnAfterNextYears:p,OnAfterPreviousYear:p,OnAfterPreviousYears:p,OnAfterChooseMonth:p,OnAfterChooseYear:p,OnAfterChooseYears:p,OnAfterChooseMonths:p},_monthPickerButton:a(),_validationMessage:a(),_destroy:function(){var b=this.element;jQuery.mask&&this.options.UseInputMask&&(b.unmask(),this.GetSelectedDate()||b.val("")),b.removeClass("month-year-input").off(g),a(c).off("click"+g+this.uuid),this._monthPickerMenu.remove();var d=this._monthPickerButton.off("click"+g);this._removeOldBtn&&d.remove(),this._validationMessage.remove()},_setOption:function(b,c){switch(b){case"i18n":c=a.extend({},c);break;case"Position":if(!s)return void alert(k);case"MonthFormat":var d=this.GetSelectedDate();d&&this.element.val(this.FormatMonth(d,c))}return b in n&&-1===n[b].indexOf(c)?void alert(l.replace(/%/,b)+n[b]):(this._super(b,c),void(o[b]?this[o[b]](c):0))},_create:function(){var b=this.element,c=this.options;if(!b.is("input")||-1===["text","month",void 0].indexOf(b.attr("type"))){var d=j+"MonthPicker can only be called on text or month inputs.";return alert(d+" \n\nSee console (developer tools) for more details."),console.error(d+"\n Caused by:"),console.log(b[0]),!1}if(!a.mask&&c.UseInputMask)return alert(j+"The UseInputMask option is set but the Digital Bush Input Mask jQuery Plugin is not loaded. Get the plugin from http://digitalbush.com/"),!1;if(null!==c.Position&&!s)return alert(k),!1;for(var e in n)if(null!==c[e]&&-1===n[e].indexOf(c[e]))return alert(l.replace(/%/,e)+n[e]),!1;this._isMonthInputType="month"===b.attr("type"),this._isMonthInputType&&(this.options.MonthFormat=this.MonthInputFormat,b.css("width","auto")),b.addClass("month-year-input");var f=this._monthPickerMenu=a('
');a(t).appendTo(f),a("body").append(f),a(".year-title",f).text(this._i18n("year")),a(".year-container-all",f).attr("title",this._i18n("jumpYears")),this._createValidationMessage(),this._yearContainer=a(".year",f),this._prevButton=a(".previous-year button",f).button({text:!1}),this._nextButton=a(".next-year button",f).button({text:!1}),this._setRTL(c.IsRTL),a(".ui-button-icon-primary",this._nextButton).text(this._i18n("nextLabel")),a(".ui-button-icon-primary",this._prevButton).text(this._i18n("prevLabel"));for(var h=a(".month-picker-month-table",f),i=0;12>i;i++){var o=i%3?o:a("").appendTo(h);o.append('')}this._buttons=a("button",h).button(),a(".year-container-all",f).click(a.proxy(this._showYearsClickHandler,this)),f.on("click"+g,function(a){return!1});var p=this,q="Month";a.each(["Min","Max"],function(a,b){p["_set"+b+q]=function(a){(p["_"+b+q]=this._toDate(a))===!1&&alert(m.replace(/%/,b).replace(/_/,a))},p._setOption(b+q,p.options[b+q])}),this._setUseInputMask(),this._setDisabledState(),this._updateFieldEvents(),this.Destroy=this.destroy},_i18n:function(b){return this.options.i18n[b]||a.MonthPicker.i18n[b]},GetSelectedDate:function(){return this._parseMonth()},GetSelectedYear:function(){var a=this.GetSelectedDate();return a?a.getFullYear():NaN},GetSelectedMonth:function(){var a=this.GetSelectedDate();return a?a.getMonth()+1:NaN},Validate:function(){var a=this.GetSelectedDate();return null===this.options.ValidationErrorMessage||this.options.Disabled||this._validationMessage[a?"hide":"show"](),a},GetSelectedMonthYear:function(){var a=this.Validate();return a?a.getMonth()+1+"/"+a.getFullYear():null},Disable:function(){this._setOption("Disabled",!0)},Enable:function(){this._setOption("Disabled",!1)},ClearAllCallbacks:function(){for(var a in this.options)0===a.indexOf("On")&&(this.options[a]=p)},Clear:function(){this.element.val(""),this._validationMessage.hide()},Toggle:function(){return this._visible?this.Close():this.Open()},Open:function(b){if(!this.options.Disabled&&!this._visible){var d=this.element,e=this.options;if(b=b||new a.Event,e.OnBeforeMenuOpen.call(d[0],b)===!1||b.isDefaultPrevented())return!1;this._visible=!0,this._ajustYear(e),r&&r.Close(b),r=this;var f=this._monthPickerMenu;this._showMonths(),a(c).on("click"+g+this.uuid,a.proxy(this.Close,this)).on("keydown"+g+this.uuid,a.proxy(this._keyDown,this)),d.off("blur"+g).focus();var h=e.ShowAnim||e.Animation,i="none"===h;f[i?"fadeIn":h]({duration:i?0:this._duration(),start:a.proxy(this._position,this,f),complete:a.proxy(e.OnAfterMenuOpen,d[0])})}return!1},Close:function(b){if(this._visible){var d=this._monthPickerMenu,e=this.options,f=this.element;if(b=b||new a.Event,e.OnBeforeMenuClose.call(f[0],b)===!1||b.isDefaultPrevented())return;this._visible=!1,r=null,a(c).off("keydown"+g+this.uuid).off("click"+g+this.uuid),this.Validate(),f.on("blur"+g,a.proxy(this.Validate,this));var h=a.proxy(e.OnAfterMenuClose,f[0]),i=e.HideAnim||e.Animation;"none"===i?d.hide(0,h):d[i](this._duration(),h)}},SetDisabled:function(a,b){try{b.button("option","disabled",a)}catch(c){b.prop("disabled",a)}},MonthInputFormat:"yy-mm",ParseMonth:function(a,b){try{return q.parseDate("dd"+b,"01"+a)}catch(c){return null}},FormatMonth:function(a,b){try{return q.formatDate(b,a)||null}catch(c){return null}},_parseMonth:function(a){return this.ParseMonth(a||this.element.val(),this.options.MonthFormat)},_formatMonth:function(a){return this.FormatMonth(a||this._parseMonth(),this.options.MonthFormat)},_showIcon:function(){var a=this._monthPickerButton;a.length?a[this.options.ShowIcon?"show":"hide"]():this._createButton(),this._updateFieldEvents()},_createButton:function(){if(this.options.ShowIcon){var b=this._monthPickerButton.off(g),d=this.options.Button,e=this.element;a.isFunction(d)&&(d=d.call(e[0],a.extend(!0,{i18n:a.MonthPicker.i18n},this.options)));var f=!1;this._monthPickerButton=(d instanceof a?d:a(d)).each(function(){a.contains(c.body,this)||(f=!0,a(this).insertAfter(e))}).on("click"+g,a.proxy(this.Toggle,this)),this._removeOldBtn&&b.remove(),this._removeOldBtn=f}},_updateFieldEvents:function(){this.element.off("click"+g),"both"!==this.options.ShowOn&&this._monthPickerButton.length||this.element.on("click"+g,a.proxy(this.Open,this))},_createValidationMessage:function(){var b=this.options.ValidationErrorMessage,c=this.element;if(-1===[null,""].indexOf(b)){var d=a(''+b+""),e=this._monthPickerButton;this._validationMessage=d.insertAfter(e.length?e:c),c.on("blur"+g,a.proxy(this.Validate,this))}else this._validationMessage.remove()},_setRTL:function(a){e(this._prevButton,!a),e(this._nextButton,a)},_keyDown:function(){var b=a.ui.keyCode;switch(event.keyCode){case b.ENTER:this._chooseMonth((new Date).getMonth()+1),this.Close();break;case b.ESCAPE:this.Close()}},_duration:function(){var b=this.options.Duration;return a.isNumeric(b)?b:b in f?f[b]:f._default},_position:s?function(b){var c=this.options.IsRTL?i:h,d=a.extend(c,this.options.Position);return b.position(a.extend({of:this.element},d))}:function(a){var b=this.element,c={top:b.offset().top+b.height()+7+"px"};return this.options.IsRTL?c.left=b.offset().left-a.width()+b.width()+7+"px":c.left=b.offset().left+"px",a.css(c)},_setUseInputMask:function(){if(!this._isMonthInputType)try{this.options.UseInputMask?this.element.mask(this._formatMonth(new Date).replace(/\d/g,9)):this.element.unmask()}catch(a){}},_setDisabledState:function(){var a=this.options.Disabled;this.element[0].disabled=a,this.element[a?"addClass":"removeClass"]("disabled"),a&&this._validationMessage.hide(),this.Close(),this._createButton(),this.SetDisabled(a,this._monthPickerButton),this.options.OnAfterSetDisabled.call(this.element[0],a)},_getPickerYear:function(){return parseInt(this._yearContainer.text(),10)},_setPickerYear:function(a){this._yearContainer.text(a||(new Date).getFullYear())},_chooseMonth:function(a){var b=new Date(this._getPickerYear(),a-1);this.element.val(this._formatMonth(b)).blur(),this.options.OnAfterChooseMonth.call(this.element[0])},_chooseYear:function(a){this._setPickerYear(a),this._showMonths(),this.options.OnAfterChooseYear.call(this.element[0])},_showMonths:function(){var b=this._i18n("months");this._prevButton.attr("title",this._i18n("prevYear")).off("click"+g).on("click"+g,a.proxy(this._addToYear,this,-1)),this._nextButton.attr("title",this._i18n("nextYear")).off("click"+g).on("click"+g,a.proxy(this._addToYear,this,1)),a(".year-container-all",this._monthPickerMenu).css("cursor","pointer"),this._buttons.off(g);var c=this,d=a.proxy(c._onMonthClick,c);a.each(b,function(b,e){a(c._buttons[b]).on("click"+g,{month:b+1},d).button("option","label",e)}),this._enableMonthButtons()},_showYearsClickHandler:function(){this._showYears(),this.options.OnAfterChooseYears.call(this.element[0])},_showYears:function(){var b=this._getPickerYear(),c=-4,d=b+c,e=5,f=this._MinMonth,h=this._MaxMonth;_minYear=f?f.getFullYear():0,_maxYear=h?h.getFullYear():0,this._prevButton.attr("title",this._i18n("prev5Years")).off("click"+g).on("click"+g,a.proxy(this._addToYears,this,-e)).button("option","disabled",_minYear&&d-1<_minYear),this._nextButton.attr("title",this._i18n("next5Years")).off("click"+g).on("click"+g,a.proxy(this._addToYears,this,e)).button("option","disabled",_maxYear&&d+12-1>_maxYear),a(".year-container-all",this._monthPickerMenu).css("cursor","default"),this._buttons.off(g);for(var i=a.proxy(this._onYearClick,this),j=0;12>j;j++){var k=b+c,l=a(this._buttons[j]);l.on("click"+g,{year:k},i).button("option","label",k),a(this._buttons[j]).button("option","disabled",_minYear&&k<_minYear||_maxYear&&k>_maxYear),c++}},_onMonthClick:function(a){this._chooseMonth(a.data.month),this.Close()},_onYearClick:function(a){this._chooseYear(a.data.year)},_addToYear:function(a){var b=this._yearContainer;b.text(parseInt(b.text())+a,10),this.element.focus(),this._enableMonthButtons(),this.options["OnAfter"+(a>0?"Next":"Previous")+"Year"].call(this.element[0])},_addToYears:function(a){var b=this._yearContainer;b.text(parseInt(b.text())+a,10),this._showYears(),this.element.focus(),this.options["OnAfter"+(a>0?"Next":"Previous")+"Years"].call(this.element[0])},_ajustYear:function(a){var b=a.StartYear||this.GetSelectedYear()||(new Date).getFullYear();null!==this._MinMonth&&(b=Math.max(this._MinMonth.getFullYear(),b)),null!==this._MaxMonth&&(b=Math.min(this._MaxMonth.getFullYear(),b)),this._setPickerYear(b)},_enableMonthButtons:function(){var b=this._getPickerYear(),c=this._MinMonth,d=this._MaxMonth;this._prevButton.button("option","disabled",c&&b==c.getFullYear()),this._nextButton.button("option","disabled",d&&b==d.getFullYear());for(var e=0;12>e;e++)a(this._buttons[e]).button("option","disabled",c&&new Date(b,e,1)d)},_toDate:function(b){if(null===b)return b;if(b instanceof Date)return b=new Date(b.getTime()),b.setDate(0),b;if(a.isNumeric(b)){var c=new Date;return c.setMonth(c.getMonth()+parseInt(b,10)),c.setDate(0),c}var c=this._parseMonth(b);return c?c:this._parsePeriod(b)},_parsePeriod:function(a,b){var c=a.trim();c=c.replace(/y/i,'":"y"'),c=c.replace(/m/i,'":"m"');try{var d=JSON.parse('{"'+c.replace(/ /g,',"')+"}"),e={};for(var f in d)e[d[f]]=f;var g=new Date;return g.setFullYear(g.getFullYear()+(parseInt(e.y,10)||0)),g.setMonth(g.getMonth()+(parseInt(e.m,10)||0)),g.setDate(0),g}catch(h){return!1}}}),a.MonthPicker.VERSION="2.6.1"}(jQuery,window,document); \ No newline at end of file +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b,c=navigator.userAgent,d=/iphone/i.test(c),e=/chrome/i.test(c),f=/android/i.test(c);a.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},autoclear:!0,dataName:"rawMaskFn",placeholder:"_"},a.fn.extend({caret:function(a,b){var c;return 0===this.length||this.is(":hidden")?void 0:"number"==typeof a?(b="number"==typeof b?b:a,this.each(function(){this.setSelectionRange?this.setSelectionRange(a,b):this.createTextRange&&(c=this.createTextRange(),c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",a),c.select())})):(this[0].setSelectionRange?(a=this[0].selectionStart,b=this[0].selectionEnd):document.selection&&document.selection.createRange&&(c=document.selection.createRange(),a=0-c.duplicate().moveStart("character",-1e5),b=a+c.text.length),{begin:a,end:b})},unmask:function(){return this.trigger("unmask")},mask:function(c,g){var h,i,j,k,l,m,n,o;if(!c&&this.length>0){h=a(this[0]);var p=h.data(a.mask.dataName);return p?p():void 0}return g=a.extend({autoclear:a.mask.autoclear,placeholder:a.mask.placeholder,completed:null},g),i=a.mask.definitions,j=[],k=n=c.length,l=null,a.each(c.split(""),function(a,b){"?"==b?(n--,k=a):i[b]?(j.push(new RegExp(i[b])),null===l&&(l=j.length-1),k>a&&(m=j.length-1)):j.push(null)}),this.trigger("unmask").each(function(){function h(){if(g.completed){for(var a=l;m>=a;a++)if(j[a]&&C[a]===p(a))return;g.completed.call(B)}}function p(a){return g.placeholder.charAt(a=0&&!j[a];);return a}function s(a,b){var c,d;if(!(0>a)){for(c=a,d=q(b);n>c;c++)if(j[c]){if(!(n>d&&j[c].test(C[d])))break;C[c]=C[d],C[d]=p(d),d=q(d)}z(),B.caret(Math.max(l,a))}}function t(a){var b,c,d,e;for(b=a,c=p(a);n>b;b++)if(j[b]){if(d=q(b),e=C[b],C[b]=c,!(n>d&&j[d].test(e)))break;c=e}}function u(){var a=B.val(),b=B.caret();if(o&&o.length&&o.length>a.length){for(A(!0);b.begin>0&&!j[b.begin-1];)b.begin--;if(0===b.begin)for(;b.beging)&&g&&13!==g){if(i.end-i.begin!==0&&(y(i.begin,i.end),s(i.begin,i.end-1)),c=q(i.begin-1),n>c&&(d=String.fromCharCode(g),j[c].test(d))){if(t(c),C[c]=d,z(),e=q(c),f){var k=function(){a.proxy(a.fn.caret,B,e)()};setTimeout(k,0)}else B.caret(e);i.begin<=m&&h()}b.preventDefault()}}}function y(a,b){var c;for(c=a;b>c&&n>c;c++)j[c]&&(C[c]=p(c))}function z(){B.val(C.join(""))}function A(a){var b,c,d,e=B.val(),f=-1;for(b=0,d=0;n>b;b++)if(j[b]){for(C[b]=p(b);d++e.length){y(b+1,n);break}}else C[b]===e.charAt(d)&&d++,k>b&&(f=b);return a?z():k>f+1?g.autoclear||C.join("")===D?(B.val()&&B.val(""),y(0,n)):z():(z(),B.val(B.val().substring(0,f+1))),k?b:l}var B=a(this),C=a.map(c.split(""),function(a,b){return"?"!=a?i[a]?p(b):a:void 0}),D=C.join(""),E=B.val();B.data(a.mask.dataName,function(){return a.map(C,function(a,b){return j[b]&&a!=p(b)?a:null}).join("")}),B.one("unmask",function(){B.off(".mask").removeData(a.mask.dataName)}).on("focus.mask",function(){if(!B.prop("readonly")){clearTimeout(b);var a;E=B.val(),a=A(),b=setTimeout(function(){B.get(0)===document.activeElement&&(z(),a==c.replace("?","").length?B.caret(0,a):B.caret(a))},10)}}).on("blur.mask",v).on("keydown.mask",w).on("keypress.mask",x).on("input.mask paste.mask",function(){B.prop("readonly")||setTimeout(function(){var a=A(!0);B.caret(a),h()},0)}),e&&f&&B.off("input.mask").on("input.mask",u),A()})}})}),function(a,b,c){"use strict";function d(a){return a.getMonth()+12*a.getFullYear()}function e(a){return Math.floor(a/12)}function f(b){return a(''+b.i18n.buttonText+"").button({text:!1,icons:{primary:b.ButtonIcon}})}function g(a,b){a.button("option",{icons:{primary:"ui-icon-circle-triangle-"+(b?"w":"e")}})}var h=a.fx.speeds,i=".MonthPicker",j={my:"left top+1",at:"left bottom"},k={my:"right top+1",at:"right bottom"},l="MonthPicker Setup Error: ",m=l+"The jQuery UI position plug-in must be loaded in order to specify a position.",n=l+"Unsupported % option value, supported (case sensitive) values are: ",o=l+'"_" is not a valid %Month value.',p={Animation:["slideToggle","fadeToggle","none"],ShowAnim:["fadeIn","slideDown","none"],HideAnim:["fadeOut","slideUp","none"]},q={ValidationErrorMessage:"_createValidationMessage",Disabled:"_setDisabledState",ShowIcon:"_showIcon",Button:"_createButton",ShowOn:"_updateFieldEvents",IsRTL:"_setRTL",StartYear:"_setPickerYear",MinMonth:"_setMinMonth",MaxMonth:"_setMaxMonth"};if(!(a&&a.ui&&a.ui.button&&a.ui.datepicker))return alert(l+"The jQuery UI button and datepicker plug-ins must be loaded before MonthPicker is called."),!1;var r=a.noop,s=a.datepicker,t=null,u=!!a.ui.position;a.MonthPicker={i18n:{year:"Year",prevYear:"Previous Year",nextYear:"Next Year",next5Years:"Jump Forward 5 Years",prev5Years:"Jump Back 5 Years",nextLabel:"Next",prevLabel:"Prev",buttonText:"Open Month Chooser",jumpYears:"Jump Years",months:["Jan.","Feb.","Mar.","Apr.","May","June","July","Aug.","Sep.","Oct.","Nov.","Dec."]}};var v='
';a.widget("KidSysco.MonthPicker",{options:{i18n:{},IsRTL:!1,Position:null,StartYear:null,ShowIcon:!0,UseInputMask:!1,ValidationErrorMessage:null,Disabled:!1,MonthFormat:"mm/yy",Animation:"fadeToggle",ShowAnim:null,HideAnim:null,ShowOn:null,MinMonth:null,MaxMonth:null,Duration:"normal",Button:f,OnAfterSetDisabled:r,ButtonIcon:"ui-icon-calculator",OnBeforeMenuOpen:r,OnAfterMenuOpen:r,OnBeforeMenuClose:r,OnAfterMenuClose:r,OnAfterNextYear:r,OnAfterNextYears:r,OnAfterPreviousYear:r,OnAfterPreviousYears:r,OnAfterChooseMonth:r,OnAfterChooseYear:r,OnAfterChooseYears:r,OnAfterChooseMonths:r},_monthPickerButton:a(),_validationMessage:a(),_destroy:function(){var b=this.element;jQuery.mask&&this.options.UseInputMask&&(b.unmask(),this.GetSelectedDate()||b.val("")),b.removeClass("month-year-input").off(i),a(c).off("click"+i+this.uuid),this._monthPickerMenu.remove();var d=this._monthPickerButton.off("click"+i);this._removeOldBtn&&d.remove(),this._validationMessage.remove()},_setOption:function(b,c){switch(b){case"i18n":c=a.extend({},c);break;case"Position":if(!u)return void alert(m);case"MonthFormat":var d=this.GetSelectedDate();d&&this.element.val(this.FormatMonth(d,c))}return b in p&&-1===p[b].indexOf(c)?void alert(n.replace(/%/,b)+p[b]):(this._super(b,c),void(q[b]?this[q[b]](c):0))},_create:function(){var b=this.element,c=this.options;if(!b.is("input")||-1===["text","month",void 0].indexOf(b.attr("type"))){var d=l+"MonthPicker can only be called on text or month inputs.";return alert(d+" \n\nSee console (developer tools) for more details."),console.error(d+"\n Caused by:"),console.log(b[0]),!1}if(!a.mask&&c.UseInputMask)return alert(l+"The UseInputMask option is set but the Digital Bush Input Mask jQuery Plugin is not loaded. Get the plugin from http://digitalbush.com/"),!1;if(null!==c.Position&&!u)return alert(m),!1;for(var e in p)if(null!==c[e]&&-1===p[e].indexOf(c[e]))return alert(n.replace(/%/,e)+p[e]),!1;this._isMonthInputType="month"===b.attr("type"),this._isMonthInputType&&(this.options.MonthFormat=this.MonthInputFormat,b.css("width","auto")),b.addClass("month-year-input");var f=this._monthPickerMenu=a('
');a(v).appendTo(f),a("body").append(f),a(".year-title",f).text(this._i18n("year")),a(".year-container-all",f).attr("title",this._i18n("jumpYears")),this._createValidationMessage(),this._yearContainer=a(".year",f),this._prevButton=a(".previous-year button",f).button({text:!1}),this._nextButton=a(".next-year button",f).button({text:!1}),this._setRTL(c.IsRTL),a(".ui-button-icon-primary",this._nextButton).text(this._i18n("nextLabel")),a(".ui-button-icon-primary",this._prevButton).text(this._i18n("prevLabel"));for(var g=a(".month-picker-month-table",f),h=0;12>h;h++){var j=h%3?j:a("").appendTo(g);j.append('')}this._buttons=a("button",g).button(),a(".year-container-all",f).click(a.proxy(this._showYearsClickHandler,this)),f.on("click"+i,function(a){return!1});var k=this,q="Month";a.each(["Min","Max"],function(a,b){k["_set"+b+q]=function(a){(k["_"+b+q]=this._toMonth(a))===!1&&alert(o.replace(/%/,b).replace(/_/,a))},k._setOption(b+q,k.options[b+q])}),this._setUseInputMask(),this._setDisabledState(),this._updateFieldEvents(),this.Destroy=this.destroy},_i18n:function(b){return this.options.i18n[b]||a.MonthPicker.i18n[b]},GetSelectedDate:function(){return this._parseMonth()},GetSelectedYear:function(){var a=this.GetSelectedDate();return a?a.getFullYear():NaN},GetSelectedMonth:function(){var a=this.GetSelectedDate();return a?a.getMonth()+1:NaN},Validate:function(){var a=this.GetSelectedDate();return null===this.options.ValidationErrorMessage||this.options.Disabled||this._validationMessage[a?"hide":"show"](),a},GetSelectedMonthYear:function(){var a=this.Validate();return a?a.getMonth()+1+"/"+a.getFullYear():null},Disable:function(){this._setOption("Disabled",!0)},Enable:function(){this._setOption("Disabled",!1)},ClearAllCallbacks:function(){for(var a in this.options)0===a.indexOf("On")&&(this.options[a]=r)},Clear:function(){this.element.val(""),this._validationMessage.hide()},Toggle:function(a){return this._visible?this.Close(a):this.Open(a)},Open:function(b){if(!this.options.Disabled&&!this._visible){var d=this.element,e=this.options;if(b=b||new a.Event,e.OnBeforeMenuOpen.call(d[0],b)===!1||b.isDefaultPrevented())return!1;this._visible=!0,this._ajustYear(e),t&&t.Close(b),t=this;var f=this._monthPickerMenu;this._showMonths(),a(c).on("click"+i+this.uuid,a.proxy(this.Close,this)).on("keydown"+i+this.uuid,a.proxy(this._keyDown,this)),d.off("blur"+i).focus();var g=e.ShowAnim||e.Animation,h="none"===g;f[h?"fadeIn":g]({duration:h?0:this._duration(),start:a.proxy(this._position,this,f),complete:a.proxy(e.OnAfterMenuOpen,d[0])})}return!1},Close:function(b){if(this._visible){var d=this._monthPickerMenu,e=this.options,f=this.element;if(b=b||new a.Event,e.OnBeforeMenuClose.call(f[0],b)===!1||b.isDefaultPrevented())return;this._visible=!1,t=null,a(c).off("keydown"+i+this.uuid).off("click"+i+this.uuid),this.Validate(),f.on("blur"+i,a.proxy(this.Validate,this));var g=a.proxy(e.OnAfterMenuClose,f[0]),h=e.HideAnim||e.Animation;"none"===h?d.hide(0,g):d[h](this._duration(),g)}},SetDisabled:function(a,b){try{b.button("option","disabled",a)}catch(c){b.prop("disabled",a)}},MonthInputFormat:"yy-mm",ParseMonth:function(a,b){try{return s.parseDate("dd"+b,"01"+a)}catch(c){return null}},FormatMonth:function(a,b){try{return s.formatDate(b,a)||null}catch(c){return null}},_parseMonth:function(a){return this.ParseMonth(a||this.element.val(),this.options.MonthFormat)},_formatMonth:function(a){return this.FormatMonth(a||this._parseMonth(),this.options.MonthFormat)},_showIcon:function(){var a=this._monthPickerButton;a.length?a[this.options.ShowIcon?"show":"hide"]():this._createButton(),this._updateFieldEvents()},_createButton:function(){if(this.options.ShowIcon){var b=this._monthPickerButton.off(i),d=this.options.Button,e=this.element;a.isFunction(d)&&(d=d.call(e[0],a.extend(!0,{i18n:a.MonthPicker.i18n},this.options)));var f=!1;this._monthPickerButton=(d instanceof a?d:a(d)).each(function(){a.contains(c.body,this)||(f=!0,a(this).insertAfter(e))}).on("click"+i,a.proxy(this.Toggle,this)),this._removeOldBtn&&b.remove(),this._removeOldBtn=f}},_updateFieldEvents:function(){this.element.off("click"+i),"both"!==this.options.ShowOn&&this._monthPickerButton.length||this.element.on("click"+i,a.proxy(this.Open,this))},_createValidationMessage:function(){var b=this.options.ValidationErrorMessage,c=this.element;if(-1===[null,""].indexOf(b)){var d=a(''+b+""),e=this._monthPickerButton;this._validationMessage=d.insertAfter(e.length?e:c),c.on("blur"+i,a.proxy(this.Validate,this))}else this._validationMessage.remove()},_setRTL:function(a){g(this._prevButton,!a),g(this._nextButton,a)},_keyDown:function(){var b=a.ui.keyCode;switch(event.keyCode){case b.ENTER:this._chooseMonth((new Date).getMonth()+1),this.Close();break;case b.ESCAPE:this.Close()}},_duration:function(){var b=this.options.Duration;return a.isNumeric(b)?b:b in h?h[b]:h._default},_position:u?function(b){var c=this.options.IsRTL?k:j,d=a.extend(c,this.options.Position);return b.position(a.extend({of:this.element},d))}:function(a){var b=this.element,c={top:b.offset().top+b.height()+7+"px"};return this.options.IsRTL?c.left=b.offset().left-a.width()+b.width()+7+"px":c.left=b.offset().left+"px",a.css(c)},_setUseInputMask:function(){if(!this._isMonthInputType)try{this.options.UseInputMask?this.element.mask(this._formatMonth(new Date).replace(/\d/g,9)):this.element.unmask()}catch(a){}},_setDisabledState:function(){var a=this.options.Disabled;this.element[0].disabled=a,this.element[a?"addClass":"removeClass"]("disabled"),a&&this._validationMessage.hide(),this.Close(),this._createButton(),this.SetDisabled(a,this._monthPickerButton),this.options.OnAfterSetDisabled.call(this.element[0],a)},_getPickerYear:function(){return parseInt(this._yearContainer.text(),10)},_setPickerYear:function(a){this._yearContainer.text(a||(new Date).getFullYear())},_chooseMonth:function(a){var b=new Date(this._getPickerYear(),a-1);this.element.val(this._formatMonth(b)).blur(),this.options.OnAfterChooseMonth.call(this.element[0])},_chooseYear:function(a){this._setPickerYear(a),this._showMonths(),this.options.OnAfterChooseYear.call(this.element[0])},_showMonths:function(){var b=this._i18n("months");this._prevButton.attr("title",this._i18n("prevYear")).off("click"+i).on("click"+i,a.proxy(this._addToYear,this,-1)),this._nextButton.attr("title",this._i18n("nextYear")).off("click"+i).on("click"+i,a.proxy(this._addToYear,this,1)),a(".year-container-all",this._monthPickerMenu).css("cursor","pointer"),this._buttons.off(i);var c=this,d=a.proxy(c._onMonthClick,c);a.each(b,function(b,e){a(c._buttons[b]).on("click"+i,{month:b+1},d).button("option","label",e)}),this._enableMonthButtons()},_showYearsClickHandler:function(){this._showYears(),this.options.OnAfterChooseYears.call(this.element[0])},_showYears:function(){var b=this._getPickerYear(),c=-4,d=b+c,f=5,g=this._MinMonth,h=this._MaxMonth,j=g?e(g):0,k=h?e(h):0;this._prevButton.attr("title",this._i18n("prev5Years")).off("click"+i).on("click"+i,a.proxy(this._addToYears,this,-f)).button("option","disabled",j&&j>d-1),this._nextButton.attr("title",this._i18n("next5Years")).off("click"+i).on("click"+i,a.proxy(this._addToYears,this,f)).button("option","disabled",k&&d+12-1>k),a(".year-container-all",this._monthPickerMenu).css("cursor","default"),this._buttons.off(i);for(var l=a.proxy(this._onYearClick,this),m=0;12>m;m++){var n=b+c,o=a(this._buttons[m]);o.on("click"+i,{year:n},l).button("option","label",n),a(this._buttons[m]).button("option","disabled",j&&j>n||k&&n>k),c++}},_onMonthClick:function(a){this._chooseMonth(a.data.month),this.Close(a)},_onYearClick:function(a){this._chooseYear(a.data.year)},_addToYear:function(a){var b=this._yearContainer;b.text(parseInt(b.text())+a,10),this.element.focus(),this._enableMonthButtons(),this.options["OnAfter"+(a>0?"Next":"Previous")+"Year"].call(this.element[0])},_addToYears:function(a){var b=this._yearContainer;b.text(parseInt(b.text())+a,10),this._showYears(),this.element.focus(),this.options["OnAfter"+(a>0?"Next":"Previous")+"Years"].call(this.element[0])},_ajustYear:function(a){var b=a.StartYear||this.GetSelectedYear()||(new Date).getFullYear();null!==this._MinMonth&&(b=Math.max(e(this._MinMonth),b)),null!==this._MaxMonth&&(b=Math.min(e(this._MaxMonth),b)),this._setPickerYear(b)},_enableMonthButtons:function(){var b=this._getPickerYear(),c=this._MinMonth,d=this._MaxMonth;this._prevButton.button("option","disabled",c&&b==e(c)),this._nextButton.button("option","disabled",d&&b==e(d));for(var f=0;12>f;f++){var g=12*b+f;a(this._buttons[f]).button("option","disabled",c&&c>g||d&&g>d)}},_toMonth:function(b){if(null===b)return b;if(b instanceof Date)return d(b);if(a.isNumeric(b))return d(new Date)+parseInt(b,10);var c=this._parseMonth(b);return c?d(c):this._parsePeriod(b)},_parsePeriod:function(a,b){var c=a.trim();c=c.replace(/y/i,'":"y"'),c=c.replace(/m/i,'":"m"');try{var e=JSON.parse('{"'+c.replace(/ /g,',"')+"}"),f={};for(var g in e)f[e[g]]=g;var h=d(new Date);return h+=parseInt(f.m,10)||0,h+12*(parseInt(f.y,10)||0)}catch(i){return!1}}}),a.MonthPicker.VERSION="2.6.2"}(jQuery,window,document); \ No newline at end of file diff --git a/test/test.html b/test/test.html index 69ebc68..d0bcbf2 100644 --- a/test/test.html +++ b/test/test.html @@ -55,9 +55,7 @@

Version @VERSION

-

Button Demonstration - -
This demonstrates the plugin's default behaviour. +

Button test

Choose a Month: @@ -76,12 +74,31 @@

Version @VERSION


No button: +
+
ShowOn both: +

Month format test Choose a Month:

+

Min/MaxMonth test Choose a Month: + +

+ +

Right to left Choose a Month: + +

+ +

Toggle method test Choose a Month: + +

+ +

Events Choose a Month: + +

+

Only one picker open test First picker:
Second picker: @@ -163,14 +180,6 @@

Version @VERSION

-

jQuery UI Dialog Integration Demonstration - -
This demonstrates the Month Picker running inside of the jQuery UI Modal Dialog. -
-
- -

-

HTML 5 Month Input Type Support
This demonstrates how the MonthPicker will work with the HTML 5 Month Input Type. View this section using Chrome @@ -184,10 +193,6 @@

Version @VERSION

- -

qUnit Testing Output

diff --git a/test/test.js b/test/test.js index 3daec33..6cb846b 100644 --- a/test/test.js +++ b/test/test.js @@ -270,16 +270,6 @@ QUnit.test('API Tests', function (assert) { assert.equal(_picker.prop('disabled'), true, '#EnableDisableDemo was disabled using the Disable() API call.'); _picker.MonthPicker('Enable'); assert.equal(_picker.prop('disabled'), false, '#EnableDisableDemo was enabled using the Disable() API call.'); - - _picker = $('#DialogDemo').MonthPicker(); - - $('#Modal').dialog({ - autoOpen: false, - title: 'MonthPicker Dialog Test', - modal: true - }); - - assert.ok($('#MonthPicker_DialogDemo').length === 1, '#DialogDemo initialized, manually test the MonthPicker behavior in the dialog.'); }); QUnit.test('Digital Bush Tests', function (assert) { @@ -346,6 +336,195 @@ QUnit.test('MonthFormat Option Tests', function (assert) { assert.equal($(FormatField).val(), 'April 2012', 'The text field has the value April 2012'); }); +// Makes sure that all events are triggered as expected. +// Perhaps we should consider removing some of these events. +QUnit.test('Events and context', function (assert) { // A.k.a duplicate code test. + // Good luck figuring out which callback is causing the + // problem if this test fails. + assert.expect(27); + + var field = $(EventsField).MonthPicker({ + Animation: 'none', // Disable animation to make sure opening and closing the menu is synchronous. + ShowOn: 'both' + }); + + var menu = $(MonthPicker_EventsField); + var OnBeforeMenuOpenTriggred = false; + // This event should be triggered twice, the first time it is prevented + // and the sceond time it goes through. + field.MonthPicker('option', 'OnBeforeMenuOpen', function(event) { + OnBeforeMenuOpenTriggred = true; + assert.equal( this, EventsField, 'OnBeforeMenuOpen was called in the right context' ); + + // Prevent opening if the event was triggered on the input field. + if (event.target === EventsField) { + event.preventDefault(); + } + }); + + // Make sure the open event triggered by clicking the field was prevented. + field.trigger('click'); + assert.ok(OnBeforeMenuOpenTriggred, 'The OnBeforeMenuOpen event was triggered'); + assert.notOk( menu.is(':visible'), 'The open event was prevented when clicking on the field' ); + + var OnAfterMenuOpenTriggred = false; + field.MonthPicker('option', 'OnAfterMenuOpen', function() { + OnAfterMenuOpenTriggred = true; + assert.equal( this, EventsField, 'OnAfterMenuOpen was called in the right context' ); + }); + + // Make sure calling the open method doesn't get prevented. + field.MonthPicker('Open'); + assert.ok(OnAfterMenuOpenTriggred, 'The OnAfterMenuOpen event was triggered'); + assert.ok( menu.is(':visible'), 'The menu was opend by calling the Open method' ); + + // Start duplicate code + var OnAfterNextYearTriggered = false; + field.MonthPicker('option', 'OnAfterNextYear', function() { + OnAfterNextYearTriggered = true; + + assert.equal( this, EventsField, 'OnAfterNextYear was called in the right context' ); + }); + + var nextYearButton = menu.find('.next-year>button'); + nextYearButton.trigger('click'); + assert.ok(OnAfterNextYearTriggered, 'Clicking the next button triggered OnAfterNextYear'); + + var OnAfterPreviousYearTriggerd = false; + field.MonthPicker('option', 'OnAfterPreviousYear', function() { + OnAfterPreviousYearTriggerd = true; + + assert.equal( this, EventsField, 'OnAfterPreviousYear was called in the right context' ); + }); + + var previousYearButton = menu.find('.previous-year>button'); + previousYearButton.trigger('click'); + assert.ok(OnAfterPreviousYearTriggerd, 'Clciking rhe previous button triggered OnAfterPreviousYear'); + + var OnAfterChooseYearsTriggerd = false; + field.MonthPicker('option', 'OnAfterChooseYears', function() { + OnAfterChooseYearsTriggerd = true; + assert.equal( this, EventsField, 'OnAfterChooseYears was called in the right context' ); + }); + + var showYearsButton = menu.find('.year-container-all'); + showYearsButton.trigger('click'); + + assert.ok(OnAfterChooseYearsTriggerd, 'Clicking the show years button triggered OnAfterChooseYears'); + + var OnAfterNextYearsTriggered = false; + field.MonthPicker('option', 'OnAfterNextYears', function() { + OnAfterNextYearsTriggered = true; + assert.equal( this, EventsField, 'OnAfterNextYears was called in the right context' ); + }); + + nextYearButton.trigger('click'); + assert.ok(OnAfterChooseYearsTriggerd, 'Clicking the next button triggered the OnAfterNextYears event'); + + var OnAfterPreviousYearsTriggered = false; + field.MonthPicker('option', 'OnAfterPreviousYears', function() { + OnAfterPreviousYearsTriggered = true; + assert.equal( this, EventsField, 'OnAfterPreviousYears was called in the right context' ); + }); + + previousYearButton.trigger('click'); + assert.ok(OnAfterPreviousYearsTriggered, 'Clicking the prev button triggered the OnAfterPreviousYears event'); + + var OnAfterChooseYearTriggered = false; + field.MonthPicker('option', 'OnAfterChooseYear', function() { + OnAfterChooseYearTriggered = true; + assert.equal( this, EventsField, 'OnAfterChooseYear was called in the right context' ); + }); + + menu.find('.button-1').trigger('click'); + assert.ok(OnAfterChooseYearTriggered, 'Clicking a year triggered OnAfterChooseYear'); + + var OnAfterChooseMonthTriggered = false; + field.MonthPicker('option', 'OnAfterChooseMonth', function() { + OnAfterChooseMonthTriggered = true; + assert.equal( this, EventsField, 'OnAfterChooseMonth was called in the right context' ); + }); + // End duplicate code + + // This event should be triggered twice, the first time it is prevented + // and the sceond time it goes through. + field.MonthPicker('option', 'OnBeforeMenuClose', function(event) { + assert.equal( this, EventsField, 'OnBeforeMenuClose was called in the right context' ); + + var target = event.target, btn1 = menu.find('.button-1')[0]; + if (event.target === btn1) { + event.preventDefault(); + } + }); + + // Click January which should triger the OnAfterChooseMonth event + // but the OnBeforeMenuClose will be prevented. + menu.find('.button-1').trigger('click'); + assert.ok(OnAfterChooseMonthTriggered, 'Clicking January triggered OnAfterChooseMonth'); + assert.ok( menu.is(':visible'), 'The close event was canceled' ); + field.MonthPicker('option', 'OnAfterChooseMonth', $.noop); + + var OnAfterMenuCloseTriggered = false; + field.MonthPicker('option', 'OnAfterMenuClose', function(event) { + OnAfterMenuCloseTriggered = true; + assert.equal( this, EventsField, 'OnAfterMenuClose was called in the right context' ); + }); + + // Clicking May should not be prevented. + menu.find('.button-5').trigger('click'); + assert.ok( !menu.is(':visible'), 'Clicking May closed the menu' ); + assert.ok(OnAfterMenuCloseTriggered, 'Clicking May triggered the OnAfterMenuClose event'); + + field.MonthPicker('ClearAllCallbacks'); +}); + +QUnit.test('Right to left', function (assert) { + var field = $(RTLField).MonthPicker({ + Animation: 'none', // Disable animation to make sure opening and closing the menu is synchronous. + Position: {collision: 'none'}, // Ensure the menu opens to the right. + IsRTL: true + }); + + field.MonthPicker('Open'); + + var menu = $(MonthPicker_RTLField); + + var nextYearButton = menu.find('.next-year>button'); + var previousYearButton = menu.find('.previous-year>button'); + + // Make sure the buttons are pointing in the right (opposite) direction. + assert.ok(previousYearButton.find('span.ui-icon-circle-triangle-e').length, 'Previous button is pointed east'); + assert.ok(nextYearButton.find('span.ui-icon-circle-triangle-w').length, 'Next button is pointed west'); + + // Make sure the menu opens to the right of the field. + var opendToTheRight = (field.position().left - menu.position().left) > 100; + assert.ok(opendToTheRight, 'The menu opened to the right of rhe field'); + + field.MonthPicker('Close'); +}); + +QUnit.test('Toggle method', function (assert) { + var field = $(ToggleField).MonthPicker({ + Animation: 'none', // Disable animation to make sure opening and closing the menu is synchronous. + }); + + field.MonthPicker('Toggle'); + + var menu = $(MonthPicker_ToggleField); + + assert.ok(menu.is(':visible'), 'The menu was opened'); + + field.MonthPicker('Toggle'); + + assert.ok(!menu.is(':visible'), 'The menu was closed'); + + field.MonthPicker('Toggle'); + + assert.ok(menu.is(':visible'), 'The menu was again'); + + field.MonthPicker('Close'); +}); + QUnit.module("Button option"); QUnit.test('Plain HTML Button test', function (assert) { @@ -561,3 +740,447 @@ QUnit.test('Disable button', function (assert) { $(NoButtonField).MonthPicker('ClearAllCallbacks'); $(NoButtonField).MonthPicker('Close'); }); + +QUnit.test('ShowOn both', function (assert) { + var field = $(ShowOnBothField).MonthPicker({ + Animation: 'none', // Disable animation to make sure opening and closing the menu is synchronous. + Button: '', + ShowOn: 'both' + }); + + field.trigger('click'); + + var menu = $(MonthPicker_ShowOnBothField); + + assert.ok(menu.is(':visible'), 'The menu was opened by clicking on the input field'); + + field.MonthPicker('Close'); + + assert.ok(!menu.is(':visible'), 'The menu was closed'); + + $(ShowOnBtn).trigger('click'); + assert.ok(menu.is(':visible'), 'The menu was opened by clicking on the button'); + + field.MonthPicker('Close'); +}); + +QUnit.module("Min/MaxMonth"); + +QUnit.test('Month buttons are disabled', function (assert) { + var field = $(RistrictMonthField).val('12/2015').MonthPicker({ + Animation: 'none', // Disable animation to make sure opening and closing the menu is synchronous. + + MinMonth: '10/2015' + }); + + field.MonthPicker('Open'); + + var menu = $(MonthPicker_RistrictMonthField); + var previousYearButton = menu.find('.previous-year>button'); + var nextYearButton = menu.find('.next-year>button'); + + + // Try to click the disabled buttons. + var buttons = menu.find('.month-picker-month-table button'); + $(buttons.slice(0, 8)).trigger('click'); + + assert.ok(previousYearButton.is('.ui-button-disabled'), 'The previous year button is disabled'); + + // Make sure that the date didn't change as a + // result of clicking the disabled button. + var selectedMonth = field.MonthPicker('GetSelectedDate'); + assert.equal( selectedMonth.getFullYear(), 2015, 'The selected year is still 2015'); + assert.equal( selectedMonth.getMonth() + 1, 12, 'The selected month is still December'); + assert.equal( field.val(), '12/2015', 'The input field still has the value 12/2015' ); + + // Make sure we can still go to the next year. + nextYearButton.trigger('click'); + var pickerYear = parseInt(menu.find('.year').text(), 10); + assert.equal(pickerYear, 2016, 'Clicking next year changed the year to 2016'); + + // Make none of the buttons are disabled. + assert.ok( !menu.find('button').is('.ui-button-disabled'), 'None of the buttons are disabled'); + + // Make sure clicking the first button selected January 2016. + menu.find('.button-1').trigger('click'); + var selectedMonth = field.MonthPicker('GetSelectedDate'); + assert.equal( selectedMonth.getFullYear(), 2016, 'The selected year is still 2016'); + assert.equal( selectedMonth.getMonth() + 1, 1, 'The selected month is still January'); + assert.equal( field.val(), '01/2016', 'The input field has the value 01/2016' ); + + // Make sure we can only go back to 2015 a.k.a the minimum year. + previousYearButton.trigger('click'); + previousYearButton.trigger('click'); + + var pickerYear = parseInt(menu.find('.year').text(), 10); + assert.equal(pickerYear, 2015, 'clicking previous year tweice keept the year at 2015'); + + // Make sure that month buttons before October (the minimum month) + // are still disabled after navigating back to 2015 + // by clicking the buttons and checking that the + // selected date didn't change. + $(buttons.slice(0, 8)).trigger('click'); + + var selectedMonth = field.MonthPicker('GetSelectedDate'); + assert.equal( selectedMonth.getFullYear(), 2016, "Clciking the buttons didn't change the selected year"); + assert.equal( selectedMonth.getMonth() + 1, 1, "Clciking the buttons didn't change the selected month"); + assert.equal( field.val(), '01/2016', "Clciking the buttons didn't change the fields value" ); + + // Make sure the buttons after October (the minumum month) are enabled. + var buttonsDisabled = $( buttons.slice(9) ).is('.ui-button-disabled'); + assert.notOk(buttonsDisabled, 'All buttons after the minumum month are enabled'); + + // Make sure clicking October (the minumum month) works as expected. + $(buttons[9]).trigger('click'); + + var selectedMonth = field.MonthPicker('GetSelectedDate'); + assert.equal( selectedMonth.getFullYear(), 2015, 'Clciking the minimum month chose the correct year'); + assert.equal( selectedMonth.getMonth() + 1, 10, 'Clciking the minimum month chose the correct month'); + assert.equal( field.val(), '10/2015', 'Clciking the minimum month set the field value to 10/2015' ); + + // Destroy the plugin so we can use the field over again + // in another Min/MaxMonth test. + field.MonthPicker('destroy'); +}); + +QUnit.test('Year buttons are disabled', function (assert) { + var field = $(RistrictMonthField).val('02/2015').MonthPicker({ + Animation: 'none', // Disable animation to make sure opening and closing the menu is synchronous. + + MaxMonth: '10/2015' + }); + + field.MonthPicker('Open'); + + var menu = $(MonthPicker_RistrictMonthField); + + // Click the year title to show the years. + menu.find('.year-title').trigger('click'); + + // Make sure we are in years view. + var buttons = menu.find('.month-picker-month-table button'); + var firstVisibleYear = parseInt($(buttons[0]).text(), 10); + assert.ok(firstVisibleYear, 'The menu is showing the year table'); + + // Make sure the years after the maximum year are disabled. + var firstDisabledIndex = (2015 - firstVisibleYear) + 1; + var disabledButttons = buttons.slice(firstDisabledIndex); + var hasEnabledBttons = $( disabledButttons ) + .trigger('click') + .is(':not(.ui-button-disabled)'); + + assert.ok(!hasEnabledBttons, 'All year buttons after the maximum year are disabled'); + + // Make sure that clicking the disabled buttons didn't select + // a year. + var firstVisibleYear = parseInt($(buttons[0]).text(), 10); + assert.ok(firstVisibleYear, "Clciking the disabled buttons didn't take us to month view"); + + // Make sure the next years button is disabled. + var nextYearsButton = menu.find('.next-year>button'); + var isDisabled = nextYearsButton + .trigger('click') + .is('.ui-button-disabled'); + + assert.ok(isDisabled, 'The next year button is disabled'); + var newFirstYrar = parseInt($(buttons[0]).text(), 10); + assert.equal(newFirstYrar, firstVisibleYear, "Clicking next year didn't change the year"); + + var previousYearsButton = menu.find('.previous-year>button'); + // Keep going back until there are no disabled buttons. + // We count to 10 to avoid an infinite loop in case there's + // a bug where we are going back in time but the the buttons stay disabled. + for (var i = 1; i <= 10; i++) { + // Make sure we can click the previous years button. + previousYearsButton.trigger('click'); + + newFirstYrar = parseInt($(buttons[0]).text(), 10); + var wentBack = firstVisibleYear > newFirstYrar; + assert.ok(wentBack, 'The plugin responsed to clicking previous years'); + if (!wentBack) { + // Avoid failing on the same problem multiple times. + return; + } + + firstVisibleYear = newFirstYrar; + + // We still have diabled button, make sure they are the right ones. + firstDisabledIndex = Math.min( (2015 - firstVisibleYear) + 1, 12 ); + disabledButttons = buttons.slice(firstDisabledIndex); + hasEnabledBttons = $( disabledButttons ) + .is(':not(.ui-button-disabled)'); + + assert.ok(!hasEnabledBttons, 'All year buttons after the maximum year are still disabled'); + + // Check if we still have diabled button. + if (!buttons.is('.ui-button-disabled')) { + // We don't have disabled buttons, make sure both next and previous + // years buttons are enabled. + assert.ok(!previousYearsButton.is('.ui-button-disabled'), 'previous year button is enabled'); + assert.ok(!nextYearsButton.is('.ui-button-disabled'), 'next year button is enabled'); + break; + } + } + + // Make sure we didn't click back 10 times and we + // still have disabled buttons. + assert.ok(!buttons.is('.ui-button-disabled'), 'All year buttons are enabled after clicking previous years ' + i + ' times'); + + // Make sure we can click enabled months. + var firstVisibleYear = parseInt($(buttons[0]).text(), 10); + $(buttons[0]).trigger('click'); + + assert.equal($(buttons[0]).text(), $.MonthPicker.i18n.months[0], 'Clicking the ' + firstVisibleYear + ' year button showed the months'); + + // Make sure none of the buttons are disabled in the month view. + var hasDidabledButtons = menu.find('button').is('.ui-button-disabled'); + assert.ok(!hasDidabledButtons, 'All buttons are enabled'); + + // Click the year title to show the years menu. + menu.find('.year-title').trigger('click'); + + // Keeps clicking next years until we reach the disabled years. + for (var i = 1; !buttons.is('.ui-button-disabled') && i <= 10; i++) { + nextYearsButton.trigger('click'); + } + + // Make sure were on the last page. + assert.ok(buttons.is('.ui-button-disabled'), 'Clciking next took us to the last page'); + assert.ok(nextYearsButton.is('.ui-button-disabled'), 'The next years button is disabled'); + assert.ok(!previousYearsButton.is('.ui-button-disabled'), 'The previous years button is enabled'); + + firstVisibleYear = parseInt($(buttons[0]).text(), 10); + nextYearsButton.trigger('click'); + newFirstYrar = parseInt($(buttons[0]).text(), 10); + assert.equal(newFirstYrar, firstVisibleYear, 'Clicking the next years button keept us on the same page'); + + // Click on 2015 and make sure we have disabled button. + var firstVisibleYear = parseInt($(buttons[0]).text(), 10); + $(buttons[(2015 - firstVisibleYear)]).trigger('click'); + + assert.ok(buttons.is('.ui-button-disabled'), 'Clciking the maximum year shows disabled month buttons'); + $(buttons[(2015 - firstVisibleYear)]).trigger('click'); + + // Click October and make sure were in month view. + $(buttons[9]).trigger('click'); + assert.equal(field.val(), '10/2015', 'Clicking October (the maximum month) sets the expected value'); + + // Destroy the plugin so we can use the field over again + // in another Min/MaxMonth test. + field.MonthPicker('destroy'); +}); + +// Here we make sure that if the user types in a year +// that is outside the restricted range the menu will +// open in the closest year that is within range, for example: +// +// If the MinMonth is: 10/2015 and the user types in 11/2020 +// the menu will open and show the year 2015. +// +// This test purposely juggles between types to ensure +// that passing in different types before and after init works +// as expected. +QUnit.test('Menu opens within range', function (assert) { + var field = $(RistrictMonthField).MonthPicker({ + Animation: 'none', // Disable animation to make sure opening and closing the menu is synchronous. + + MinMonth: '01/2013', + MaxMonth: new Date(2016, 11 - 1) + }); + + var menu = $(MonthPicker_RistrictMonthField); + + // Make sure the menu opens in the year 2013 even if the user + // types in 02/2010. + field.val('02/2010'); + field.MonthPicker('Open'); + + assert.equal(menu.find('.year').text(), 2013, 'The menu opend at the minimum year (2013) and not 2010' ); + + field.MonthPicker('Close'); + + // Make sure the menu opens in the year 2016 even if the user + // types in 02/2020. + field.val('12/2020'); + field.MonthPicker('Open'); + + assert.equal(menu.find('.year').text(), 2016, 'The menu opend at the maximum year (2016) and not 2020' ); + + field.MonthPicker('Close'); + + // Make sure that the menu will open at the year 2018 + // If we change the MaxMonth option. + field.MonthPicker('option', 'MaxMonth', '12/2018'); + field.MonthPicker('Open'); + + assert.equal(menu.find('.year').text(), 2018, 'The menu opend at the year 2018 after changing the MaxMonth option' ); + + field.MonthPicker('Close'); + + // Make sure the menu opens at the the selected year if the MaxMonth + // is greater than the selected month. + field.MonthPicker('option', 'MaxMonth', new Date(2021, 12 - 1)); + field.MonthPicker('Open'); + + assert.equal(menu.find('.year').text(), 2020, 'The menu opend at the the selected year 2020 after' ); + + field.MonthPicker('Close'); + + field.MonthPicker('option', 'MinMonth', new Date(2010, 12 - 1)); + field.val('02/2009'); + field.MonthPicker('Open'); + + assert.equal(menu.find('.year').text(), 2010, 'The menu opend at the year 2010 after chagnig the MinMonth option' ); + + field.MonthPicker('Close'); + + // Make sure the menu opens at the selected year the MinMonth option + // to soemthing smaller than the selected month. + field.MonthPicker('option', 'MinMonth', new Date(2008, 04)); + field.MonthPicker('Open'); + + assert.equal(menu.find('.year').text(), 2009, 'The menu opend at the selected year after changing the MinMonth option again' ); + + // Destroy the plugin so we can use the field over again + // in another Min/MaxMonth test. + field.MonthPicker('destroy'); +}); + +QUnit.test('Number of months from today', function (assert) { + var field = $(RistrictMonthField).MonthPicker({ + Animation: 'none', // Disable animation to make sure opening and closing the menu is synchronous. + + MinMonth: 0, + MaxMonth: 16 + }); + + // Make sure the menu will open on the current month. + field.val($.datepicker.formatDate('mm/yy', new Date)); + + field.MonthPicker('Open'); + + var menu = $(MonthPicker_RistrictMonthField); + + // Make sure we are in years view. + var buttons = menu.find('.month-picker-month-table button'); + var nextYearButton = menu.find('.next-year>button'); + var previousYearButton = menu.find('.previous-year>button'); + var enabledMonths = 0; + + // Make sure that 16 buttons + 1 for today are disabled. + // + // Keep clicking next until the next year button is disabled + // We count to 10 to avoid an infinite loop in case there's + // a bug where the next button is not disabled. + var hasNext = nextYearButton.is(':not(.ui-button-disabled)'); + for (var i = 0; hasNext && i < 10; i++) { + hasNext = nextYearButton.is(':not(.ui-button-disabled)'); + enabledMonths += buttons.not('.ui-button-disabled').length; + nextYearButton.trigger('click'); + } + assert.equal(enabledMonths, 17, 'Today + 16 month buttons are enabled'); + + field.MonthPicker('Close'); + + // Make sure that 20 buttons + 1 for today are disabled. + field.MonthPicker({MinMonth: -20, MaxMonth: 0}); + field.MonthPicker('Open'); + enabledMonths = 0; + + hasNext = previousYearButton.is(':not(.ui-button-disabled)'); + + for (var i = 0; hasNext && i < 10; i++) { + hasNext = previousYearButton.is(':not(.ui-button-disabled)'); + enabledMonths += buttons.not('.ui-button-disabled').length; + previousYearButton.trigger('click'); + } + assert.equal(enabledMonths, 21, 'Today + 20 month buttons are enabled'); + + // Destroy the plugin so we can use the field over again + // in another Min/MaxMonth test. + field.MonthPicker('destroy'); +}); + +QUnit.test('Relative month periods', function (assert) { + var field = $(RistrictMonthField).MonthPicker({ + Animation: 'none', // Disable animation to make sure opening and closing the menu is synchronous. + + MinMonth: '+1Y -12m', // a.k.a 0 months (this month). + MaxMonth: '6M +1y' // a.k.a 18 months. + }); + + // Make sure the menu will open on the current month. + field.val($.datepicker.formatDate('mm/yy', new Date)); + + field.MonthPicker('Open'); + + var menu = $(MonthPicker_RistrictMonthField); + + // Make sure we are in years view. + var buttons = menu.find('.month-picker-month-table button'); + var nextYearButton = menu.find('.next-year>button'); + var previousYearButton = menu.find('.previous-year>button'); + var enabledMonths = 0; + + // Make sure that 18 buttons + 1 for today are disabled. + // + // Keep clicking next until the next year button is disabled + // We count to 10 to avoid an infinite loop in case there's + // a bug where the next button is not disabled. + var hasNext = nextYearButton.is(':not(.ui-button-disabled)'); + for (var i = 0; hasNext && i < 10; i++) { + hasNext = nextYearButton.is(':not(.ui-button-disabled)'); + enabledMonths += buttons.not('.ui-button-disabled').length; + nextYearButton.trigger('click'); + } + assert.equal(enabledMonths, 19, 'Today + 18 month buttons are enabled'); + + field.MonthPicker('Close'); + + // Make sure that 24 buttons + 1 for today are disabled. + field.MonthPicker({MinMonth: '-2y', MaxMonth: '0M'}); + field.MonthPicker('Open'); + enabledMonths = 0; + + hasNext = previousYearButton.is(':not(.ui-button-disabled)'); + + for (var i = 0; hasNext && i < 10; i++) { + hasNext = previousYearButton.is(':not(.ui-button-disabled)'); + enabledMonths += buttons.not('.ui-button-disabled').length; + previousYearButton.trigger('click'); + } + assert.equal(enabledMonths, 25, 'Today + 24 month buttons are enabled'); + + // Destroy the plugin so we can use the field over again + // in another Min/MaxMonth test. + field.MonthPicker('destroy'); +}); + +QUnit.test('JavaScript Date objects', function (assert) { + var field = $(RistrictMonthField).MonthPicker({ + Animation: 'none', // Disable animation to make sure opening and closing the menu is synchronous. + + MinMonth: new Date(2015, 2 - 1), + MaxMonth: new Date(2015, 11 - 1) + }); + + field.val('05/2015'); + + var menu = $(MonthPicker_RistrictMonthField); + var buttons = menu.find('.month-picker-month-table button'); + + field.MonthPicker('Open'); + assert.equal(buttons.not('.ui-button-disabled').length, 10, '10 month buttons are enabled'); + + field.MonthPicker('Close'); + field.MonthPicker('option', 'MinMonth', new Date(2016, 1 - 1)); + field.MonthPicker('option', 'MaxMonth', new Date(2016, 6 - 1)); + + field.MonthPicker('Open'); + assert.equal(menu.find('.year').text(), 2016, 'The menu opend at the expected year 2015'); + assert.equal(buttons.not('.ui-button-disabled').length, 6, '12 month buttons are enabled'); + + // Destroy the plugin so we can use the field over again + // in another Min/MaxMonth test. + field.MonthPicker('destroy'); +});