<script>
(function () {
let correction = false; // коррекция количества (true - уменьшаем, false - оставляем как есть)
const MIN_RENTAL_DAYS = 3; // Минимальный срок аренды в днях
// Сообщения
const MESSAGE_ERROR = `Минимальная аренда ${MIN_RENTAL_DAYS} дн.`;
const MESSAGE_SUCCESS = "Срок аренды: ";
const CART_SELECTOR = ".t706";
const DATE_START_SELECTOR = 'input[name="datestart"]';
const DATE_END_SELECTOR = 'input[name="dateend"]';
const SUBMIT_BUTTON_SELECTOR = "button.t-submit";
const MESSAGE_SELECTOR = 'a[href="#date-message"]';
const QNT_DISPLAY_SELECTOR = '.t706__product-quantity';
const QNT_INPUT_SELECTOR = '.t706__product-quantity input';
// Правила коррекции количества (чем больше дней, тем больше вычитаем)
const CORRECTION_RULES = [
{ threshold: 20, subtract: 5 },
{ threshold: 10, subtract: 2 },
{ threshold: 5, subtract: 1 }
];
let isInitialized = false;
let cartObserver = null;
let originalOpenCart = null;
let firstOpenAfterInit = true;
const processedCarts = new WeakSet();
function parseDate(dateString) {
if (!dateString) return null;
let separator;
if (dateString.includes('/')) separator = '/';
else if (dateString.includes('-')) separator = '-';
else if (dateString.includes('.')) separator = '.';
else return null;
let parts = dateString.split(separator);
if (parts.length !== 3) return null;
let day, month, year;
if (parseInt(parts[0]) > 31) {
year = parseInt(parts[0]);
month = parseInt(parts[1]) - 1;
day = parseInt(parts[2]);
} else {
day = parseInt(parts[0]);
month = parseInt(parts[1]) - 1;
year = parseInt(parts[2]);
}
return new Date(year, month, day);
}
function getDaysDifference(startDate, endDate) {
if (!startDate || !endDate) return null;
const start = new Date(startDate);
start.setHours(0, 0, 0, 0);
const end = new Date(endDate);
end.setHours(0, 0, 0, 0);
const diffTime = end - start;
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return diffDays;
}
function toggleClass(element, className, add) {
if (!element) return;
if (add) {
element.classList.add(className);
} else {
element.classList.remove(className);
}
}
function calculateQuantity(days, applyCorrection) {
if (!applyCorrection) {
return days;
}
let newQuantity = days;
for (let rule of CORRECTION_RULES) {
if (days >= rule.threshold) {
newQuantity = days - rule.subtract;
break;
}
}
return newQuantity;
}
function updateQuantity(cartElement, days) {
const quantityDisplay = cartElement.querySelector(QNT_DISPLAY_SELECTOR);
if (!quantityDisplay) return;
const startDateInput = cartElement.querySelector(DATE_START_SELECTOR);
const endDateInput = cartElement.querySelector(DATE_END_SELECTOR);
if (!startDateInput || !endDateInput) return;
const startDate = parseDate(startDateInput.value);
const endDate = parseDate(endDateInput.value);
if (!startDate || !endDate) return;
const actualDays = getDaysDifference(startDate, endDate);
if (actualDays !== days) return;
const newQuantity = calculateQuantity(days, correction);
const qntInput = cartElement.querySelector(QNT_INPUT_SELECTOR);
if (qntInput && parseInt(qntInput.value) === newQuantity) return;
quantityDisplay.click();
setTimeout(() => {
const qntInput = cartElement.querySelector(QNT_INPUT_SELECTOR);
if (qntInput) {
qntInput.setAttribute('autocomplete', 'off');
qntInput.setAttribute('autocorrect', 'off');
qntInput.setAttribute('autocapitalize', 'off');
qntInput.setAttribute('spellcheck', 'false');
qntInput.value = newQuantity;
qntInput.dispatchEvent(new Event('input', { bubbles: true }));
qntInput.blur();
const focusoutEvent = new Event('focusout', { bubbles: true });
qntInput.dispatchEvent(focusoutEvent);
const enterEvent = new KeyboardEvent('keydown', {
key: 'Enter',
code: 'Enter',
keyCode: 13,
bubbles: true
});
qntInput.dispatchEvent(enterEvent);
}
}, 50);
}
function updateDateValidation(cartElement, startDate, endDate) {
const days = getDaysDifference(startDate, endDate);
const submitButton = cartElement.querySelector(SUBMIT_BUTTON_SELECTOR);
const dateEndInput = cartElement.querySelector(DATE_END_SELECTOR);
const messageElement = cartElement.querySelector(MESSAGE_SELECTOR);
if (days !== null && days < MIN_RENTAL_DAYS) {
if (submitButton) submitButton.type = "button";
toggleClass(dateEndInput, "redtext", true);
if (messageElement) {
messageElement.textContent = MESSAGE_ERROR;
toggleClass(messageElement, "redtext", true);
}
} else if (days !== null && days >= MIN_RENTAL_DAYS) {
if (submitButton) submitButton.type = "submit";
toggleClass(dateEndInput, "redtext", false);
if (messageElement) {
messageElement.textContent = MESSAGE_SUCCESS + days + " дн.";
toggleClass(messageElement, "redtext", false);
}
updateQuantity(cartElement, days);
}
}
function handleDatesChange(cartElement) {
const startDateInput = cartElement.querySelector(DATE_START_SELECTOR);
const endDateInput = cartElement.querySelector(DATE_END_SELECTOR);
if (!startDateInput || !endDateInput) return;
const startDate = parseDate(startDateInput.value);
const endDate = parseDate(endDateInput.value);
if (startDate && endDate) {
updateDateValidation(cartElement, startDate, endDate);
} else if (endDateInput.value && !startDateInput.value) {
const submitButton = cartElement.querySelector(SUBMIT_BUTTON_SELECTOR);
if (submitButton) submitButton.type = "button";
}
}
function initCartHandlers(cartElement) {
if (processedCarts.has(cartElement)) return;
const startDateInput = cartElement.querySelector(DATE_START_SELECTOR);
const endDateInput = cartElement.querySelector(DATE_END_SELECTOR);
if (!startDateInput || !endDateInput) return;
const handleChange = function() {
handleDatesChange(cartElement);
};
startDateInput.addEventListener('input', handleChange);
endDateInput.addEventListener('input', handleChange);
startDateInput.addEventListener('change', handleChange);
endDateInput.addEventListener('change', handleChange);
processedCarts.add(cartElement);
cartElement._dateHandlers = {
startInput: handleChange,
endInput: handleChange,
startChange: handleChange,
endChange: handleChange
};
setTimeout(() => handleDatesChange(cartElement), 100);
}
function initAllCarts() {
const cartElements = document.querySelectorAll(CART_SELECTOR);
cartElements.forEach(cartElement => {
const submitButton = cartElement.querySelector(SUBMIT_BUTTON_SELECTOR);
if (submitButton && submitButton.type === 'submit') {
submitButton.type = 'button';
}
initCartHandlers(cartElement);
});
}
function observeCartElements() {
if (cartObserver) {
cartObserver.disconnect();
}
cartObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1) {
if (node.matches && node.matches(CART_SELECTOR)) {
initCartHandlers(node);
} else if (node.querySelectorAll) {
const cartElements = node.querySelectorAll(CART_SELECTOR);
cartElements.forEach(cartElement => {
initCartHandlers(cartElement);
});
}
}
});
});
});
cartObserver.observe(document.body, {
childList: true,
subtree: true
});
}
function checkCartOnOpen() {
const cartElements = document.querySelectorAll(CART_SELECTOR);
cartElements.forEach(cartElement => {
const startDateInput = cartElement.querySelector(DATE_START_SELECTOR);
const endDateInput = cartElement.querySelector(DATE_END_SELECTOR);
if (startDateInput && startDateInput.value && endDateInput && endDateInput.value) {
handleDatesChange(cartElement);
}
});
}
function overrideCartOpen() {
if (typeof window.tcart__openCart !== 'undefined' && !originalOpenCart) {
originalOpenCart = window.tcart__openCart;
window.tcart__openCart = function(...args) {
const result = originalOpenCart.apply(this, args);
setTimeout(() => {
checkCartOnOpen();
}, 100);
return result;
};
}
}
function init() {
if (isInitialized) return;
initAllCarts();
observeCartElements();
overrideCartOpen();
isInitialized = true;
}
document.addEventListener("DOMContentLoaded", function() {
t_onReady(function() {
setTimeout(function() {
t_onFuncLoad('tcart__init', function() {
init();
});
}, 200);
});
});
})();
</script>
<style>
#allrecords a[href="#date-message"]
{
color: #000;
pointer-events: none;
}
#allrecords a.redtext[href="#date-message"] ,
input.redtext {
color: #ff0000 !important;
}
.t706 button.t-submit[type="button"] {
pointer-events: none;
opacity: 0.5;
filter: grayscale(1);
}
</style>