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
  • answer updated. Commented May 27, 2019 at 7:38
  • You can get product id here and pass to custom controller for php code Commented May 27, 2019 at 7:57
  • You can override js file by module...check this out - magento.stackexchange.com/questions/60276/… Commented May 27, 2019 at 8:34
  • Override is not working? Commented May 27, 2019 at 9:50
  • Did you run upgrade and deploy commands? Commented May 27, 2019 at 10:04
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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.