Кастомизируем календарь в битриксе

calendar.png В оформлении заказа интернет-магазина заполняется свойство "Дата доставки", в нем пользователь выбирает день доставки товара. Клиенты ошибались в выборе дня, могли указать прошедшую дату, поэтому владелец интернет-магазина принял решение ограничить интервал выбора возможных дат доставки, а именно в течении 7 дней начиная с текущего дня.
Задача:

В оформлении заказа sale.order.ajax у свойства типа дата добавить ограничение по выбору дня, чтобы можно было выбрать только из ближайших 7 дней начиная с текущего.

Решение:

В шаблоне компонента sale.order.ajax находим файл order_ajax.js, в нем метод alterDateProperty. В данном методе реализован показ календаря для свойства заказа типа дата.
По клику на иконку рядом с input появляется календарь, за показ отвечает метод :

BX.calendar({
	node: parentNode.querySelector('.input-group-append'),
	field: parentNode.querySelector('input[type=text]').name,
	form: '',
	bTime: settings.TIME === 'Y',
	bHideTime: false
});
У BX.calendar есть параметр callback_after, вызывается после выбора даты, его и будем использовать для ограничения выбора даты.

В результате BX.calendar выглядит так:

BX.calendar({
	node: parentNode.querySelector('.input-group-append'),
	field: parentNode.querySelector('input[type=text]').name,
	form: '',
	bTime: settings.TIME === 'Y',
	bHideTime: false,
	callback_after: function(arDay) 
	{
		var currentDate = new Date();
		var d_current =  currentDate.getTime() / 1000; // текущая дата в секундах
		var d_select =  arRights.getTime() / 1000; // выбранная дата в секундах

		if ((Number(d_select - d_current)/(24*3600)+1)<0 ||  Number(Number(d_select - d_current)/(24*3600))>6)  // определим интервал 7 дней за пределами которого будет появляться ошибка
		{
			alert('Доставка в течение 7 дней начиная с сегодняшнего дня');
			BX.adjust(parentNode.querySelector('input[type=text]'), {
				props: {
					value: ''
				}
			});
		}
		else 
		{		
         // если дата в заданном интервале, то устанавливаем значение из календаря в input свойства заказа
			BX.adjust(parentNode.querySelector('input[type=text]'), {
				rops: {
					value: BX.date.format("d.m.Y", arRights)
				}
			});
		}                         
	}					
});



Чтобы стилизовать календарь, добавим после кода показа календаря:

var el = $('[id ^= "calendar_popup_"]');
var links = el.find(".bx-calendar-cell");
var currentDate = new Date();

for (var i =0; i < links.length; i++)
{
	var itemDate = links[i].attributes['data-date'].value;
	var d = currentDate.valueOf();
	var g = links[i].innerHTML;
	if ((itemDate - currentDate+24*60*60*1000) >= 0 && itemDate - currentDate < 6*24*60*60*1000) {
		$('[data-date="' + itemDate +'"]').addClass("weight700"); 
	}
}

14.12.2022

Семен Голиков.