2

I am using Magento CE 1.9.2.4, and the Porto Theme. I have some Configurable Products with a lot of variants (in some cases there are 5 attributes, each with several options). Each variant has a Simple Product associated with it, and the prices are set up under the Super Product Attribute Configuration.

Everything looks correct in Admin as far as I can tell.

On the Front end product page, the first time you select your options is fine, some options are disabled (greyed out) based on the choices you select. (For example, a certain Size may not be available in a certain Colour, and that Colour may not be available for one if the other choices etc)

However, if you then change your mind, and what to select a different combination of options, you can't do this because some options remain disabled.

You have to reload the page completely, to reset all the options back to 'Choose an option...'.

I understand this a theme issue, but it is expected behavior since RWD and Colour Swatches were introduced (as described in Configurable products..... Am I missing something?)

This doesn't sound right? It seems like a bug to me?!

If I change the 'Custom Design' of a product page to use something like the 'modern' theme instead, it works as I would expect. The first drop-down options are not disabled, and if you change the value, it resets all the options below it to 'Choose an option...' and re-populates them accordingly.

I have looked though \app...[theme]......\options\configurable.phtml code and configurable.js but cannot find what causes this behavior.

Has anyone come across this issue? Or have any advice on how you would revert back to using 'just' the product options behavior described above (the pre RWD & Swatch Module behavior) without breaking the basic functionality of your child theme?

I imagine you could just delete the \app...[theme]......\options\configurable.phtml file and try and deal with the impact, but is there a better way?

2 Answers 2

1

Have a look at /skin/frontend/rwd/default/js/configurableswatches/swatches-product.js

It overrides many of the functions in configurable.js, and is responsible for loading all of the <select> fields with their options upfront rather than as they are selected (which is how configurable.js handles them). I'm guessing there is a swatches-product.js or similar in the Porto theme (don't have the theme, so I can't confirm).

I wish I could offer a more helpful answer, but I've only come across your question because I'm having a similar problem. I may be able to update later once I've investigated further, but I hope this at least offers some direction in the meantime.

Update:

I think you may be looking for this, which is on line 612 of swatches-product.js:

/**
 *
 * Reset all the options and their availability, the attribute labels, and the stock status
 **/
resetAvailableOptions: function() {
    var opt = this._E.optionOver;

    if (opt) {
        var attr = opt.attr;

        // Reset last label
        attr._e.attrLabel.innerHTML = attr._e.selectedOption ? this.getOptionLabel(attr._e.selectedOption) : '';

        // Reset current action
        this._F.currentAction = false;

        // process
        if (!attr._f.isCustomOption) {
            // Reset the availability of all options
            this.setAvailableOptions();
            // Set stock status
            this.checkStockStatus();
        }

        // reset the last optionOver
        this._E._last.optionOver = false;
    };
},
1
  • 1
    Thanks this pointed me in the right direction. In /swatches-product.js on line 30 and line 34, it is overriding the functionality from /js/varien/configurable.js which deals with filling the selects and resetting the children. Commented Jun 1, 2016 at 10:49
2

To achieve what I wanted I did the following:

In /skin/frontend/[Theme]/js/configurableswatches/swatches-product.js

Change:

// rewrite the fillselect method from /js/varien/configurable.js
Product.Config.prototype.fillSelect = function (element) {
    return;
};

To:

// rewrite the fillselect method from /js/varien/configurable.js
Product.Config.prototype.fillSelect = function (element) {
    var attributeId = element.id.replace(/[a-z]*/, '');
    var options = this.getAttributeOptions(attributeId);
    this.clearSelect(element);
    element.options[0] = new Option('', '');
    element.options[0].innerHTML = this.config.chooseText;

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

    if(options) {
        var index = 1;
        for(var i=0;i<options.length;i++){
            var allowedProducts = [];
            if(prevConfig) {
                for(var j=0;j<options[i].products.length;j++){
                    if(prevConfig.config.allowedProducts
                        && prevConfig.config.allowedProducts.indexOf(options[i].products[j])>-1){
                        allowedProducts.push(options[i].products[j]);
                    }
                }
            } else {
                allowedProducts = options[i].products.clone();
            }

            if(allowedProducts.size()>0){
                options[i].allowedProducts = allowedProducts;
                element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price), options[i].id);
                if (typeof options[i].price != 'undefined') {
                    element.options[index].setAttribute('price', options[i].price);
                }
                element.options[index].config = options[i];
                index++;
            }
        }
    }
    //return;
};

And also change:

// rewrite the resetChildren method from /js/varien/configurable.js; it would reset the third attribute when selecting a swatch in the first attribute
Product.Config.prototype.resetChildren = function (element) {
    return;
};

To:

// rewrite the resetChildren method from /js/varien/configurable.js; it would reset the third attribute when selecting a swatch in the first attribute
Product.Config.prototype.resetChildren = function (element) {
        if(element.childSettings) {
            for(var i=0;i<element.childSettings.length;i++){
                element.childSettings[i].selectedIndex = 0;
                element.childSettings[i].disabled = true;
                if(element.config){
                    this.state[element.config.id] = false;
                }
            }
        }
    //return;
};

This reinstated the product options behavior from the base theme to my child theme.

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.