Configurable Product – How to Stop Other Attributes Changing Swatch Image

configurable-productsimple-productswatches

Most of my products have two attributes, Product Colour and Size.
When the Product colour is selected it changes the swatch, as expected.

However, if the customer then selects the size. It reverts it back to the base image. (It also puts only the base image in the cart, but this is not my main concern.)

I want it so that it only reloads when the customer is selecting Product Colour.

This has lost me sales and caused confusion for the customer.
The link below is an example of the problem I face.

OLD LINK

My simple products do not have individual images. One product could have over 400 variations so it will take far too long to do it that way.

Best Answer

Facing with the same problem, today I wrote the following fix, it works both with attribute selectors and configurable swatches.

$j(document).ready(function() {
    if (typeof ConfigurableMediaImages === 'undefined' || typeof optionsPrice === 'undefined' || typeof Product === 'undefined') return;

    /**
     * Returns true, if there is a label-matching image on config product for the selected option's label
     * @param el
     * @returns {boolean}
     */
    var matchingImageExists = function(el) {
        // copy from product-media.js:150-152
        var select = $j(el);
        var label = select.find('option:selected').attr('data-label');
        var productId = optionsPrice.productId; //get product ID from options price object

        // the inspection, based on product-media.js:94
        return ConfigurableMediaImages.productImages[productId]['option_labels'][label]['configurable_product'][ConfigurableMediaImages.imageType];
    };

    // activation for attribute selectors (selectors as used in product-media.js:175)
    $j('.product-options .super-attribute-select')
        .off('change', ConfigurableMediaImages.updateImage(this))
        .on('change', function() { if (matchingImageExists(this)) { ConfigurableMediaImages.updateImage(this); } });

    // activation for swatches (overriding Product.ConfigurableSwatches.prototype.updateSelect method in swatches-product.js:722)
    Product.ConfigurableSwatches.prototype.updateSelect = function(attr) {
        // fire select change event
        // this will trigger the validation of the select
        // only fire if this attribute has had a selected option at one time
        if (attr._e.selectedOption !== false && attr._e.optionSelect) {
            this._F.nativeSelectChange = false;
            if (matchingImageExists(attr._e.optionSelect)) ConfigurableMediaImages.updateImage(attr._e.optionSelect);
            this.productConfig.handleSelectChange(attr._e.optionSelect);
            this._F.nativeSelectChange = true;
        };
    }
});

You can include it in a separate JS (update: for this, check dawhoo's answer below), so don't need to modify any of the core files.

matchingImageExists() checks, whether there's an image set in the configurable product with the selected option.

In the last two blocks we are overriding the core attribute selector event handler and the Product.ConfigurableSwatches.prototype.updateSelect method for placing the matchingImageExists() control, so we let Magento change the product images only in that case if a label-matching image exists on config product for the selected option's label.

Hope it'll help you. Please notify in case of bugs as I'll use this fix in my shop as well. :-)