Magento 2 отключить/удалить кнопку корзины из настраиваемого продукта для опций, отсутствующих на складе


Я использую Magento 2.1 и обнаружил, что для настраиваемых продуктов, если какой-либо вариант соответствующего продукта отсутствует на складе, кнопка "Добавить в корзину" все еще видна.
Я хочу скрыть/отключить его, когда выбранного простого продукта нет на складе, чтобы пользователь знал, что продукта нет на складе.
В настоящее время кнопка "Добавить в корзину" видна для всех вариантов товара, и когда я нажимаю "Добавить в корзину", она показывает мне сообщение об ошибке, что товара нет на складе.
Пожалуйста руководство, как я могу этого достичь.

Author: John, 2017-03-14

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 из блока, чтобы определить, есть ли на складе вариация продукта или нет. Если это не так, то это будет скройте добавление в корзину, если оно есть в наличии, оно отобразится.

 2
Author: Richard Cripps, 2017-03-14 07:35:33