Magento 2 – Get Selected Simple Product on Swatch Option Change

category-productsmagento2

When change a swatch option how to get a selected simple product id from configurable in category product listing page in Magento 2

when I select a swatch option, I was get a option id, from the option id how to get a simple product id from configurable product

Refer image : https://prnt.sc/ntsay1

code:

app\code\Cm\Preorder\view\frontend\templates\product\list.phtml

    <script type="text/javascript">
requirejs(['jquery','underscore'], function(jQuery,_){
    jQuery(window).load(function(){
        jQuery( '[class*="swatch-opt"]' ).on('click', '.swatch-option', function() {

            selpro();

        });
    });
    function selpro () {
        var selected_options = {};
        jQuery('div.swatch-attribute').each(function(k,v){
            var attribute_id    = jQuery(v).attr('attribute-id');
            var option_selected = jQuery(v).attr('option-selected');
            // console.log(attribute_id, option_selected);
            if(!attribute_id || !option_selected){ return;}
            selected_options[attribute_id] = option_selected;
        });
             console.log(selected_options);

    }
});

</script> 

Best Answer

Create plugin to add quantity to the JS config to get from swatch renderer

Vendor/Module/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\ConfigurableProduct\Block\Product\View\Type\Configurable">
        <plugin name="vendor_configurable_product_configurable"
                type="vendor\module\Plugin\Block\ConfigurableProduct\Product\View\Type\Configurable"
                sortOrder="1"/>
    </type>
</config>

Create a plugin file with quantity script below in vendor\module\Plugin\Block\ConfigurableProduct\Product\View\Type\Configurable.php

<?php

namespace vendor\module\Plugin\Block\ConfigurableProduct\Product\View\Type;

use Magento\Framework\Json\EncoderInterface;
use Magento\Framework\Json\DecoderInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;

class Configurable
{

    protected $jsonEncoder;
    protected $jsonDecoder;
    protected $stockRegistry;

    public function __construct(
        EncoderInterface $jsonEncoder,
        DecoderInterface $jsonDecoder,
        StockRegistryInterface $stockRegistry
    ) {

        $this->jsonDecoder = $jsonDecoder;
        $this->jsonEncoder = $jsonEncoder;
        $this->stockRegistry = $stockRegistry;
    }

    // Adding Quantitites (product=>qty)
    public function aroundGetJsonConfig(
        \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable $subject,
        \Closure $proceed
    )
    {
        $quantities = [];
        $config = $proceed();
        $config = $this->jsonDecoder->decode($config);

        foreach ($subject->getAllowProducts() as $product) {
            $stockitem = $this->stockRegistry->getStockItem(
                $product->getId(),
                $product->getStore()->getWebsiteId()
            );
            $quantities[$product->getId()] = $stockitem->getQty();
        }

        $config['quantities'] = $quantities;

        return $this->jsonEncoder->encode($config);
    }
}

And your phtml looks like

<span class="classname"><?php echo $_product->getId(); ?></span>

You can get product quantity from swatches you need to override vendor/magento/module-swatches/view/frontend/web/js/swatch-renderer.js function _Rebuild add following code..

 //Check weather product list page or view page
    if ($('body.catalog-product-view').size() <= 0) {
        if( controls.size() == selected.size()){
            var productQty = $widget.options.jsonConfig.quantities[this.getProduct()];
            $widget.element.parents('.product-item-info').find('.classname').html(productQty);
        }
    }

finally it looks like

       _Rebuild: function () {
            var $widget = this,
                controls = $widget.element.find('.' + $widget.options.classes.attributeClass + '[attribute-id]'),
                selected = controls.filter('[option-selected]');

            // Enable all options
            $widget._Rewind(controls);

            // done if nothing selected
            if (selected.size() <= 0) {
                return;
            }

    //Check weather product list page or view page
    if ($('body.catalog-product-view').size() <= 0) {
        if( controls.size() == selected.size()){
            var productQty = $widget.options.jsonConfig.quantities[this.getProduct()];
            $widget.element.parents('.product-item-info').find('.classname').html(productQty);
        }
    }

            // Disable not available options
            controls.each(function () {
                var $this = $(this),
                    id = $this.attr('attribute-id'),
                    products = $widget._CalcProducts(id);

                if (selected.size() === 1 && selected.first().attr('attribute-id') === id) {
                    return;
                }

                $this.find('[option-id]').each(function () {
                    var $element = $(this),
                        option = $element.attr('option-id');

                    if (!$widget.optionsMap.hasOwnProperty(id) || !$widget.optionsMap[id].hasOwnProperty(option) ||
                        $element.hasClass('selected') ||
                        $element.is(':selected')) {
                        return;
                    }

                    if (_.intersection(products, $widget.optionsMap[id][option].products).length <= 0) {
                        $element.attr('disabled', true).addClass('disabled');
                    }
                });
            });
        },

You can add your logic here instead of adding scripts in phtml files.

To override js file copy from vendor/magento/module-swatches/view/frontend/web/js/swatch-renderer.js to app/design/VENDOR/THEME/Magento_Swatches/web/js/swatch-renderer.js Run upgrade and content deploy to see changes

Related Topic