Difference between revisions of "Adding multiple drop down options to product pages"

From Spiffy Stores Knowledge Base

(Created page with 'A demonstration of this method can be found at http://fresh.spiffystores.com/products/apples')
 
Line 1: Line 1:
A demonstration of this method can be found at http://fresh.spiffystores.com/products/apples
+
This tutorial details how to update an existing theme to use Spiffy Stores' new multiple option javascript helper. This javascript helper will build multiple select drop-down boxes for a given product, so that users can easily select a product variant by selecting different values for each product option. A callback mechanism allows designers to provide a callback action to enable/disable their 'add to cart' button and update and price field, etc.
 +
 
 +
While designers can create their own selector methods if they like, using the built-in javascript helper is an easy way to implement multiple select boxes as a way to select product variants and custom options.
 +
 
 +
==Quick Overview of Steps==
 +
1. Add the new "option_dropdowns.js" javascript helper to your theme.liquid file
 +
 
 +
2. Update your product.liquid template to use <select> tag and use unique ids
 +
 
 +
3. Define a callback
 +
 
 +
4. Instantiate javascript with valid parameters
 +
 
 +
===1. Update your theme.liquid file to include the OptionDropdowns javascript===
 +
 
 +
To use the Option Dropdowns javascript, your theme must include the following code in the header of the theme.liquid file.
 +
 
 +
Insert the following into the head section
 +
 
 +
{{ 'option_dropdowns.js' | global_asset_url | script_tag }}
 +
{{ 'mootools' | global_asset_url  | script_tag }}
 +
 
 +
 
 +
for example
 +
 
 +
<pre>
 +
<head>
 +
<title>{{ shop.name }} — {{ page_title }}</title>
 +
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 +
  {{ header.author }}
 +
  {{ header.copyright }}
 +
  {{ header.description }}
 +
  {{ header.keywords }}
 +
  {{ 'stylesheet.css' | asset_url | stylesheet_tag }}
 +
 
 +
  {{ 'mootools.js'        | global_asset_url  | script_tag }}
 +
  {{ 'option_dropdowns.js' | global_asset_url | script_tag }}
 +
 
 +
  {{ content_for_header }}
 +
 
 +
</head>
 +
</pre>
 +
 
 +
 
 +
===2. Update your Product.liquid template===
 +
 
 +
Inside your product.liquid file, ensure you have a <form> element that posts to the "/cart/add" action, and that contains a <select> element that contains all the variants for your given product.
 +
 
 +
For example:
 +
<pre>
 +
<form action="/cart/add" method="post">
 +
  <select id="variant-select" name="id">
 +
    {% for variant in product.variants %}
 +
      {% if variant.available %}
 +
        <option value="{{variant.id}}">{{ variant.title }} for {{ variant.price | money_with_currency }}{% if variant.price < variant.compare_at_price %} usually {{ variant.compare_at_price | money_with_currency }}{% endif %}</option>
 +
      {% else %}
 +
<option value="{{variant.id}}" disabled="disabled">{{ variant.title }} - sold out!</option>
 +
      {% endif %}
 +
    {% endfor %}
 +
  </select>
 +
 
 +
  <input name="cart-add" type="submit" class="button" id="cart-add" value="Buy Now!">
 +
  <span id="price-field"></span>
 +
</form>
 +
</pre>
 +
 
 +
 
 +
You need to ensure the following elements are in place in your <form> to use Spiffy Stores' javascript helper:
 +
• use a <select> element as the selection method for your variants
 +
• the <select> element requires a unique id. ie: <select id='variant-select' name='id'>
 +
• there should be a div element with an id of "price-field" for messages when selecting different variants. This is used for updating the price of the product, or setting a 'unavailable' or 'sold out' message
 +
• the add to cart button should have an id of "cart-add". This is to allow the callback to enable/disable the button.
 +
 
 +
There are two components to the required javascript script:
 +
• Define a callback (which is called whenever a user changes one of the newly created <select> elements
 +
• Instantiate the javascript OptionSelectors model
 +
 
 +
 
 +
===3. Define a callback===
 +
A callback is called whenever a user changes one of the new multiple <select> drop-down boxes. You can define a callback to perform whatever actions you need (for example, update the price, enable/disable the add to cart button if the particular option is not valid, etc.)
 +
 
 +
The format of the callback is:
 +
<pre>
 +
var selectCallback = function(variant, selector) {
 +
  <your code goes here>
 +
}
 +
</pre>
 +
 
 +
Where:
 +
  variant : object of the selected variant (if exists). It will have the following attributes:
 +
    { id             : id of the product variant,
 +
      title           : concatenation of option values with ' / '. ie: Large / Blue / Cotton
 +
      price           : price in cents
 +
      compare_at_price: compare_at_price in cents (or null)
 +
      weight         : weight in grams (or null)
 +
      available       : true / false
 +
      option1         : value of option1
 +
      option2         : value of option2 (or null if not used)
 +
      option3         : value of option3 (or null if not used)
 +
      sku             : sku (or null)
 +
    }
 +
  selector : object of the calling OptionSelector.
 +
 
 +
This callback will be called when any of the new <select> elements is changed by a user. Your callback should handle the following cases:
 +
• When variant passed in is null (no valid variant with the selected options was found)
 +
• When variant passed in is not available (there is a variant with the selected options, but available = false)
 +
• when variant passed in is available
 +
 
 +

Here's a sample callback function for mootools:
 +
<pre>
 +
<script type="text/javascript">
 +
<!--
 +
  // mootools callback for multi variants dropdown selector
 +
  var selectCallback = function(variant, selector, price, compare_at_price) {
 +
    if (variant && variant.available == true) {
 +
      // selected a valid variant
 +
      $('cart-add').removeClass('disabled');    // remove unavailable class from add-to-cart button
 +
      $('cart-add').disabled = false; // reenable add-to-cart button
 +
      if (variant.price < variant.compare_at_price) {
 +
$('price-field').innerHTML = Spiffy.formatMoney(price, "{{shop.money_with_currency_format}}") + '<br/><small>Usually <span class="compare-at-price">' + Spiffy.formatMoney(compare_at_price, "{{shop.money_with_currency_format}}</span></small>"); // update price field
 +
      } else {
 +
$('price-field').innerHTML = Spiffy.formatMoney(price, "{{shop.money_with_currency_format}}"); // update price field
 +
      }
 +
    } else {
 +
      // variant doesn't exist
 +
      $('cart-add').addClass('disabled');      // set add-to-cart button to unavailable class
 +
      $('cart-add').disabled = true;       // disable add-to-cart button
 +
      $('price-field').innerHTML = (variant) ? "Sold Out" : "Unavailable"; // update price-field message
 +
    }
 +
  };
 +
-->
 +
</script>
 +
</pre>
 +
 
 +
 
 +
===4. Instantiate Spiffy.OptionDropdowns javascript===
 +
To use Spiffy Stores' javascript helper, you must instantiate Spiffy.OptionDropdowns with the id of the <select>, a javascript representation of the product, and a callback. This will hide the existing <select> element, build new <select> elements for each product option, and bind the callback to each selector.
 +
<pre>
 +
<script type="text/javascript">
 +
<!--
 +
  // initialize multi selector for product
 +
  window.addEvent('domready', function() {
 +
    new Spiffy.OptionDropdowns("variant-select", { product: {{ product | json }}, onVariantSelected: selectCallback });
 +
  });
 +
-->
 +
</script>
 +
</pre>
 +
 
 +

Format of javascript is:
 +
    new Spiffy.OptionDropdowns(<domid of select>, { product: <product>, onVariantSelected: <callback>});
 +
 
 +
Where:
 +
  <domid of select> : id of the existing <select> element for the product. Must be a <select> tag.
 +
  <product> : javascript object that represents the product. Spiffy stores has liquid functionality to do this automatically.
 +
              Pass in the following liquid tag {{ product | json }}
 +
 
 +
  <callback> : the callback function that will be called whenever one of the new <select> elements is changed
 +
 
 +
 +
 
 +
 
 +
Here's a complete MooTools script that calls the Spiffy javascript helper to enabled multiple options for a product:
 +
<pre>
 +
<script type="text/javascript">
 +
<!--
 +
  // mootools callback for multi variants dropdown selector
 +
  var selectCallback = function(variant, selector, price, compare_at_price) {
 +
    if (variant && variant.available == true) {
 +
      // selected a valid variant
 +
      $('cart-add').removeClass('disabled');    // remove unavailable class from add-to-cart button
 +
      $('cart-add').disabled = false; // reenable add-to-cart button
 +
      if (variant.price < variant.compare_at_price) {
 +
$('price-field').innerHTML = Spiffy.formatMoney(price, "{{shop.money_with_currency_format}}") + '<br/><small>Usually <span class="compare-at-price">' + Spiffy.formatMoney(compare_at_price, "{{shop.money_with_currency_format}}</span></small>"); // update price field
 +
      } else {
 +
$('price-field').innerHTML = Spiffy.formatMoney(price, "{{shop.money_with_currency_format}}"); // update price field
 +
      }
 +
    } else {
 +
      // variant doesn't exist
 +
      $('cart-add').addClass('disabled');      // set add-to-cart button to unavailable class
 +
      $('cart-add').disabled = true;       // disable add-to-cart button
 +
      $('price-field').innerHTML = (variant) ? "Sold Out" : "Unavailable"; // update price-field message
 +
    }
 +
  };
 +
 
 +
  // initialize multi selector for product
 +
  window.addEvent('domready', function() {
 +
    new Spiffy.OptionDropdowns("variant-select", { product: {{ product | json }}, onVariantSelected: selectCallback });
 +
  });
 +
-->
 +
</script>
 +
</pre>
 +
 
 +
A full example using MooTools can be found here (it's a fake store"):http://fresh.spiffystores.com/products/apples

Revision as of 11:22, 31 March 2010

This tutorial details how to update an existing theme to use Spiffy Stores' new multiple option javascript helper. This javascript helper will build multiple select drop-down boxes for a given product, so that users can easily select a product variant by selecting different values for each product option. A callback mechanism allows designers to provide a callback action to enable/disable their 'add to cart' button and update and price field, etc.

While designers can create their own selector methods if they like, using the built-in javascript helper is an easy way to implement multiple select boxes as a way to select product variants and custom options.

Quick Overview of Steps

1. Add the new "option_dropdowns.js" javascript helper to your theme.liquid file

2. Update your product.liquid template to use <select> tag and use unique ids

3. Define a callback

4. Instantiate javascript with valid parameters

1. Update your theme.liquid file to include the OptionDropdowns javascript

To use the Option Dropdowns javascript, your theme must include the following code in the header of the theme.liquid file.

Insert the following into the head section

Template:'option dropdowns.js' Template:'mootools'


for example

<head>
<title>{{ shop.name }} — {{ page_title }}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  {{ header.author }}
  {{ header.copyright }}
  {{ header.description }}
  {{ header.keywords }}
  {{ 'stylesheet.css' | asset_url | stylesheet_tag }}

  {{ 'mootools.js'        | global_asset_url  | script_tag }}
  {{ 'option_dropdowns.js' | global_asset_url | script_tag }}

  {{ content_for_header }}

</head>


2. Update your Product.liquid template

Inside your product.liquid file, ensure you have a <form> element that posts to the "/cart/add" action, and that contains a <select> element that contains all the variants for your given product.

For example:

<form action="/cart/add" method="post">
  <select id="variant-select" name="id">
    {% for variant in product.variants %}
      {% if variant.available %}
        <option value="{{variant.id}}">{{ variant.title }} for {{ variant.price | money_with_currency }}{% if variant.price < variant.compare_at_price %} usually {{ variant.compare_at_price | money_with_currency }}{% endif %}</option>
      {% else %}
	<option value="{{variant.id}}" disabled="disabled">{{ variant.title }} - sold out!</option>
      {% endif %}
    {% endfor %}
  </select>

  <input name="cart-add" type="submit" class="button" id="cart-add" value="Buy Now!">
  <span id="price-field"></span>
</form>


You need to ensure the following elements are in place in your <form> to use Spiffy Stores' javascript helper: • use a <select> element as the selection method for your variants • the <select> element requires a unique id. ie: <select id='variant-select' name='id'> • there should be a div element with an id of "price-field" for messages when selecting different variants. This is used for updating the price of the product, or setting a 'unavailable' or 'sold out' message • the add to cart button should have an id of "cart-add". This is to allow the callback to enable/disable the button.

There are two components to the required javascript script: • Define a callback (which is called whenever a user changes one of the newly created <select> elements • Instantiate the javascript OptionSelectors model


3. Define a callback

A callback is called whenever a user changes one of the new multiple <select> drop-down boxes. You can define a callback to perform whatever actions you need (for example, update the price, enable/disable the add to cart button if the particular option is not valid, etc.)

The format of the callback is:

var selectCallback = function(variant, selector) {
  <your code goes here>
}

Where:

 variant : object of the selected variant (if exists). It will have the following attributes:
   { id              : id of the product variant,
     title           : concatenation of option values with ' / '. ie: Large / Blue / Cotton
     price           : price in cents
     compare_at_price: compare_at_price in cents (or null)
     weight          : weight in grams (or null)
     available       : true / false
     option1         : value of option1 
     option2         : value of option2 (or null if not used)
     option3         : value of option3 (or null if not used)
     sku             : sku (or null)
   } 
 selector : object of the calling OptionSelector. 
 

This callback will be called when any of the new <select> elements is changed by a user. Your callback should handle the following cases: • When variant passed in is null (no valid variant with the selected options was found) • When variant passed in is not available (there is a variant with the selected options, but available = false) • when variant passed in is available


Here's a sample callback function for mootools:

<script type="text/javascript">
<!--
  // mootools callback for multi variants dropdown selector
  var selectCallback = function(variant, selector, price, compare_at_price) {
    if (variant && variant.available == true) {
      // selected a valid variant
      $('cart-add').removeClass('disabled');    // remove unavailable class from add-to-cart button
      $('cart-add').disabled = false;		// reenable add-to-cart button
      if (variant.price < variant.compare_at_price) {
	$('price-field').innerHTML = Spiffy.formatMoney(price, "{{shop.money_with_currency_format}}") + '<br/><small>Usually <span class="compare-at-price">' + Spiffy.formatMoney(compare_at_price, "{{shop.money_with_currency_format}}</span></small>"); // update price field
      } else {
	$('price-field').innerHTML = Spiffy.formatMoney(price, "{{shop.money_with_currency_format}}"); // update price field
      }
    } else {
      // variant doesn't exist
      $('cart-add').addClass('disabled');      // set add-to-cart button to unavailable class
      $('cart-add').disabled = true;	       // disable add-to-cart button
      $('price-field').innerHTML = (variant) ? "Sold Out" : "Unavailable"; // update price-field message
    }
  };
-->
</script>


4. Instantiate Spiffy.OptionDropdowns javascript

To use Spiffy Stores' javascript helper, you must instantiate Spiffy.OptionDropdowns with the id of the <select>, a javascript representation of the product, and a callback. This will hide the existing <select> element, build new <select> elements for each product option, and bind the callback to each selector.

<script type="text/javascript">
<!--
  // initialize multi selector for product
  window.addEvent('domready', function() {
    new Spiffy.OptionDropdowns("variant-select", { product: {{ product | json }}, onVariantSelected: selectCallback });
  });
-->
</script>


Format of javascript is:

   new Spiffy.OptionDropdowns(<domid of select>, { product: <product>, onVariantSelected: <callback>}); 

Where:

 <domid of select> : id of the existing <select> element for the product. Must be a <select> tag.
 <product> : javascript object that represents the product. Spiffy stores has liquid functionality to do this automatically.
             Pass in the following liquid tag Template:Product
 <callback> : the callback function that will be called whenever one of the new <select> elements is changed



Here's a complete MooTools script that calls the Spiffy javascript helper to enabled multiple options for a product:

<script type="text/javascript">
<!--
  // mootools callback for multi variants dropdown selector
  var selectCallback = function(variant, selector, price, compare_at_price) {
    if (variant && variant.available == true) {
      // selected a valid variant
      $('cart-add').removeClass('disabled');    // remove unavailable class from add-to-cart button
      $('cart-add').disabled = false;		// reenable add-to-cart button
      if (variant.price < variant.compare_at_price) {
	$('price-field').innerHTML = Spiffy.formatMoney(price, "{{shop.money_with_currency_format}}") + '<br/><small>Usually <span class="compare-at-price">' + Spiffy.formatMoney(compare_at_price, "{{shop.money_with_currency_format}}</span></small>"); // update price field
      } else {
	$('price-field').innerHTML = Spiffy.formatMoney(price, "{{shop.money_with_currency_format}}"); // update price field
      }
    } else {
      // variant doesn't exist
      $('cart-add').addClass('disabled');      // set add-to-cart button to unavailable class
      $('cart-add').disabled = true;	       // disable add-to-cart button
      $('price-field').innerHTML = (variant) ? "Sold Out" : "Unavailable"; // update price-field message
    }
  };

  // initialize multi selector for product
  window.addEvent('domready', function() {
    new Spiffy.OptionDropdowns("variant-select", { product: {{ product | json }}, onVariantSelected: selectCallback });
  });
-->
</script>

A full example using MooTools can be found here (it's a fake store"):http://fresh.spiffystores.com/products/apples