Skip to content

Instantly share code, notes, and snippets.

@Artemeey
Last active August 2, 2022 12:47
  • Star 14 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Artemeey/5ebc39370e568c34f03dce1639cabee8 to your computer and use it in GitHub Desktop.
/* jQuery ui-datepicker extension */
/**
*
* https://gist.github.com/Artemeey/8bacd37964a8069a2eeee8c9b0bd2e44/
*
* Version: 1.0 (15.06.2016)
* Requires: jQuery v1.8+
* Requires: jQuery-UI v1.10+
*
* Copyright (c) 2016 Artemeey
* Under MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* sample:
* $('.datepicker').datepicker({
range:'period', // 'period' or 'multiple'
onSelect:function(dateText, inst, extensionRange){
// range - new argument!
switch(inst.settings.range){
case 'period':
console.log(extensionRange.startDateText);
console.log(extensionRange.endDateText);
console.log(extensionRange.startDate);
console.log(extensionRange.endDate);
break;
case 'multiple':
console.log(extensionRange.dates); // object, width UTC-TIME keys
console.log(extensionRange.datesText); // object, width UTC-TIME keys
break;
}
}
});
*
* extension styles:
* .selected
* .selected-start
* .selected-end
* .first-of-month
* .last-of-month
*
*/
$.datepicker._get_original=$.datepicker._get,$.datepicker._get=function(t,e){var i=$.datepicker._get_original(t,e),a=t.settings.range;if(!a)return i;var s=this;switch(a){case"period":case"multiple":var n=$(this.dpDiv).data("datepickerExtensionRange");switch(n||(n=new _datepickerExtension,$(this.dpDiv).data("datepickerExtensionRange",n)),n.range=a,n.range_multiple_max=t.settings.range_multiple_max||0,e){case"onSelect":var r=i;r||(r=function(){}),i=function(t,e){n.onSelect(t,e),r(t,e,n),s._datepickerShowing=!1,setTimeout(function(){s._updateDatepicker(e),s._datepickerShowing=!0}),n.setClassActive(e)};break;case"beforeShowDay":var r=i;r||(r=function(){return[!0,""]}),i=function(t){var e=r(t);return e=n.fillDay(t,e)};break;case"beforeShow":var r=i;r||(r=function(){}),i=function(t,e){r(t,e),n.setClassActive(e)};break;case"onChangeMonthYear":var r=i;r||(r=function(){}),i=function(t,e,i){r(t,e,i),n.setClassActive(i)}}}return i},$.datepicker._setDate_original=$.datepicker._setDate,$.datepicker._setDate=function(t,e,i){var a=t.settings.range;if(!a)return $.datepicker._setDate_original(t,e,i);var s=this.dpDiv.data("datepickerExtensionRange");if(!s)return $.datepicker._setDate_original(t,e,i);switch(a){case"period":("object"!=typeof e||void 0==e.length)&&(e=[e,e]),s.step=0,$.datepicker._setDate_original(t,e[0],i),s.startDate=this._getDate(t),s.startDateText=this._formatDate(t),$.datepicker._setDate_original(t,e[1],i),s.endDate=this._getDate(t),s.endDateText=this._formatDate(t),s.setClassActive(t);break;case"multiple":("object"!=typeof e||void 0==e.length)&&(e=[e]),s.dates=[],s.datesText=[];var n=this;$.map(e,function(e){$.datepicker._setDate_original(t,e,i),s.dates.push(n._getDate(t)),s.datesText.push(n._formatDate(t))}),s.setClassActive(t)}};var _datepickerExtension=function(){this.range=!1,this.range_multiple_max=0,this.step=0,this.dates=[],this.datesText=[],this.startDate=null,this.endDate=null,this.startDateText="",this.endDateText="",this.onSelect=function(t,e){switch(this.range){case"period":return this.onSelectPeriod(t,e);case"multiple":return this.onSelectMultiple(t,e)}},this.onSelectPeriod=function(t,e){this.step++,this.step%=2,this.step?(this.startDate=this.getSelectedDate(e),this.endDate=this.startDate,this.startDateText=t,this.endDateText=this.startDateText):(this.endDate=this.getSelectedDate(e),this.endDateText=t,this.startDate.getTime()>this.endDate.getTime()&&(this.endDate=this.startDate,this.startDate=this.getSelectedDate(e),this.endDateText=this.startDateText,this.startDateText=t))},this.onSelectMultiple=function(t,e){var i=this.getSelectedDate(e),a=-1;$.map(this.dates,function(t,e){t.getTime()==i.getTime()&&(a=e)});var s=$.inArray(t,this.datesText);-1!=a?this.dates.splice(a,1):this.dates.push(i),-1!=s?this.datesText.splice(s,1):this.datesText.push(t),this.range_multiple_max&&this.dates.length>this.range_multiple_max&&(this.dates.splice(0,1),this.datesText.splice(0,1))},this.fillDay=function(t,e){var i=e[1];switch(1==t.getDate()&&(i+=" first-of-month"),t.getDate()==new Date(t.getFullYear(),t.getMonth()+1,0).getDate()&&(i+=" last-of-month"),e[1]=i.trim(),this.range){case"period":return this.fillDayPeriod(t,e);case"multiple":return this.fillDayMultiple(t,e)}},this.fillDayPeriod=function(t,e){if(!this.startDate||!this.endDate)return e;var i=e[1];return t>=this.startDate&&t<=this.endDate&&(i+=" selected"),t.getTime()==this.startDate.getTime()&&(i+=" selected-start"),t.getTime()==this.endDate.getTime()&&(i+=" selected-end"),e[1]=i.trim(),e},this.fillDayMultiple=function(t,e){var i=e[1],a=!1;return $.map(this.dates,function(e){e.getTime()==t.getTime()&&(a=!0)}),a&&(i+=" selected selected-start selected-end"),e[1]=i.trim(),e},this.getSelectedDate=function(t){return new Date(t.selectedYear,t.selectedMonth,t.selectedDay)},this.setClassActive=function(t){var e=this;setTimeout(function(){$("td.selected > *",t.dpDiv).addClass("ui-state-active"),"multiple"==e.range&&$("td:not(.selected)",t.dpDiv).removeClass("ui-datepicker-current-day").children().removeClass("ui-state-active")})}};
@mrFANRA
Copy link

mrFANRA commented Nov 25, 2016

Nice extension! Thanks!

But here is one bug, not working with beforeShowDay method.

beforeShowDay: function(date){
    var string  =   jQuery.datepicker.formatDate('yy-mm-dd', date);
    var array   =   ['2017-01-01'];
    return [ array.indexOf(string) == -1 ]
}

@ivankrivenko
Copy link

Добрый день. Спасибо за хорошее решение.
Видел вашу статью на Хабре https://habrahabr.ru/post/303186/
Как уже написали 25 Nov 2016: нет возможности установить неактивные даты.

@atach
Copy link

atach commented Sep 15, 2017

Большое спасибо за скрипт!
Подскажите, а как можно в типе "период" запретить выбор конечной даты, такой же как и начальной?

@nawmem
Copy link

nawmem commented Jul 18, 2018

Спасибо тебе большой человек. Мудрил свое, но тут нарвался на это чудо.

@devnaumov
Copy link

Добрый день. У меня возникла проблема, когда выбираешь период с 2 инпутами и пытаешься переключить месяц или нажать кнопку today, календарь бликает, а само переключение происходит только со второго раза. В вашем примере на jsfiddle такая проблема тоже есть, в чем может быть дело?
Заранее спасибо.

@motoroller1983
Copy link

Подскажите, а как передать параметры дат, чтобы были выбраны при загрузке плагина?

@Artemeey
Copy link
Author

Artemeey commented Jul 22, 2020

Подскажите, а как передать параметры дат, чтобы были выбраны при загрузке плагина?

Можно установить нужные даты с помощью метода setDate:

var $datePicker = $('#datepicker');
$datePicker.datepicker('setDate', ['-1w +1d', '+0d']); // период - последняя неделя

@rasxod
Copy link

rasxod commented May 11, 2022

при multiple по умолчанию выбрана сегодняшняя дата, как от этого избавится? чтобы при мервом нажатии в массив передавалась только 1 дата
разобрался
при инициализации

$('#_datepicker').datepicker('widget').data('datepickerExtensionRange', '');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment