Плюс и минус в каунте корзины MS2
Досточно простой вопрос, который мучает начинающих разработчиков. Решил поделиться решением, как сделать кнопки плюс и минус в корзине MS2. Что бы все было «по-фуншую»
Начнем c разметки. Я показываю на страндартной теме MS2. Вносим правки в чанк tpl.msCart
Далее подключим JS файл и подключим его последним.
И далее напишем ms2.js
Решение от @mngatoff
Начнем c разметки. Я показываю на страндартной теме MS2. Вносим правки в чанк tpl.msCart
...
<td class="count">
<form method="post" class="ms2_form" role="form">
<input type="hidden" name="key" value="{$product.key}"/>
<div class="form-group">
<div class="input-group input-group-sm qty">
<span class="input-group-prepend">
<span class="input-group-text minus input_count_action">-</span>
</span>
<input type="number" name="count" value="{$product.count}" class="form-control"/>
<span class="input-group-append">
<span class="input-group-text plus input_count_action">+</span>
<span class="input-group-text">{'ms2_frontend_count_unit' | lexicon}</span>
</span>
</div>
<button class="btn btn-sm" type="submit" name="ms2_action" value="cart/change">
↻</button>
</div>
</form>
</td>
...
Далее подключим JS файл и подключим его последним.
{$_modx->regClientScript("assets/js/ms2.js")}
И далее напишем ms2.js
$(document).ready(function() {
$('.qty').on('click', '.input_count_action', function(e) {
var $input = $(this).closest("div").find('input');
var count = parseInt($input.val());
if ($(this).hasClass("plus")) {
count = count + 1;
} else if ($(this).hasClass("minus")) {
count = count - 1;
}
$input.val(count);
$input.change();
return false;
});
$('div.count').click(function(e) {
var v = $(this).parent().find('input#product_price').val(),
k = $(this).parent().find('input[name="key"]').val();
if (($(this).hasClass('minus') || $(this).hasClass('plus')) && v > 0) {
$.post("", {
ms2_action: 'cart/change',
key: k,
count: v
}, function(response) {
if (typeof response.success !== "undefined") {
if (response.success) {
miniShop2.Order.getcost();
miniShop2.Cart.status(response.data);
}
}
}, "json");
}
});
miniShop2.Callbacks.Cart.change.before = function() {
var $field = $(miniShop2.sendData.$form[0]).find(miniShop2.Cart.countInput);
var count = +$field.val();
if (count < 1) {
$field.val('1');
miniShop2.Message.error('Ошибка! Нельзя ставить кол-во меньше 1!');
return false;
}
return true;
}
});
И получаем результат.Решение от @mngatoff
<script>
$(document)
.on('click touchend', countButton, function (e) { // где countButton - кнопки плюс и минус
e.preventDefault();
var $container = $(this).closest('.ms2_form'),
$count = $container.find('[name="count"]'),
num = $count.val();
if (isNaN(num) === false) { // страховочка от, например, пустого поля
num = parseInt(num, 10);
switch ($(this).data('ms2-count')) { // соответственно, у кнопок должен быть атрибут data-ms2-count="plus или minus"
case 'plus':
num = num + 1;
$count.val(num);
break;
case 'minus':
if (num <= 1) return;
num = num - 1;
$count.val(num);
break;
}
} else {
return false;
}
$count.trigger('change'); // инициализируем отправку на сервер.
})
.on('change keypress keyup', '.ms2_form [name="count"]', function() {
if ($(this).val().match(/\D/)) {
this.value = $(this).val().replace(/\D/g,''); // следим на лету, чтобы в поле были только цифры
}
if (parseInt($(this).val(), 10) < 1) {
this.value = 1; // следим на лету, чтобы в поле было не меньше единицы
}
});
</script>
Ну и обязательно ставим плюсы первому комментарию)
Поблагодарить автора
Отправить деньги
Комментарии: 13
достаточно триггернуть событие change на input:count, и запрос отправится стандартными средствами минишопа.
я вот так делаю (немного вырвано из контекста, но принцип ясен):
я вот так делаю (немного вырвано из контекста, но принцип ясен):
<script>
$(document)
.on('click touchend', countButton, function (e) { // где countButton - кнопки плюс и минус
e.preventDefault();
var $container = $(this).closest('.ms2_form'),
$count = $container.find('[name="count"]'),
num = $count.val();
if (isNaN(num) === false) { // страховочка от, например, пустого поля
num = parseInt(num, 10);
switch ($(this).data('ms2-count')) { // соответственно, у кнопок должен быть атрибут data-ms2-count="plus или minus"
case 'plus':
num = num + 1;
$count.val(num);
break;
case 'minus':
if (num <= 1) return;
num = num - 1;
$count.val(num);
break;
}
} else {
return false;
}
$count.trigger('change'); // инициализируем отправку на сервер.
})
.on('change keypress keyup', '.ms2_form [name="count"]', function() {
if ($(this).val().match(/\D/)) {
this.value = $(this).val().replace(/\D/g,''); // следим на лету, чтобы в поле были только цифры
}
if (parseInt($(this).val(), 10) < 1) {
this.value = 1; // следим на лету, чтобы в поле было не меньше единицы
}
});
</script>
плюс этого варианта еще и в том, что его можно без изменений использовать в карточке товара в форме добавления в корзину
Cпасибо за решение. Добавил как альтернативное в тело статьи.
.on('click touchend', countButton, function (e) { // где countButton — кнопки плюс и минусПодскажите пожалуйста, что нужно вписать в функцию countButton, у меня в консоли вылазиет ошибка:
Uncaught ReferenceError: countButton is not defined
а при нажатии на сами кнопки количество не меняется.
У вас в коде нет «countButton», вот она и не может его найти. Попробуйте кнопкам прописать класс countButton, а в функции написать: .on('click touchend', '.countButton', function (e) {…
Спасибо. Заработало =)
Действительно, вот эта часть вашего кода:
ну очень не нужна
Обратите внимание, что на изменение input[name=count] повешена функция которая отправляет форму.
@mngatoff как раз и предлагает воспользоваться методом trigger или на худой конец можно было бы самостоятельно сабмитить форму
$('div.count').click(function(e) {
var v = $(this).parent().find('input#product_price').val(),
k = $(this).parent().find('input[name="key"]').val();
if (($(this).hasClass('minus') || $(this).hasClass('plus')) && v > 0) {
$.post("", {
ms2_action: 'cart/change',
key: k,
count: v
}, function(response) {
if (typeof response.success !== "undefined") {
if (response.success) {
miniShop2.Order.getcost();
miniShop2.Cart.status(response.data);
}
}
}, "json");
}
});
ну очень не нужна
Обратите внимание, что на изменение input[name=count] повешена функция которая отправляет форму.
@mngatoff как раз и предлагает воспользоваться методом trigger или на худой конец можно было бы самостоятельно сабмитить форму
И еще позвольте немного покритиковать, сюдя по этой вашей строчке:
у каждого товара в корзине есть input с id=«product_price»… Транслируя готовые решения или пошаговые инструкции по хорошему нужно осознавать некую ответственность.
var v = $(this).parent().find('input#product_price').val(),
у каждого товара в корзине есть input с id=«product_price»… Транслируя готовые решения или пошаговые инструкции по хорошему нужно осознавать некую ответственность.
Идентификатор в коде документа должен быть в единственном экземпляре
судя*
Соглашусь с комментариями выше и прошу исправить решение в посте в соответствии с ними! Ибо потом производятся сайты, созданные на копипасте (без мозгов), которые приходится корректировать мне или другим адекватным разработчикам.
Ну и хорошо бы вставлять код в пост не как попало, а хоть как-то его корректируя. Зачем в первом блоке с HTML кодом эти табы вначале каждой строки?
Ну и хорошо бы вставлять код в пост не как попало, а хоть как-то его корректируя. Зачем в первом блоке с HTML кодом эти табы вначале каждой строки?
Ну и хорошо бы вставлять код в пост не как попало, а хоть как-то его корректируя.
Зачем в первом блоке с HTML кодом эти табы вначале каждой строки?
Каюсь) Поправил. Соглашусь с комментариями выше и прошу исправить решение в посте в соответствии с ними!
Обязательно вникну и поправлю основываясь на комментариях выше.
Вот что странно иногда возникают ситуации когда код @mngatoff не срабатывает — у меня миникорзина выпадает через меню dropdown в выпадающий список, Bootstrap 5 — возникает какая-то ошибка и событие change на поле input ну ни в какую не хочет срабатывать. Плюс на сайте может быть несколько корзин.
И тут пригождается кусок кода ms2.js в ТС (только не удаляйте) — прием как отправить ms2_action: 'cart/change' оказался для меня лично очень полезен.
Да не по стандарту, но главное что работает. Может я не адекватный программист, но я уже не знаю как заставить сработать стандартным «правильным» способом $count.trigger('change'), т.к. возникает конфликт с Bootstrap 5 — кстати в нем по умолчанию отключили jQuery — интересно когда коды js minishop перепишут без использования jQuery?..
На другом сайте с Bootstrap 3 все работает нормально.
И тут пригождается кусок кода ms2.js в ТС (только не удаляйте) — прием как отправить ms2_action: 'cart/change' оказался для меня лично очень полезен.
Да не по стандарту, но главное что работает. Может я не адекватный программист, но я уже не знаю как заставить сработать стандартным «правильным» способом $count.trigger('change'), т.к. возникает конфликт с Bootstrap 5 — кстати в нем по умолчанию отключили jQuery — интересно когда коды js minishop перепишут без использования jQuery?..
На другом сайте с Bootstrap 3 все работает нормально.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.