Иногда для интернет-магазина бывает полезно сделать быстрый просмотр товара в pop up, вместо открытия в новом окне, без лишней информации, . Здесь расскажу, как достаточно легко сделать быстрый просмотр для популярного магазина под MODX miniShop2.
Для реализации понадобится не так уж много: новый ресурс для вызова сниппета + сам сниппет для получения полей определенного ресурса + чанк, в котором будет шаблон товара + Ajax запрос. Ну и останется оформить все это в CSS.
Поскольку каждый товар имеет свой шаблон, который в popup использовать не получится, нужно будет получать содержимое через другой ресурс
Для начала добавим кнопку вызова popup в чанк товаров (tpl.msProducts.row по-умолчанию)
<span class="btn btn-default openajax" data="{$id}">Просмотр</span>
На класс openajax будет реагировать JS, в аттрибуте data передается id товара
Ajax запрос
Здесь не используются элементы шаблона, так что можно использовать в js файле
$('.openajax').click(function() {
var id = $(this).attr('data');
if (id > 0) {/*На всякий случай решил сделать проверку на ID*/
$.ajax({
url: '/formpopup.html',
type: 'post',
data: {
id: id,
},
dataType: 'json',
beforeSend: function() {
$(this).html('loading');
},
complete: function() {
},
success: function(json) {
if (json) {
$('body').append(json);
}
}
});
}
});
Теперь нужно создать страницу (ресурс) с URI "formpopup.html". Название не имеет значения, шаблон - пустой. Содержимое:
[[!GetAjax]]
Сниппет
Создадим сниппет с названием GetAjax
В сниппете получим заголовок, описание, цену и передадим это в чанк. Опции, изображения при этом здесь не нужны, их можно вызвать через другие сниппеты уже из чанка.
<?php
$out='';
$row = array();
$resid = (int)$_POST['id'];
$product = $modx->getObject('msProduct', $resid);
$row['pagetitle'] = $product->pagetitle;
$row['content'] = $product->content;
$row['price'] = $product->get('price');
$row['old_price'] = $product->get('old_price');
$row['id'] = $resid;
$out = $modx->getChunk('GetAjaxProdPopup', $row);/*GetAjaxProdPopup - имя чанка с товаром*/
return json_encode($out);
Теперь нужно создать чанк GetAjaxProdPopup
Чанк
Для начала код, после - пояснения.
<div class="popup" id="tovar" style="display: block;">
<link rel="stylesheet" type="text/css" href="/assets/components/minishop2/css/web/lib/fotorama.min.css">
<script type="text/javascript" src="/assets/components/minishop2/js/web/lib/fotorama.min.js"></script>
<span class="bcgrnd close"></span>
<div>
<i class="close fas fa-times"></i>
<div class="row">
<div class="col-sm-6">[[msGallery? &product=`[[+id]]`]]</div>
<div class="col-sm-6 ms2_product">
<h1>[[+pagetitle]]</h1>
<form method="post" class="ms2_form align-items-center no-gutters">
<input type="hidden" name="id" value="[[+id]]">
<input type="hidden" name="count" value="1">
<input type="hidden" name="options" value="[]">
[[msOptions? &product=`[[+id]]`]]
[[msProductOptions? &product=`[[+id]]`]]
<div class="price-box">
<div class="price">[[+price]]</div>
[[+old_price:ne=``:then=`<div class="price">[[+old_price]]</div>`]]
</div>
<button class="btn btn-primary" type="submit" name="ms2_action" value="cart/add">В корзину</button>
</form>
</div>
</div>
<p class="desc">[[+content]]</p>
</div>
<script>
$('.close').click(function() {
$(this).parents('.popup').hide(50).remove();
});
</script>
</div>
Все содержимое чанка будет вызываться через ajax и помещаться перед закрытием body. Здесь важно, что бы вызов jQuery был так же до закрытия body, перед содержимым чанка.
В чанк добавлено подключение галереи "Fotorama", для корректного отображения изображений. Вызов окна, как предполагаю, будет со страниц категорий, или главной. Честно говоря не проверял работу со страницы товара, где скрипт галереи уже добавлен. Возможно нужно будет использовать в чанке вот такую проверку:
[[*template:ne=`11111111`:then=`
<link rel="stylesheet" type="text/css" href="/assets/components/minishop2/css/web/lib/fotorama.min.css">
<script type="text/javascript" src="/assets/components/minishop2/js/web/lib/fotorama.min.js"></script>
`]]
Где 11111111 - id шаблона товара
Так же в окне есть два элемента с классом "close" - фон окна и кнопка закрытия, для работы которых и добавлен скрипт вконце. По нажатию окно скрывается и удаляется. Для кнопки использую иконку font awesome. Может не отображаться даже при подключенном скрипте font awesome, обратите внимание на классы fas/fa
Осталось оформить все это в CSS
CSS
Такой вариант popup использую часто и приведенный CSS достаточно универсален, что бы не приходилось каждый раз что то сильно менять. В примере так же приведу полный вариант, все что касается отличий именно для этого окна будет начинаться с "#tovar".
.popup {display: none;position: fixed;top: 0px;left: 0px;width: 100%;height: 100%;z-index: 99;overflow: hidden;}
#tovar.popup {display:block;}
.popup.open {display: block;}
.popup .bcgrnd.close {position: absolute;top:0px;left: 0px;width: 100%;height: 100%;background: rgba(0, 0, 0, 0.75);border-radius: 0px;min-height: 600px;}
.popup .bcgrnd.close:hover {background: rgba(0, 0, 0, 0.6);}
.popup > div {width: 510px;box-sizing: border-box;margin-left: auto;margin-right: auto;background-color: #fff;top:15%;position: relative;padding: 30px;border-radius: 4px;box-shadow: 0px 0px 5px #fff;max-height: 95%;overflow: auto;max-width: 98% !important;}
#tovar.popup > div {width: 1170px;}
.popup i.close {height: 40px;width: 40px;font-size: 32px;border-radius: 50px;position: absolute;right: 0px;top: 0px;opacity: 1;display: block;text-align: center;cursor: pointer;color: #533423}
.popup > div > .close {z-index: 9999;}
.popup .form-group {width: 100%;margin-bottom: 5px;}
.popup .form-group.nobg {background: none;}
.popup .title {font-size: 15px;text-align: center;text-transform: uppercase;}
.popup .form {border: 2px solid #606;border-radius: 5px;box-shadow: 0px 0px 5px #8e008d;}
.popup .form .price {text-align: center;margin-bottom: 5px;}
.popup .form > div {background: rgba(255, 255, 255, 0.6);text-shadow: 0px 0px 3px #fff;}
.popup .alert-success {position: absolute;top: 40%;width: 100%;margin-left: -30px;box-shadow: 0px 0px 100px 50px #f8ffce;text-align: center;}
.popup .submit {width: 200px;display: block;margin: 0px auto;}
Вот и все. Пишите в комментариях если что-то не работает.
Спасибо за полезную информацию!
Стоит добавить, что Ajax запрос лучше сделать так:
$(«body»).on(«click», ".openajax", function () {
var id = $(this).attr('data');
if (id > 0) {/*На всякий случай решил сделать проверку на ID*/
$.ajax({
url: '/formpopup.html',
type: 'post',
data: {
id: id,
},
dataType: 'json',
beforeSend: function() {
$(this).html('loading');
},
complete: function() {
},
success: function(json) {
if (json) {
$('body').append(json);
}
}
});
}
});
Чтобы делегировать скрипты, для вновь подгруженных динамических элементов и не потребуется повторная инициализация скриптов.