4

How to set drops downs on configurable products to be set to the first option rather than please select.

I have tried below code:

<script>
require(['jquery', 'jquery/ui'], function($){ 
  $('.product-add-form .field select').each(function(i, obj) {
    $(obj).find('option:eq(1)').prop('selected', true);
  });
});
</script>

However, this fails unless I time it out a bit which feels messy. It also does not update price when using this method.

2

3 Answers 3

11

Override configurable.js within the Configurable Products Module. The following code can be placed at around line 370 of configurable.js:

if (i == 0) {
    this.options.values[attributeId] = options[i].id;
}   

This is placed at the end of options loop so that the default option is set just after the first option is created for each attribute / select.

In the case that options were set in url the code for updating defaults was needed to run again to set the values correctly which can be achieved by adding below just outside of the loop:

if (window.location.href.indexOf('#') !== -1) {this._parseQueryParams(window.location.href.substr(window.location.href.indexOf('#') + 1));}

This is placed just after the for loop for options so that it's run just once at the end of the option creation.

So _fillSelect within configurable.js now should look like below:

_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++;
                }
                //new code here - updates the value to first option
                if (i == 0) {
                    this.options.values[attributeId] = options[i].id;
                }   
            }
            //new code here checks 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));}
        }

    },

Original file:

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

Location when overridden in theme:

app/design/frontend/ThemeVendor/Theme/Magento_ConfigurableProduct/web/js/configurable.js

3
  • Nothing happens on my magento 2.3.4
    – Silver
    Commented Oct 22, 2020 at 16:22
  • highest option value preselected of size atribute
    – Himanshu
    Commented May 21, 2021 at 9:53
  • Yes..its working fine for me.
    – vijay rami
    Commented Nov 12, 2021 at 10:12
5

Override vendor\magento\module-swatches\view\frontend\web\js\swatch-renderer.js to your theme
your theme file location will be:
app/design/frontend/Vendor/themename/Magento_Swatches/web/js/swatch-renderer.js

change _RenderControls() function

just wrinte below code at the end of this function

var swatchLength = $('.swatch-attribute').length;
if(swatchLength >= 1){
    if($('.swatch-attribute').hasClass("size")){
        $('.swatch-option').first().trigger('click');
    }
}

http://prntscr.com/n6qo62

2
  • not working on product listing page Commented Jul 14, 2020 at 8:01
  • Hey @Jigs it's work for me . Thank you !! Commented Mar 4, 2022 at 7:41
1

I did same thing as jigs suggestion, Thanks jigs But i need to check selected option size first and if no any option was selected then we fire click event on first element.

i follow bellow steps override / copy swatch-renderer.js from

vendor/magento/module-swatches/view/frontend/web/js

To your custom theme

app/design/frontend/{{vendor}}/{{theme}}/Magento_Swatches/web/js

Find _RenderControls: function () and replace

$widget._EmulateSelected($.parseQuery()); $widget._EmulateSelected($widget._getSelectedAttributes());

with

$widget._EmulateSelected($.parseQuery()); $widget._EmulateSelected($widget._getSelectedAttributes());

if($(".swatch-opt .swatch-attribute").find(".selected").length == 0)

$('.swatch-option').first().trigger('click');

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.