Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This page will show how to customize item variations.  If you need item options instead, see this article: Modifying Item Options in a StoreFront

...

Converting an Item from using Options to Variations (introduction to variations)Options and

Item Variations (instructions for creating/configuring variations) 

Tip

Adding ?uc-debug to then end of an item page containing variations will generate debugging output in the browser console.

Example: https://demo.ultracartstore.com/shop/TSHIRT.html?uc-debug

HTML Components

The variations are found in two places. 

...

Code Block
<script type="text/javascript" src="/catalog_5.1.js"></script>
 
<!-- there will be a lot of other html components in between the catalog_5.1.js reference and the actual item variation code ... just FYI -->
 
 
#if($item && $item.hasVariations() && "$cart" != "")
  <script type='text/javascript'>
  //this is dependent on jquery and catalog_5.1.js
  console.log('initializing catalog variations');
  #set($currencyCode = $cart.getCurrency().getSymbol())
  // this can be named anything or assigned anywhere.  Or not even assigned to a variable.
  // I just chose window.itemVariations so it would be easy to debug
  var itemVariationsOptions = {
    merchantItemId: "$item.getMerchantItemID()",
    variationMatrix: ${item.getVariationMatrix().getJavascriptItemVariationMatrix2(false, 80, 80)},
    multimedia: ${item.getMultimediaAsJson()},
    currencyCode: "$currencyCode",
    inventory: 'show-quantity',
    validation: function(missingFields){ 
      window.alert("Look jackball, select values for the following fields before continuing: " + missingFields.join(", ")); 
      return false; 
    },
    customOutOfStock: {'X-Large': 'out of season'},
    formatters: {
      'Color': function(formatData){
        var priceIsRanged = (formatData.cost != formatData.maxCost);
        var costStr = " " + formatData.costFormatted;
        if(priceIsRanged){
          costStr = " [" + formatData.costFormatted + " - " + formatData.maxCostFormatted + "]";
        }
         if(formatData.inventory > 0){
           return formatData.optionText + costStr;
         } else if(formatData.status == 'backorder') {
           return formatData.optionText + costStr + " (backorder" + (formatData.eta ? (" until " + formatData.eta + ")") : ")");
         } else if(formatData.status == 'made to order') {
           return formatData.optionText + costStr + " (made to order" + (formatData.leadTime ? (" in " + formatData.leadTime + " days)") : ")");
         } else if(formatData.status == 'preorder') {
           return formatData.optionText + costStr + " (preorder" + (formatData.eta ? (", ships " + formatData.eta + ")") : ")");
         } else {
           return formatData.optionText + costStr + " (" + formatData.status + ")";
        } //end-if inventory/status selections
      }, //end of 'Color' formatter
      'Size': function(formatData){
        var priceIsRanged = (formatData.cost != formatData.maxCost);
        var costStr = " " + formatData.costFormatted;
        if(priceIsRanged){
          costStr = " [" + formatData.costFormatted + " - " + formatData.maxCostFormatted + "]";
        }
         if(formatData.inventory > 0){
           return formatData.optionText + costStr;
         } else if(formatData.status == 'backorder') {
           return formatData.optionText + costStr + " (backorder" + (formatData.eta ? (" until " + formatData.eta + ")") : ")");
         } else if(formatData.status == 'made to order') {
           return formatData.optionText + costStr + " (made to order" + (formatData.leadTime ? (" in " + formatData.leadTime + " days)") : ")");
         } else if(formatData.status == 'preorder') {
           return formatData.optionText + costStr + " (preorder" + (formatData.eta ? (", ships " + formatData.eta + ")") : ")");
         } else {
           return formatData.optionText + costStr + " (" + formatData.status + ")";
        } //end-if inventory/status selections
      } //end of 'Size' formatter            
    } //end of formatters
  }; //end of item variation options hash.
  window.itemVariations = new ultracart.ItemVariations(jQuery, itemVariationsOptions);
    window.itemVariations.on('options-changed', function(event, new_options){ console.log('options-change event triggered', new_options); });
    window.itemVariations.on('cost-changed', function(event, cost_data){ console.log('cost-change event triggered', cost_data); });
    window.itemVariations.on('item-selected', function(event, item_data){ console.log('item-selected event triggered', item_data); });
    window.itemVariations.on('item-unselected', function(event){ console.log('item-unselected event triggered (no extra data provided)'); });                      
    window.itemVariations.on('multimedia-selected', function(event, multimediaOid){ 
      console.log('multimedia-selected event triggered, multimediaOid:', multimediaOid); 
      var multimediaImageIndex = parseInt(jQuery("li.product-image[data-multimedia-oid='" + multimediaOid + "']").attr('index'));
      if(!isNaN(multimediaImageIndex)){
         jQuery('#main-item-image-viewer-holder').slickGoTo(multimediaImageIndex);
      }                           
    });
    window.itemVariations.on('multimedia-unselected', function(event){             
      console.log('multimedia-unselected event triggered (no extra data provided)');            
      // revert back to the original image, which is always at index 0.
      jQuery('#main-item-image-viewer-holder').slickGoTo(0);
    });          
  </script>
#elseif($item && $item.hasOptions() && "$cart" != "")

   ## THIS WILL CONTAIN A LARGE CODE BLOCK FOR ITEM OPTIONS.  IT WAS REMOVED TO AVOID CONFUSION IN THIS DOCUMENTATION.

#end



 Options

inventory : 'show-quantity' | 'hide-out-of-stock'

show-quantity will display the quantity of inventory next to the option

hide-out-of-stock will remove any options that have an inventory less than or equal to 0.  this option will also exclude backorder and preorder items.

For find tune control, use 'show-quantity' and use custom formatters to render your options.

...

This event fires whenever an variation changes options (customer selects a different value).  

data:  

/**
* @typedef {Object} VariationEventOptionsChange
* this event will contain a hash of all options and their currently selected values. any unselected values will have
* a zero length string.
*/

 

Tip

The variations event above has a plural options, while the item options event has a singular option. Please note the difference.

...

This event fires whenever the minimum cost changes.

/**
* @typedef {Object} VariationEventCostChange
* @property {number} cost
* @property {string} costFormatted
* @property {number} originalCost
* @property {string} originalCostFormatted
* @property {number} saleCost
* @property {string} saleCostFormatted
* @property {boolean} hasSale true if these combination of items is on sale.
* @property {boolean} hasSelectedItem true if a single item is selected, else false
* @property {string} itemId will contain the item id of the item if it's selected, else null.
* @property {number} parentCost
* @property {string} parentCostFormatted
* @property {number} parentOriginalCost
* @property {string} parentOriginalCostFormatted
* @property {number} parentSaleCost
* @property {string} parentSaleCostFormatted
* @property {boolean} parentHasSale true if these combination of items is on sale.
* this event contains all relevant price data.
*/

 

item-selected

This event fires whenever enough variations have been selected to narrow down the possible choice of child items to one.  This is very useful for changing the main item image to the child item.

/**
* @typedef {Object} Variation This object would be better termed 'VariationItem', since each record represents a child variation of the top level item
* @property {string} itemId the merchant item id
* @property {number} cost The current cost of the variation item. Example 19.99
* @property {number} originalCost The original cost of this variation. Example: 29.99
* @property {number} [saleCost] The sale cost of this variation. Example: 29.99. Will be absent entirely if item is not on sale
* @property {boolean} hasSale true if this variation is on sale, false otherwise
* @property {number} inventory the inventory of this variation. if inventory is not tracked, this will be 1000
* @property {boolean} inventoryTracked true if inventory is tracked on this item
* @property {boolean} allowBackOrder true if this item allows backOrder
* @property {boolean} preorder true if this item is a preorder item
* @property {string} eta date string of the estimate time of arrival for backOrder or preorder
* @property {boolean} madeToOrder true if this item is made to order
* @property {integer} [leadTime] number of days required to make this item, will be missing if madeToOrder = false
* @property {Object} values an object of option values that match this variation. For example: Object { Size="Large", Color="Black"}
* @property {string} compositeKey a pipe delimited list of values in 'sort' order to allow for easy option value -> variation lookup.
*/

item-unselected

This event fires whenever the variations change and a single item is no longer selected.  For example, if the customers starts over with the first select box again, this will fire.  This is useful for reverting any image or description information back to the main parent item.

...

This event fires whenever a multimedia (image) is applicable to the currently selected variations.  This can occur based on a selection from one of the select boxes (or radio buttons), or when enough selections are made to narrow down to a single child item which has an assigned multimedia image.

/**
* @typedef {Object} Multimedia contains high level information about one of the multimedia objects associated with the parent item
* @property {string} type
* @property {boolean} isDefault
* @property {number} imageWidth
* @property {number} imageHeight
* @property {string} viewUrl
* @property {string} viewSsl
* @property {string} description
* @property {string} code
* @property {string} merchantItemId
* @property {boolean} excludeFromGallery
* @property {string} filename
* @property {number} multimediaOid
*/

multimedia-unselected

This event fires whenever the customer has changed their selections (or cleared them out) to the point where no images can be found to match the current set of variation choices.

...