title: Need help making the WooCommerce swatch plugin work with the cloud zoom js, not a typical NoConflict issue
body: <p>I am using the Blanco theme (Wordpress). This is a WooCommerce theme from theme forest that has Cloud Zoom JQuery built into the single product pages. I am also using the "WooCommerce Variation Swatches and Photos" plugin. This creates visial swatches to replace WooCommerce drop down selector menus for product variations.</p>
  
  <p>The swatch on the page uses js to highlight the one that has been clicked so that is can be highlighted and for when the item is added to the cart.</p>
  
  <p>The gallery images use js to change the attachment src of the main image place for the cloud zoom.</p>
  
  <p>My client wants the main image to also change when clicking on the swatch so that it shows an image that matches the color that was just selected.</p>
  
  <p>I have edited the swatch plugin to offer an option to save an image url for each attribute in the product when editing the swatch settings. When this is set the swatch has the same code added to the tag that the gallery image uses. This successfully loads the chosen image int the main image place like desired. However the swatch does not get selected anymore.</p>
  
  <p>Also the "loading" on the main image does not go away when loaded with the swatch. But it does go away when loaded with the gallery image.</p>
  
  <p>It is hard to explain in words. If you visit this product page:</p>
  
  <p><a href="http://tummytrimmerz.com/shop/cami-with-jog-bra/" rel="nofollow">http://tummytrimmerz.com/shop/cami-with-jog-bra/</a></p>
  
  <p>You will see the size swatches xs, s, m ,l ... are working as they should. And you can see the three color swatches are not working like the size ones but they are loading the main image.</p>
  
  <p>Here is the code I am adding to the a tag inside of the dive that should be effected by the swatch jquery:</p>
  
  <pre><code>&lt;a href="https://tummytrimmerz.com/wp-content/uploads/2013/02/Tummy-Trimmerz-Black-Cami-Pink-Bra-Front-View1-266x400.jpg" class="cloud-zoom-gallery" cloud-zoom-data="useZoom: 'zoom1', smallImage: 'https://tummytrimmerz.com/wp-content/uploads/2013/02/Tummy-Trimmerz-Black-Cami-Pink-Bra-Front-View1-266x400.jpg'" style="width:90px;height:90px;" title="Jet Black / Magenta"&gt;&lt;img src="https://tummytrimmerz.com/wp-content/uploads/2013/03/Black-Pink.jpg" alt="Thumbnail" class="wp-post-image swatch-photopa_color_" width="90" height="90"&gt;&lt;/a&gt;
  </code></pre>
  
  <p>and here is the swatch picker JQuery:</p>
  
  <pre><code>jQuery(document).ready( function($) {
  var calculator = new variation_calculator(product_attributes, product_variations_flat, my_all_set_callback, my_not_all_set_callback);
  calculator.reset_selected();
  calculator.reset_current();
  
  function my_not_all_set_callback() {
  
  // Reset image
  var img = $('div.images img:eq(0)');
  var link = $('div.images a.zoom:eq(0)');
  var o_src = $(img).attr('data-o_src');
  var o_href = $(link).attr('data-o_href');
  
  if ( o_src &amp;&amp; o_href ) {
  $(img).attr('src', o_src);
  $(link).attr('href', o_href);
  }
  
  $('form input[name=variation_id]').val('').change();
  $('.single_variation_wrap').hide();
  $('.single_variation').text('');
  
  
  if( $().uniform &amp;&amp; $.isFunction($.uniform.update) ) {
  $.uniform.update();
  }
  
  }
  
  function my_all_set_callback(selected) {
  var found = null;
  
  for (sa in selected) {
  $('#' + sa).val( selected[sa] );
  }
  
  for(var p = 0; p &lt; product_variations.length; p++) {
  var result = true;
  for (attribute in product_variations[p].attributes) {
  for(selected_attribute in selected) {
  if (selected_attribute == attribute) {
  var v = product_variations[p].attributes[attribute];
  if (v != selected[selected_attribute]) {
      result = false;
  }
  }
  }
  }
  
  if (result){
  found = product_variations[p];
  }
  
  }
  
  
  if (!found) {
  for(var p = 0; p &lt; product_variations.length; p++) {
  var result = true;
  for (attribute in product_variations[p].attributes) {
  for(selected_attribute in selected) {
  if (selected_attribute == attribute) {
      var v = product_variations[p].attributes[attribute];
      var vs = selected[selected_attribute];
      if (v != '' &amp;&amp; v != vs) {
          result = false;
      }
  }
  }
  }
  
  if (result){
  found = product_variations[p];
  }
  }
  }
  
  if (found) {
  show_variation(found);
  }
  }
  
  function show_variation(variation) {
  swap_image(variation);
  
  $('.variations_button').show();
  $('.single_variation').html( variation.price_html + variation.availability_html );
  
  if (variation.sku) {
  $('.product_meta').find('.sku').text( variation.sku );
  } else {
  $('.product_meta').find('.sku').text('');
  }
  
  $('.single_variation_wrap').find('.quantity').show();
  
  if (variation.min_qty) {
  $('.single_variation_wrap').find('input[name=quantity]').attr('data-min', variation.min_qty).val(variation.min_qty);
  } else {
  $('.single_variation_wrap').find('input[name=quantity]').removeAttr('data-min');
  }
  
  if ( variation.max_qty ) {
  $('.single_variation_wrap').find('input[name=quantity]').attr('data-max', variation.max_qty);
  } else {
  $('.single_variation_wrap').find('input[name=quantity]').removeAttr('data-max');
  }
  
  if ( variation.is_sold_individually == 'yes' ) {
  $('.single_variation_wrap').find('input[name=quantity]').val('1');
  $('.single_variation_wrap').find('.quantity').hide();
  }
  
  $('form input[name=variation_id]').val(variation.variation_id).change();
  
  $('.single_variation_wrap').slideDown('200').trigger( 'show_variation', [ variation ] );
  $('form.cart').trigger( 'found_variation', [ variation ] );
  
  }
  
  function swap_image(variation) {
  
  var img = $('div.images img:eq(0)');
  var link = $('div.images a.zoom:eq(0)');
  var o_src = $(img).attr('data-o_src');
  var o_title = $(img).attr('data-o_title');
  
  var o_href = $(link).attr('data-o_href');
  
  
  var variation_image = variation.image_src;
  var variation_link = variation.image_link;
  var variation_title = variation.image_title;    
  
  
  if (!o_src) {
  $(img).attr('data-o_src', $(img).attr('src'));
  }
  
  if (!o_title) {
  $(img).attr('data-o_title', $(img).attr('title') );
  }
  
  if (!o_href) {
  $(link).attr('data-o_href', $(link).attr('href'));
  }
  
  
  if (variation_image &amp;&amp; variation_image.length &gt; 1) {    
  $(img).attr('src', variation_image);
  $(img).attr('title', variation_title);
  $(img).attr('alt', variation_title);
  $(link).attr('href', variation_link);
  $(link).attr('title', variation_title);
  } else {
  $(img).attr('src', o_src);
  $(img).attr('title', o_title);
  $(img).attr('alt', o_title);
  $(link).attr('href', o_href);
  $(link).attr('title', o_title);
  }
  }
  
  
  var $variation_form = $('form.cart');
  
  $('.variations select', $variation_form).unbind();
  $('div.select-option').delegate('a', 'click', function(event) {
  event.preventDefault();
  
  var $the_option = $(this).closest('div.select-option');
  
  if ($the_option.hasClass('disabled')) {
  return false;
  } else if ($the_option.hasClass('selected')) {
  $the_option.removeClass('selected');
  
  var select = $the_option.closest('div.select');
  select.data('value', '');
  $(this).parents('div.select').trigger('change', []);
  
  } else {
  
  var select = $(this).closest('div.select');
  $(select).find('div.select-option').removeClass('selected');
  $the_option.addClass('selected');
  
  select.data('value', $the_option.data('value') );
  $(this).parents('div.select').trigger('change', []);
  }
  
  return false;
  
  });
  
  $('div.select', $variation_form).bind('change', function() {
  
  $variation_form.trigger( 'woocommerce_variation_select_change' );
  
  var $parent = $(this).closest('.variation_form_section');
  $('select', $parent).each( function(index, element) {
  var optval = $(element).val();
  
  optval = optval.replace("'", "&amp;#039;");
  optval = optval.replace('"', "&amp;quot;");
  
  
  calculator.set_selected( $(element).data('attribute-name'), optval );
  });
  
  $('div.select', $parent).each( function(index, element) {
  calculator.set_selected( $(element).data('attribute-name'), $(element).data('value') );
  });
  
  var current_options = calculator.get_current();
  $('select', $parent).each( function(index, element) {                
  var attribute_name = $(element).data('attribute-name');
  var avaiable_options = current_options[attribute_name];
  
  $(element).find('option:gt(0)').each(function(index, option) {
  var optval = $(option).val();
  
  optval = optval.replace("'", "&amp;#039;");
  optval = optval.replace('"', "&amp;quot;");
  
  if (!avaiable_options[ optval ] ) {
  $(option).attr('disabled','disabled');
  } else {
  $(option).removeAttr('disabled');
  }
  });   
  });
  
  $('div.select', $parent).each( function(index, element) {                
  var attribute_name = $(element).data('attribute-name');
  var avaiable_options = current_options[attribute_name];
  
  $(element).find('div.select-option').each(function(index, option) {
  if (!avaiable_options[ $(option).data('value') ] ) {
  $(option).addClass('disabled','disabled');
  } else {
  $(option).removeClass('disabled');
  }
  });   
  });
  
  calculator.trigger_callbacks();
  
  });
  
  $('select', $variation_form).change(function() {
  var $parent = $(this).closest('.variation_form_section');
  $('select', $parent).each( function(index, element) {
  var optval = $(element).val();
  
  optval = optval.replace("'", "&amp;#039;");
  optval = optval.replace('"', "&amp;quot;");
  calculator.set_selected( $(element).data('attribute-name'), optval);
  });
  
  var current_options = calculator.get_current();
  $('select', $parent).each( function(index, element) {                
  var attribute_name = $(element).data('attribute-name');
  var avaiable_options = current_options[attribute_name];
  
  $(element).find('option:gt(0)').each(function(index, option) {
  var optval = $(option).val();
  
  optval = optval.replace("'", "&amp;#039;");
  optval = optval.replace('"', "&amp;quot;");
  
  if (!avaiable_options[ optval ] ) {
  $(option).attr('disabled','disabled');
  } else {
  $(option).removeAttr('disabled');
  }
  });
  
  });
  
  $('div.select', $parent).each( function(index, element) {                
  var attribute_name = $(element).data('attribute-name');
  var avaiable_options = current_options[attribute_name];
  
  $(element).find('div.select-option').each(function(index, option) {
  if (!avaiable_options[ $(option).data('value') ] ) {
  $(option).addClass('disabled','disabled');
  } else {
  $(option).removeClass('disabled');
  }
  });   
  });
  
  calculator.trigger_callbacks();
  
  }); 
  
  
  
  //Fire defaults
  $('div.select-option[data-default=true]').find('a').click();
  $('select', 'form.cart').trigger('change', []);
  
  });
  
  function variation_manager(variations) {
  this.variations = variations; 
  this.find_matching_variation = function(selected) {
  
  for (var v = 0;v&lt;this.variations.length;v++) {
  var variation = this.variations[v];
  var matched = true;
  
  //Find any with an exact match. 
  for( var attribute in variation.attributes ) {
  matched = matched &amp; selected[attribute] != undefined &amp;&amp; selected[attribute] == variation.attributes[attribute];
  }
  
  if (matched) {
  return variation;
  }
  }
  
  //An exact match was not found.   Find any with a wildcard match
  for (var v = 0;v&lt;this.variations.length;v++) {
  var variation = this.variations[v];
  var matched = true;
  
  //Find any with an exact match. 
  for( var attribute in variation.attributes ) {
  matched = matched &amp; selected[attribute] != undefined &amp;&amp; (selected[attribute] == variation.attributes[attribute] || variation.attributes[attribute] == '');
  }
  
  if (matched) {
  return variation;
  }
  }
  
  return false;
  }
  }
  
  function variation_calculator(keys, possibile, all_set_callback, not_all_set_callback) {    
  this.recalc_needed = true;
  
  this.all_set_callback = all_set_callback;
  this.not_all_set_callback = not_all_set_callback;
  
  //The varioius variation key values available as configured in woocommerce. 
  this.variation_keys = keys;
  
  //The actual variations that are configured in woocommerce. 
  this.variations_available = possibile;
  
  //Stores the attribute + values that are currently available
  this.variations_current = {};
  
  //Stores the selected attributes + values
  this.variations_selected = {};
  
  this.reset_current = function( ) {
  for(var key in this.variation_keys) {
  this.variations_current[ key ] = {};
  for( var av = 0; av &lt; this.variation_keys[key].length; av++ ) {
  this.variations_current[ key ][ this.variation_keys[key][av] ] = 0;
  } 
  }
  };
  
  this.update_current = function( ) {
  this.reset_current();
  
  for( var i = 0; i &lt; this.variations_available.length; i++ ) {
  for(var attribute in this.variations_available[ i ]) {
  
  var available_value = this.variations_available[ i ][attribute];
  var selected_value = this.variations_selected[attribute];
  
  if (selected_value &amp;&amp; selected_value == available_value ) {
  this.variations_current[ attribute ][ available_value ] = 1;//this is a currently selected attribute value
  } else {
  
  var result = true;
  //Loop though any other item that is selected, checking to see if any DO NOT match.
  for(var other_selected_attribute in this.variations_selected) {
  
  if (other_selected_attribute == attribute) {
      //We are looking to see if any attribute that is selected will cause this to fail. 
      continue;
  }
  
  var other_selected_attribute_value = this.variations_selected[other_selected_attribute];
  var other_available_attribute_value = this.variations_available[i][other_selected_attribute];
  if ( other_selected_attribute_value ) {
      if ( other_available_attribute_value ) {
          if (other_selected_attribute_value != other_available_attribute_value) {
              result = false;
          }
      }
  }
  }
  
  if (result) {
  if (available_value) {
      this.variations_current[ attribute ][ available_value ] = 1;
  } else {
      for (var av in this.variations_current[ attribute ]) {
          this.variations_current[ attribute ][ av ] = 1;
      }
  }
  }
  
  }
  }
  }
  
  this.recalc_needed = false;
  };
  
  this.get_current = function() {
  if (this.recalc_needed) {
  this.update_current();
  }
  
  return this.variations_current;
  };
  
  this.get_value_is_current = function( key, value ) {
  if (this.recalc_needed) {
  this.update_current();
  }
  
  return this.variations_current[ key ][ value ] === true;
  };
  
  this.reset_selected = function() {
  this.recalc_needed = true;
  this.variations_selected = [];
  }
  
  this.set_selected = function(key, value) {
  this.recalc_needed = true;
  this.variations_selected[ key ] = value; 
  };
  
  this.get_selected = function() {
  return this.variations_selected;
  }
  
  this.trigger_callbacks = function(){ 
  var all_set = true;
  
  for (var key in this.variation_keys) {
  all_set = all_set &amp; this.variations_selected[key] != undefined &amp;&amp; this.variations_selected[key] != '';
  }
  
  if (all_set) {
  this.all_set_callback( this.variations_selected );
  } else {
  this.not_all_set_callback();
  }
  }
  };
  </code></pre>
  
  <p>I have spent 6 days on trying to get this to work correct and I am new to JS so any help would be greatly appreciated.</p>
  
  <p>UPDATE: sorry you can not view sit with out a login, here:</p>
  
  <p>URL <a href="https://tummytrimmerz.com/wp-login.php" rel="nofollow">https://tummytrimmerz.com/wp-login.php</a>
  user: stack
  pw: stack</p>
  
  <p>Leon</p>