8

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

Is this possible?

1 Answer 1

24

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();
    });

},
22
  • Hello, i am using module swatch , the above code is for drop downs i guess, can we make it work for swatches also? Jul 2, 2018 at 15:42
  • 1
    After upgrading to 2.3.1 this method stopped working for some dropdowns. I'm not entirely sure why but the fix was easy, just change if (i == 0) to if (i === 0) Apr 24, 2019 at 16:08
  • 1
    Thanks this code is working perfectly for magento 2.3 also
    – kushal
    May 1, 2019 at 11:53
  • 1
    Code is working perfectly
    – Shorabh
    Jul 18, 2019 at 11:33
  • 1
    Thanks sukumar instead of theme how to override the same function from custom module? Dec 26, 2019 at 14:01

Your Answer

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

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