4

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> 
0

2 Answers 2

13
+50

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

53
8

You can find prodcutId from [Magento_Root]\vendor\magento\module-swatches\view\frontend\web\js\swatch-renderer.js

find _OnClick function.

_OnClick: function ($this, $widget) {
        var $parent = $this.parents('.' + $widget.options.classes.attributeClass),
            $label = $parent.find('.' + $widget.options.classes.attributeSelectedOptionLabelClass),
            attributeId = $parent.attr('attribute-id'),
            $input = $parent.find('.' + $widget.options.classes.attributeInput);

        if ($widget.inProductList) {
            $input = $widget.productForm.find(
                '.' + $widget.options.classes.attributeInput + '[name="super_attribute[' + attributeId + ']"]'
            );
        }

        if ($this.hasClass('disabled')) {
            return;
        }

        if ($this.hasClass('selected')) {
            $parent.removeAttr('option-selected').find('.selected').removeClass('selected');
            $input.val('');
            $label.text('');
        } else {
            $parent.attr('option-selected', $this.attr('option-id')).find('.selected').removeClass('selected');
            $label.text($this.attr('option-label'));
            $input.val($this.attr('option-id'));
            $this.addClass('selected');
            console.log($this.attr('option-id')); // Here you can find selected simple product id
        }

        $widget._Rebuild();

        if ($widget.element.parents($widget.options.selectorProduct)
                .find(this.options.selectorProductPrice).is(':data(mage-priceBox)')
        ) {
            $widget._UpdatePrice();
        }

        $widget._LoadProductMedia();
        $input.trigger('change');
    },

It will help you.

2
  • how to get in list.phtml file Commented May 27, 2019 at 11:23
  • you can add new hidden field and update on click event. after that you will get that hidden field value in list.phtml. Make sure unique value to get that. Commented May 27, 2019 at 11:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.