2

I am trying to make auto select first child product from the configurable product in product detail page.

Is this possible?

10

For Dropdown:

Override this file to your theme:

vendor/magento/module-configurable-product/view/frontend/web/js/configurable.js

your theme file location will be:

app/design/frontend/[vendor]/[theme]/Magento_ConfigurableProduct/web/js/configurable.js

Replace the _fillSelect method under configurable.js

_fillSelect: function (element) {
    var attributeId = element.id.replace(/[a-z]*/, ''),
        options = this._getAttributeOptions(attributeId),
        prevConfig,
        index = 1,
        allowedProducts,
        i,
        j;

    this._clearSelect(element);
    element.options[0] = new Option('', '');
    element.options[0].innerHTML = this.options.spConfig.chooseText;
    prevConfig = false;

    if (element.prevSetting) {
        prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];
    }

    if (options) {
        for (i = 0; i < options.length; i++) {
            allowedProducts = [];
            if (prevConfig) {
                for (j = 0; j < options[i].products.length; j++) {
                    // prevConfig.config can be undefined
                    if (prevConfig.config &&
                        prevConfig.config.allowedProducts &&
                        prevConfig.config.allowedProducts.indexOf(options[i].products[j]) > -1) {
                        allowedProducts.push(options[i].products[j]);
                    }
                }
            } else {
                allowedProducts = options[i].products.slice(0);
            }

            if (allowedProducts.length > 0) {
                options[i].allowedProducts = allowedProducts;
                element.options[index] = new Option(this._getOptionLabel(options[i]), options[i].id);
                if (typeof options[i].price !== 'undefined') {
                    element.options[index].setAttribute('price', options[i].prices);
                }

                element.options[index].config = options[i];




                index++;
            }
            // Code added to select option
            if (i == 0) {
                this.options.values[attributeId] = options[i].id;
            }   
        }
        //Code added to check if configurations are set in url and resets them if needed 
        if (window.location.href.indexOf('#') !== -1) {this._parseQueryParams(window.location.href.substr(window.location.href.indexOf('#') + 1));}
    }

},

For Swatch: Override the below file to your theme

/module-swatches/view/frontend/web/js/SwatchRenderer.js

And update the method _RenderControls

_RenderControls: function () {
    var $widget = this,
        container = this.element,
        classes = this.options.classes,
        chooseText = this.options.jsonConfig.chooseText,
        selectedArray = []; // Variable declation for autoselect element array

    $widget.optionsMap = {};

    $.each(this.options.jsonConfig.attributes, function () {
        var item = this,
            controlLabelId = 'option-label-' + item.code + '-' + item.id,
            options = $widget._RenderSwatchOptions(item, controlLabelId),
            select = $widget._RenderSwatchSelect(item, chooseText),
            input = $widget._RenderFormInput(item),
            listLabel = '',
            label = '';

        // Show only swatch controls
        if ($widget.options.onlySwatches && !$widget.options.jsonSwatchConfig.hasOwnProperty(item.id)) {
            return;
        }

        if ($widget.options.enableControlLabel) {
            label +=
                '<span id="' + controlLabelId + '" class="' + classes.attributeLabelClass + '">' +
                    item.label +
                '</span>' +
                '<span class="' + classes.attributeSelectedOptionLabelClass + '"></span>';
        }

        if ($widget.inProductList) {
            $widget.productForm.append(input);
            input = '';
            listLabel = 'aria-label="' + item.label + '"';
        } else {
            listLabel = 'aria-labelledby="' + controlLabelId + '"';
        }

        // Create new control
        container.append(
            '<div class="' + classes.attributeClass + ' ' + item.code + '" ' +
                 'attribute-code="' + item.code + '" ' +
                 'attribute-id="' + item.id + '">' +
                label +
                '<div aria-activedescendant="" ' +
                     'tabindex="0" ' +
                     'aria-invalid="false" ' +
                     'aria-required="true" ' +
                     'role="listbox" ' + listLabel +
                     'class="' + classes.attributeOptionsWrapper + ' clearfix">' +
                    options + select +
                '</div>' + input +
            '</div>'
        );

        $widget.optionsMap[item.id] = {};

        // Aggregate options array to hash (key => value)
        $.each(item.options, function () {
            if (this.products.length > 0) {
                $widget.optionsMap[item.id][this.id] = {
                    price: parseInt(
                        $widget.options.jsonConfig.optionPrices[this.products[0]].finalPrice.amount,
                        10
                    ),
                    products: this.products
                };
            }
        });
        //Create array for Autoselect swatch
        selectedArray.push($widget.element.find('[attribute-id=' + item.id + '] .swatch-option')[0]);
    });


    // Connect Tooltip
    container
        .find('[option-type="1"], [option-type="2"], [option-type="0"], [option-type="3"]')
        .SwatchRendererTooltip();

    // Hide all elements below more button
    $('.' + classes.moreButton).nextAll().hide();

    // Handle events like click or change
    $widget._EventListener();

    // Rewind options
    $widget._Rewind(container);

    //Emulate click on all swatches from Request
    $widget._EmulateSelected($.parseQuery());
    $widget._EmulateSelected($widget._getSelectedAttributes());

    //Trigger click for Autoselect first option swatch
    $.each(selectedArray, function () {
        if(this != undefined) this.click();
    });

},
  • Hello, i am using module swatch , the above code is for drop downs i guess, can we make it work for swatches also? – jafar pinjar Jul 2 '18 at 15:42
  • Please check my updated answer. – Sukumar Gorai Jul 2 '18 at 15:46
  • checked but i am getting $.parseParams is not a function error – jafar pinjar Jul 2 '18 at 15:54
  • 1
    Thanks this code is working perfectly for magento 2.3 also – kushal May 1 at 11:53
  • 1
    Code is working perfectly – Shorabh yesterday

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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