0

I want to get product id on selecting swatch option.for that i have used code as given below. i am getting error of "Cannot read properties of undefined (reading 'options')" as per given screenshot.i am using Magento 2.4.4. if i print simple console.log(" hello world ") using this Js code this will execute but for select options it throws error.

error:- https://i.stack.imgur.com/cAsgD.png

/app/code/Vendor/Module/view/frontend/templates/product/view/type/default.phtml

<script>
    requirejs(['jquery','underscore','Magento_Catalog/js/price-utils','mage/url'],
        function(jQuery,_,flooring,priceUtils,urlBuilder){
        jQuery(window).on('load',function(){
            jQuery( ".product-options-wrapper div" ).click(function() {
                selpro();
            });
        });
        function selpro () {
            var selected_options = {};
            jQuery('div.swatch-attribute').each(function(k,v){
                var attribute_id    = jQuery(v).attr('data-attribute-id');
                var option_selected = jQuery(v).attr('data-option-selected');
                if(!attribute_id || !option_selected){ return;}
                selected_options[attribute_id] = option_selected;
            });
            
            var product_id_index = jQuery('[data-role=swatch-options]').data('mageSwatchRenderer').options.jsonConfig.index;
            var found_ids = [];
            jQuery.each(product_id_index, function(product_id,attributes){
                var productIsSelected = function(attributes, selected_options){
                    return _.isEqual(attributes, selected_options);
                }
                if(productIsSelected(attributes, selected_options)){
                    found_ids.push(product_id);
                }
            });
            var new_found_ids = found_ids[0];             
        }
    });
</script>

/app/code/Vendor/Module/view/frontend/layout/catalog_product_view_type_configurable.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.configurable">
            <action method="setTemplate">
                <argument name="template" xsi:type="string">Vendor_Module::product/view/type/default.phtml</argument>
            </action>
        </referenceBlock>
    </body>
</page>

1 Answer 1

1

Following code work for me you can try it.

app\code\Vendor\Extension\etc\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 disabled="false" name="Vendor_Extension_Plugin_ConfigurableProduct_Block_Product_View_Type_Configurable" sortOrder="10" type="Vendor\Extension\Plugin\ConfigurableProduct\Block\Product\View\Type\Configurable"/>
    </type>
 
    <type name="Magento\Swatches\Block\Product\Renderer\Configurable">
        <plugin disabled="false" name="Vendor_Extension_ConfigurableSkuSwitch_Plugin_Magento_Swatches_Block_Product_Renderer_Configurable" sortOrder="10" type=" Vendor \ Extension \Plugin\Swatches\Block\Product\Renderer\Configurable"/>
    </type>
</config>

app\code\Vendor\Extension\Plugin\ConfigurableProduct\Block\Product\View\Type\Configurable.php

<?php
namespace Vendor\Extension\Plugin\ConfigurableProduct\Block\Product\View\Type;
 
class Configurable
{
 
    public function afterGetJsonConfig(
        \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable $subject,
        $result
    ) {
 
    $jsonResult = json_decode($result, true);
    $jsonResult['skus'] = [];
        foreach ($subject->getAllowProducts() as $simpleProduct) {
            $jsonResult['skus'][$simpleProduct->getId()] = $simpleProduct->getSku();
    }
    $result = json_encode($jsonResult);
        return $result;
    }
}

app\code\Vendor\Extension\Plugin\Swatches\Block\Product\Renderer\Configurable.php

<?php
namespace Vendor\Extension\Plugin\Swatches\Block\Product\Renderer;
 
class Configurable
{
    public function afterGetJsonConfig(\Magento\Swatches\Block\Product\Renderer\Configurable $subject, $result) {
 
        $jsonResult = json_decode($result, true);
        $jsonResult['skus'] = [];
 
        foreach ($subject->getAllowProducts() as $simpleProduct) {
           $jsonResult['skus'][$simpleProduct->getId()] = $simpleProduct->getSku();
        }
        $result = json_encode($jsonResult);
        return $result;
    }
}

app\code\Vendor\Extension\view\frontend\requirejs-config.js

var config = {
    config: {
        mixins: {
            'Magento_ConfigurableProduct/js/configurable': {
                'Vendor_Extension/js/model/skuswitch': true
            },
            'Magento_Swatches/js/swatch-renderer': {
                'Vendor_Extension/js/model/swatch-skuswitch': true
            }
        }
    }
};

app\code\Vendor\Extension\view\frontend\web\js\model\skuswitch.js

    define([
    'jquery',
    'mage/utils/wrapper'
], function ($, wrapper) {
    'use strict';
 
    return function(targetModule){
 
        var reloadPrice = targetModule.prototype._reloadPrice;
        var reloadPriceWrapper = wrapper.wrap(reloadPrice, function(original){
        var result = original();
        var simpleSku = this.options.spConfig.skus[this.simpleProduct];
 
            if(simpleSku != '') {
                $('div.product-info-main .sku .value').html(simpleSku);
            }
            return result;
        });
        targetModule.prototype._reloadPrice = reloadPriceWrapper;
        return targetModule;
    };
});

app\code\Vendor\Extension\view\frontend\web\js\model\swatch-skuswitch.js

define([
    'jquery',
    'mage/utils/wrapper'
], function ($, wrapper) {
    'use strict';
 
    return function(targetModule){
        var updatePrice = targetModule.prototype._UpdatePrice;
        targetModule.prototype.configurableSku = $('div.product-info-main .sku .value').html();
        var updatePriceWrapper = wrapper.wrap(updatePrice, function(original){
            var allSelected = true;
            for(var i = 0; i<this.options.jsonConfig.attributes.length;i++){
                if (!$('div.product-info-main .product-options-wrapper .swatch-attribute.' + this.options.jsonConfig.attributes[i].code).attr('data-option-selected')){
                    allSelected = false;
                }
            }
            var simpleSku = this.configurableSku;
            if (allSelected){
                var products = this._CalcProducts();
                simpleSku = this.options.jsonConfig.skus[products.slice().shift()];
            }
            $('div.product-info-main .sku .value').html(simpleSku);
              return original();
        });
 
        targetModule.prototype._UpdatePrice = updatePriceWrapper;
        return targetModule;
    };
});

Note: this will update SKU on selection you can modify as per your need.

1

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.