Пример настроек на сайте ocStore 3.0.3.7
Блок "Свой CSS код"
/* ============================================================
3. КНОПКА "ДОДАТИ ВСЕ В КОШИК" (Ефекти наведення)
============================================================ */
#addAllToCart:hover {
background-color: #218838 !important;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}
#addAllToCart:disabled {
cursor: not-allowed;
opacity: 0.7;
}
блок "Свой JavaScript код"
/* =============================================================================
БЛОК 1: НАЛАШТУВАННЯ ТА КОНСТАНТИ
============================================================================= */
// Конфігурація для кошика
const CONFIG_CART = {
RADIUS_OPTION_ID: '229',
ROUTE_ADD: 'index.php?route=checkout/cart/add',
ROUTE_INFO: 'index.php?route=common/cart/info #cart > button > *',
REDIRECT_URL: 'index.php?route=checkout/checkout'
};
// Карта артикулів (якщо ID не прописані безпосередньо в HTML)
const PRODUCT_MAP = {
'372332': 50, '132320': 51, '132310': 67, '142345': 158,
'422361': 159, '372320': 99, '412318': 93, '141030': 113,
'702320': 112, '372351': 104, '702322': 105, '372310': 98,
'702310': 100, '702321': 113
};
/* =============================================================================
БЛОК 3: УНІВЕРСАЛЬНИЙ ОБРОБНИК КАЛЬКУЛЯТОРІВ
============================================================================= */
/**
* Додавання товарів з калькулятора в кошик
*/
function universalAddToCart(btnElement) {
const wrapper = btnElement.closest('.gate-calc-wrapper') || btnElement.parentElement;
const rows = wrapper.querySelectorAll('tbody tr');
const status = wrapper.querySelector('.status-msg') || wrapper.querySelector('#cartStatus');
if (!rows.length) return alert('Спочатку виконайте розрахунок!');
// Блокування кнопки
btnElement.disabled = true;
const originalText = btnElement.innerText;
btnElement.innerText = "Обробка...";
if (status) {
status.style.display = "block";
status.innerText = "Додаємо товари у кошик...";
}
let requests = [];
rows.forEach(row => {
let productId = row.dataset.prodid;
let quantity = row.dataset.qty || row.dataset.quantity;
let optionVal = row.dataset.optval;
// Пошук ID через карту артикулів, якщо немає data-атрибутів
if (!productId) {
const artCell = row.querySelector('.col-art') || row.cells[0];
const art = artCell.textContent.trim();
productId = PRODUCT_MAP[art];
const qtyText = row.cells[row.cells.length - 1].textContent;
quantity = Math.ceil(parseFloat(qtyText.replace(',', '.').replace(/[^0-9.]/g, '')));
}
if (productId && quantity > 0) {
let postData = { product_id: productId, quantity: quantity };
if (optionVal) {
postData[`option[${CONFIG_CART.RADIUS_OPTION_ID}]`] = optionVal;
}
requests.push($.ajax({ url: CONFIG_CART.ROUTE_ADD, type: 'post', data: postData, dataType: 'json' }));
}
});
if (!requests.length) {
btnElement.disabled = false;
btnElement.innerText = originalText;
return alert('Товари не знайдені!');
}
// Виконання всіх запитів
$.when.apply($, requests).done(function() {
if (status) status.innerText = "✅ Переходимо до оформлення...";
$('#cart > button').load(CONFIG_CART.ROUTE_INFO);
setTimeout(() => { window.location.href = CONFIG_CART.REDIRECT_URL; }, 800);
}).fail(function() {
if (status) status.innerText = "❌ Помилка при додаванні.";
btnElement.disabled = false;
btnElement.innerText = "Спробувати ще раз";
});
}
/**
* Зміна значень лічильників (+/-)
*/
function changeVal(id, step, min = 0, max = 9999) {
const el = document.getElementById(id);
let v = (parseFloat(el.value) || 0) + step;
el.value = Math.max(min, Math.min(max, v));
}
// Для сумісності зі старими шаблонами
function changeRadiusVal(id, step, min, max) { changeVal(id, step, min, max); }
Блок "HTML контент"
пример кода из блока HTML рабочего калькулятора
<div class="gate-calc-wrapper">
<h3 class="calc-title">Калькулятор *** воріт</h3>
<div class="input-group-row">
<div class="input-field">
<label>Ширина в'їзду А1 (см)</label>
<div class="counter-box">
<button type="button" onclick="changeVal('inputA1', -10, 100, 1000)">-</button>
<input type="number" id="inputA1" value="400">
<button type="button" onclick="changeVal('inputA1', 10, 100, 1000)">+</button>
</div>
</div>
</div>
<button type="button" class="btn-calculate" onclick="calculateNewGate()">Розрахувати</button>
<div id="newGateResult" style="display:none;">
<div class="results-container">
<div class="result-section">
<h4><i class="fa fa-info-circle"></i> Технічні параметри</h4>
<div class="res-item"><span>Ширина в'їзду <b>А1</b>:</span> <span class="res-val"><span id="r_A1"></span> см</span></div>
<div class="res-item"><span>Каркас <b>А2</b>:</span> <span class="res-val"><span id="r_A2"></span> см</span></div>
<div class="res-item"><span>Відкат <b>А3</b>:</span> <span class="res-val"><span id="r_A3"></span> см</span></div>
<div class="res-item"><span>Направляюча <b>А4</b>:</span> <span class="res-val"><span id="r_A4"></span> см</span></div>
</div>
<div class="result-section">
<h4><i class="fa fa-wrench"></i> Монтажні параметри</h4>
<div class="res-item"><span>Відстань між каретками <b>А5</b>:</span> <span class="res-val"><span id="r_A5"></span> см</span></div>
<div class="res-item"><span>Крок кронштейнів <b>А6</b>:</span> <span class="res-val"><span id="r_A6"></span> см</span></div>
<div class="res-item" style="background: #eef9f1; border-color: #c3e6cb;">
<span>Кількість кареток:</span> <b><span id="r_QtyCar"></span> шт</b>
</div>
</div>
</div>
<h4 class="table-title">Оберіть вантажопідйомність:</h4>
<div class="weight-tabs">
<button type="button" class="tab-btn active" onclick="switchWeight(this, 300)">до 300 кг</button>
<button type="button" class="tab-btn" onclick="switchWeight(this, 500)">до 500 кг</button>
<button type="button" class="tab-btn" onclick="switchWeight(this, 1000)">до 1000 кг</button>
</div>
<div class="table-responsive">
<table class="calc-table">
<thead>
<tr>
<th class="col-art">Код</th>
<th>Найменування</th>
<th style="text-align:center;">К-сть</th>
</tr>
</thead>
<tbody id="newGateTableBody"></tbody>
</table>
</div>
<button type="button" class="btn-checkout" id="addAllToCart" onclick="processCartAddition()">
ОФОРМИТИ ЗАМОВЛЕННЯ
</button>
<div id="cart-status-msg" style="text-align:center; margin-top:10px; font-weight:bold; min-height: 20px;"></div>
</div>
</div>
<style>
/* Базові стилі калькулятора */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number] { -moz-appearance: textfield; }
.weight-tabs { display: flex; gap: 5px; margin-bottom: 15px; background: #f1f1f1; padding: 5px; border-radius: 10px; }
.tab-btn { flex: 1; padding: 10px; border: none; background: none; cursor: pointer; font-weight: bold; border-radius: 7px; transition: 0.3s; color: #666; font-size: 14px; }
.tab-btn.active { background: #fff; color: #007bff; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
.gate-calc-wrapper { max-width: 800px; margin: 20px auto; padding: 25px; border-radius: 15px; background: #ffffff; box-shadow: 0 10px 30px rgba(0,0,0,0.08); color: #333; font-family: 'Segoe UI', Roboto, sans-serif; }
.calc-title { text-align: center; margin-bottom: 25px; color: #222; font-weight: 700; }
.input-group-row { display: flex; gap: 20px; margin-bottom: 20px; }
.input-field { flex: 1; }
.counter-box { display: flex; border: 2px solid #e9ecef; border-radius: 8px; overflow: hidden; height: 48px; }
.counter-box button { width: 50px; border: none; background: #f8f9fa; font-size: 20px; cursor: pointer; transition: 0.2s; }
.counter-box button:hover { background: #dee2e6; }
.counter-box input { flex: 1; border: none; text-align: center; font-size: 16px; font-weight: 600; outline: none; width: 50px; }
.btn-calculate { width: 100%; padding: 15px; background: #007bff; color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: bold; cursor: pointer; transition: 0.3s; }
.btn-calculate:hover { background: #0056b3; }
.results-container { display: flex; gap: 20px; margin-top: 25px; }
.result-section { flex: 1; background: #fdfdfd; padding: 15px; border: 1px solid #edf2f7; border-radius: 10px; }
.res-item { font-size: 13px; margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center; padding: 6px 8px; background: #fff; border: 1px solid #f1f4f8; border-radius: 6px; }
.calc-table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 14px; }
.calc-table th { background: #f8f9fa; padding: 12px 10px; border: 1px solid #dee2e6; text-align: left; }
.calc-table td { padding: 10px; border: 1px solid #dee2e6; }
.btn-checkout { width: 100%; padding: 18px; background: #28a745; color: #fff; border: none; border-radius: 8px; font-size: 18px; font-weight: bold; margin-top: 20px; cursor: pointer; transition: 0.3s; }
.btn-checkout:hover { background: #218838; }
/* Мобільна адаптація */
@media (max-width: 600px) {
.input-group-row, .results-container { flex-direction: column; }
/* Ховаємо колонку "Код" (перша th і перша td у кожному рядку) */
.calc-table th.col-art,
.calc-table td.col-art {
display: none;
}
.tab-btn { font-size: 12px; padding: 8px 4px; }
}
</style>
<script>
let lastCalc = {};
function changeVal(id, step, min, max) {
const input = document.getElementById(id);
let val = parseFloat(input.value) + step;
if (val < min) val = min;
if (val > max) val = max;
input.value = val;
}
function calculateNewGate() {
const A1 = parseFloat(document.getElementById('inputA1').value);
if (!A1) return alert("Введіть ширину");
const A2 = A1 + 20;
const A4 = A1 * 2;
const A5 = A1 - 60;
const N = Math.round(A5 / 75);
const A6 = (A5 / N).toFixed(1);
const qtyCarriages = Math.round(A5 / 200) + 1;
const qtyBrackets = (N + 1) * 2;
lastCalc = { A1, A2, A4, A5, A6, qtyCarriages, qtyBrackets };
document.getElementById('r_A1').innerText = A1;
document.getElementById('r_A2').innerText = A2;
document.getElementById('r_A3').innerText = A2;
document.getElementById('r_A4').innerText = A4;
document.getElementById('r_A5').innerText = A5;
document.getElementById('r_A6').innerText = A6;
document.getElementById('r_QtyCar').innerText = qtyCarriages;
document.getElementById('newGateResult').style.display = 'block';
const activeTab = document.querySelector('.tab-btn.active');
const weightVal = parseInt(activeTab.innerText.match(/\d+/)[0]);
switchWeight(activeTab, weightVal);
}
function switchWeight(element, weight) {
document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
element.classList.add('active');
const tbody = document.getElementById('newGateTableBody');
tbody.innerHTML = '';
if (weight === 300) render300kg(tbody);
else if (weight === 500) render500kg(tbody);
else if (weight === 1000) render1000kg(tbody);
}
function addTableRow(tbody, art, name, prodId, qty) {
if (qty <= 0) return;
const tr = document.createElement('tr');
tr.className = "cart-item-row";
tr.dataset.prodid = prodId;
tr.dataset.qty = qty;
// Додаємо клас col-art для першої комірки
tr.innerHTML = `<td class="col-art" style="font-family:monospace; font-weight:bold;">${art}</td><td>${name}</td><td style="text-align:center; font-weight:bold;">${qty}</td>`;
tbody.appendChild(tr);
}
function render300kg(tbody) {
const data = lastCalc;
addTableRow(tbody, '112330', 'Напрямна СТРІКС середня 42×54 мм (метр)', '148', Math.ceil(data.A4 / 100));
addTableRow(tbody, '132349', 'Каретка СТРІКС С2а 42×54 мм до 250 кг', '142', data.qtyCarriages);
addTableRow(tbody, '180703', 'Вушка для роликової каретки (пара)', '182', data.qtyCarriages);
addTableRow(tbody, '122391', 'Кронштейн СТРІКС С настінний 42×54 мм', '149', data.qtyBrackets);
addTableRow(tbody, '412314', 'Упор (стопор) СТРІКС С 42×54 мм', '155', 2);
let connQty = (data.A4 / 100 > 12.1) ? 2 : (data.A4 / 100 > 6.1 ? 1 : 0);
if (connQty > 0) addTableRow(tbody, '122393', 'Кронштейн СТРІКС С з\'єднувальний 42×54 мм', '151', connQty);
addTableRow(tbody, '422341', 'П-подібний напрямний профіль Ø34 мм (МЕТР)', '168', Math.ceil(data.A2 / 100));
addTableRow(tbody, '422323', 'Напрямні ролики з кронштейном КСВ', '172', 1);
addTableRow(tbody, '142345', 'Уловлювач 3С тип 2 з гумовими роликами', '158', 1);
addTableRow(tbody, '422361', 'Куточок уловлювача ТИП 2', '159', 1);
}
function render500kg(tbody) {
const data = lastCalc;
addTableRow(tbody, '122300', 'Направляюча мала 69×58 мм (метр)', '53', Math.ceil(data.A4 / 100));
addTableRow(tbody, '122359', 'Каретка несуча №3Б 69×58 мм', '119', data.qtyCarriages);
addTableRow(tbody, '180703', 'Вушка для роликової каретки (пара)', '182', data.qtyCarriages);
addTableRow(tbody, '422347', 'Кронштейн настінний тип 2 (69×58 мм)', '175', data.qtyBrackets);
addTableRow(tbody, '412311', 'Упор для воріт №2 (69×58 мм)', '97', 2);
let connQty = (data.A4 / 100 > 12.1) ? 2 : (data.A4 / 100 > 6.1 ? 1 : 0);
if (connQty > 0) addTableRow(tbody, '422339', 'Кронштейн з\'єднувальний 69×58 мм', '128', connQty);
addTableRow(tbody, '422341', 'П-подібний напрямний профіль Ø34 мм (МЕТР)', '168', Math.ceil(data.A2 / 100));
addTableRow(tbody, '422323', 'Напрямні ролики з кронштейном КСВ', '172', 1);
addTableRow(tbody, '142345', 'Уловлювач 3С тип 2 з гумовими роликами', '158', 1);
addTableRow(tbody, '422361', 'Куточок уловлювача ТИП 2', '159', 1);
}
function render1000kg(tbody) {
const data = lastCalc;
addTableRow(tbody, '112300', 'Напрямна велика 95×81 мм (метр)', '64', Math.ceil(data.A4 / 100));
addTableRow(tbody, '122346', 'Каретка несуча А 95×81 мм', '115', data.qtyCarriages);
addTableRow(tbody, '180703', 'Вушка для роликової каретки (пара)', '182', data.qtyCarriages);
addTableRow(tbody, '412318', 'Стопор Б тип 2', '93', 2);
addTableRow(tbody, '422341', 'П-подібний напрямний профіль Ø34 мм (МЕТР)', '168', Math.ceil(data.A2 / 100));
addTableRow(tbody, '422323', 'Напрямні ролики з кронштейном КСВ', '172', 1);
addTableRow(tbody, '142345', 'Уловлювач 3С тип 2 з гумовими роликами', '158', 1);
addTableRow(tbody, '422361', 'Куточок уловлювача ТИП 2', '159', 1);
}
function processCartAddition() {
const rows = document.querySelectorAll('.cart-item-row');
const status = document.getElementById('cart-status-msg');
if (rows.length === 0) return;
status.innerText = "Додаємо товари у кошик...";
status.style.color = "#007bff";
rows.forEach(row => {
const id = row.dataset.prodid;
const q = row.dataset.qty;
if (typeof cart !== 'undefined' && cart.add) {
cart.add(id, q);
} else if (typeof universalAddToCart === 'function') {
universalAddToCart(row);
}
});
setTimeout(() => {
status.innerText = "Готово! Перенаправлення на оплату...";
status.style.color = "#28a745";
setTimeout(() => {
window.location.href = "https://ksv.in.ua/checkout/";
}, 2000);
}, 600);
}
</script>
Потрібно об'єднати логіку калькулятора новою структурою коду: додати клас .cart-item-row, використовувати data-prodid та data-qty для кожного рядка таблиці, а також впровадити оновлену функцію processCartAddition з двома таймерами затримки.
Що потрібно зробити:
Динамічні атрибути: У функцію addRowM додано створення атрибутів data-prodid та data-qty, а також класу .cart-item-row. Це дозволяє скрипту "бачити" товари.
Обробка кошика: Функція processCartAddition тепер проходить циклом по всіх згенерованих рядках таблиці та додає їх до замовлення.
Візуальні таймери:
Через 0.5 сек з'являється зелений напис про успішне додавання.
Через 2.0 сек відбувається автоматичне перенаправлення на сторінку https://ksv.in.ua/checkout/.
Адаптивність: Збережено приховування колонки "Код" на мобільних пристроях для кращого вигляду.