Magento 2 отключить/удалить кнопку корзины из настраиваемого продукта для опций, отсутствующих на складе
Я использую Magento 2.1 и обнаружил, что для настраиваемых продуктов, если какой-либо вариант соответствующего продукта отсутствует на складе, кнопка "Добавить в корзину" все еще видна.
Я хочу скрыть/отключить его, когда выбранного простого продукта нет на складе, чтобы пользователь знал, что продукта нет на складе.
В настоящее время кнопка "Добавить в корзину" видна для всех вариантов товара, и когда я нажимаю "Добавить в корзину", она показывает мне сообщение об ошибке, что товара нет на складе.
Пожалуйста руководство, как я могу этого достичь.
1 answers
Этот ответ предполагает, что вы знаете, как создать модуль в Magento 2, поскольку это выходит за рамки вопроса.
Для начала создайте файл макета в своем модуле, предназначенный для настраиваемого дескриптора продукта. Таким образом, имя файла будет catalog_product_view_type_configurable.xml
, и оно будет храниться в [Vendor]/[Module]/view/frontend/layout
.
Внутри этого создайте блок, который позволит вам добавить шаблон на страницу. Этот блок будет нуждаться в пользовательской функциональности, поэтому его необходимо будет создать. Так, например, ваш xml может выглядеть следующим образом:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product.info.options.wrapper">
<block class="[Vendor]\[Module]\Block\[BlockClass]" name="your.name.here" template="[Vendor]_[Module]::path/to/your/template.phtml" after="-"/>
</referenceBlock>
</body>
</page>
Для включения этой функции на страницу потребуется JS. Здесь мы можем воспользоваться собственным типом скрипта Magento text/x-magento-init
, чтобы заполнить модели и представления JS. Так, например, наш шаблон может выглядеть так:
<?php /** @var \Magento\Catalog\Model\Product $product */ ?>
<?php $product = $block->getProduct(); ?>
<?php if ($product): ?>
<script type="text/x-magento-init">
{
"*": {
"[Vendor]_[Module]/js/path/to/js/file":<?php echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getProductChildData($product->getId())); ?>
}
}
</script>
<?php endif; ?>
Теперь нам нужно заполнить наш JS некоторыми данными о дочерних элементах текущего продукта. Для этого мы можем создать функцию в нашем блоке (здесь я назвал ее getProductChildData()
, но не имеет значения, как вы ее называете очевидно.
Итак, в вашем классе блоков функция будет выглядеть примерно так:
/**
* Array of attributes to be used for stock data
*
* @var array
*/
protected $_stockDataAttributes = [
'qty',
'is_in_stock'
];
public function getProductChildData($productId)
{
$data = [];
/** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable $_configurableProductModel */
$children = $this->_configurableProductModel->getChildrenIds($productId);
foreach ($children as $child) {
foreach ($child as $item) {
/** @var \Magento\CatalogInventory\Model\StockRegistry $_stockItemRegistry */
$stockItem = $this->_stockItemRegistry->getStockItem($item);
if($stockItem) {
foreach ($this->_stockDataAttributes as $attribute) {
$data[$item][$attribute] = $stockItem->getData($attribute);
}
}
}
}
return $data;
}
Теперь все, что нам нужно, это наш JS для обработки данных, чтобы показывать кнопку "Купить сейчас" /делать все, что вам нравится, с помощью кнопки "Купить сейчас", когда товар есть на складе.
Так, например, ваш JS может выглядеть так:
define([
'jquery',
'domReady!'
], function ($) {
'use strict';
$.widget('name.of.widget', {
options: {
},
_create: function () {
this._bind();
},
_bind: function() {
var options = this.options;
var select = $('[class^="super-attribute"]');
var id = $('[name="selected_configurable_option"]');
var self = this;
setTimeout(function() {
select.on("change", function() {
if(typeof options[id.val()] !== 'undefined') {
if (options[id.val()].is_in_stock == 0) {
self._toggleShow(0);
} else {
self._toggleShow(1);
}
}
})}, 300);
},
_toggleShow: function (inStock) {
if (inStock) {
$('.box-tocart').removeClass('no-display');
} else if(!inStock) {
$('.box-tocart').addClass('no-display');
}
}
});
return $.name.of.widget;
});
Затем следует использовать данные, проанализированные как данные JSON из блока, чтобы определить, есть ли на складе вариация продукта или нет. Если это не так, то это будет скройте добавление в корзину, если оно есть в наличии, оно отобразится.