Magento – Setting Configurable product select options

configurable-productjavascript

I have the following requirement. Shop sells varnish with litres/sheen product variations. However, not every product will have same attributes – a 5ltr can may have two sheen options, a 10ltr can may only have one sheen.

  1. When a user selects a gallery image of a 5lt can it should

    a. change the main product image to 5 ltr
    b. change the litres selection option to '5'

  2. When the user uses the select to change the litres, it should update the main product image

I have the main functionality sorted for 1 & 2, but I can't control the 'sheen' select – if I enable it the product sheen options are not firing in sync with the size changes. Hopefully you could see in the attachment what I mean (if I was allowed to post one!) – the second select is stuck on 'Select an Option', whereas it should be populated with options. Nor does changing the gallery images update the sheen select.

The code I have is as follows:

<div class="product-img-box">
   <p class="product-image product-image-zoom"><img id="image" src="" alt="Bona parent" title="Bona parent" /></p>
</div>

<div class="more-views none-slider-more-views">
    <ul id="img-list"> 
      <li> <img class="changer" data-main-image-src=""  src="" alt="5" title="5"  /></li>
      <li><img class="changer" data-main-image-src=""  src="" alt="0.75" title="0.75"  /></li>
    </ul> 
</div>

The Javascript is being deployed in template/product/view/media.phtml & uses JQuery to retrieve the clicked image & substitute, using the image alt as a map between the image & the Litre options, is as follows:

jQuery(document).ready(function()
{
    jQuery('.changer').click(function()
    {    
        jQuery("#image").attr("src", jQuery(this).attr("data-main-image-src"));
        var divid = jQuery(this).attr("alt");
        changeSelectState("#attribute990");
        jQuery("#attribute989 option").each(function () {
        if (jQuery(this).html() == divid) {
            jQuery(this).attr("selected", "selected");        
            return;
        }
       });  

    });
    jQuery("#attribute989").change(function(){

         jQuery("#attribute989 option").each(function () {
         changeImage(jQuery('#attribute989 :selected').text());
         changeState();
         return false;
       });  
    });
    function changeImage(obj){
        jQuery('.changer').each( function(idx,img) {
         var pAlt = img.alt;
         if(obj == pAlt)
            jQuery("#image").attr("src", jQuery(this).attr("data-main-image-src"));
        });
    }
    function changeSelectState(obj){
         changeState();
         //jQuery(obj).attr('disabled', false);

    }


});
  function changeState(){
    // simulate firing a DOM event
    if (typeof fireEvent !== 'function') {
        document.fireEvent = document.createEventObject ? // IE
        function(element, event) {
        var evt = document.createEventObject();
        return element.fireEvent('on' + event, evt);
    } : // FX
        function(element, event) {
            var evt = document.createEvent('HTMLEvents');
            evt.initEvent(event, true, true); // event type, bubbling, cancelable
            return !element.dispatchEvent(evt);
        };
    }
    // preselect the 1st option of the 1st-maxPreselectedAttributeOptionCount
    window.maxPreselectedAttributeOptionCount = 2;
    Event.observe(window, 'load', function() {
        if (!spConfig) {
        return;
    }
    for (var i = 0; i < Math.min(maxPreselectedAttributeOptionCount, spConfig.settings.length); ++i) {
        var attr = spConfig.settings[i];
            attr.selectedIndex = 1;
            Event.observe(attr, 'change', Prototype.emptyFunction);
            fireEvent(attr, 'change');
            spConfig.reloadPrice();
        }
    });
  }

This issue comes when simulating the user selecting an option from the Litres dropdown. I'm sure I'm doing something very wrong here! Any suggestions most welcome. Thanks

Best Answer

Still unsolved?

I use this on a site to select the first configurable option, which triggers the 'change' event, which populates the second select for me.

Hopefully you can use/adapt it to your usage case.

document.observe("dom:loaded", function() {
  // Once dom has loaded, grab the first select option (Business rules say there will always only be 1 - this is the product colour)
  // ...select this option and set as true. Triggers 'change' event for size option select to work/enable/populate.

  var options = $$('.super-attribute-select');
  var len = options.length;
  var qty = $$('#qty');
  for (var i = 0; i < len; i++) {
    if(options[0][1]){
      options[0][1].selected = true;

      triggerEvent($$('.super-attribute-select')[0],'change');
    }
    // Always selects 1
    if(qty[0]){
      qty[0][1].selected = true;
    }
  }

});


// Custom prototype function to fire an event
// http://stackoverflow.com/questions/460644/trigger-an-event-with-prototype
function triggerEvent(element, eventName) {
  // safari, webkit, gecko
  if (document.createEvent)
  {
    var evt = document.createEvent('HTMLEvents');
    evt.initEvent(eventName, true, true);

    return element.dispatchEvent(evt);
  }

  // Internet Explorer
  if (element.fireEvent) {
    return element.fireEvent('on' + eventName);
  }
}
Related Topic