Multiple Product-Variants

Continuing with our consumer electronics store example, we would like to handle several variants of some of our products separately.

Let's assume we sell iPhones, and would like to receive separate analytics from QL for each color variant - Black or White.

However, our product page shows information about each iPhone model, regardless of its color (in other words, we have a single product page for both black and white iPhones).

To accommodate this behaviour, we're going to make the following changes:

  1. Change our controller to render products found by EAN instead of id
  2. Add a variable called @variants that contains price, productId and color of each variant for a given EAN
  3. Display a drop-down with colors to the user, so they can select which color variant to view
  4. Attach Javascript change event to the drop-down and send an event to QL using the SDK

Let's modify our product page controller and view to include these changes.

app/controllers/products_controller.rb

class ProductsController < ApplicationController
  
  # GET /products/:ean - renders product page
  def show
    products = Product.where(ean: params[:ean]) # find products in DB by ean
    # grab the first product and set to @product variable, to display in view
    @product = products.first
    # set view variables for SDK
    @variants = []
    products.each do |product|
      @variants.push({
        color: product.color,
        # productId is a combination of ean and color
        productId: "#{product.ean}-#{product.color}",
        shelfPrice: product.shelfPrice
      })
    end
    @clientKey = 'myvirtualstore'    
    render('show') # explicit call to render the product page view
  end
  
end

With our controller code in place, we can now modify our product page view.

Note the rendering of <select> with an <option> tag for each color variant - The value of each <option> tag is the combination of the productId and the shelfPrice into a single string: productId|shelfPrice.

This will make it easy to grab both values when the user makes a selection and send them to QL using the SDK.

app/views/products/show.erb

<div>
  <h1><%= @product.name %></h1>
  <select id="product-variants">
    <!-- render a drop down to select different colors -->
    <%- @variants.each do |product| %>
    <option value="<%= product[:productId] + '|' + product[:shelfPrice] %>">
      <%= product[:color] %>
    </option>
    <%- end %>
  </select>
  <!-- rest of HTML is redacted for simplicity --> 
</div>

<!-- ADD QL's SDK at the bottom of the page template -->
<script>
  window.QLAsync = function(QL){
    var clientKey  = '<%= @clientKey %>',
        permalink = '<%= product_url(@product.id) %>', // product_url is a function provided by Rails to get the product's permalink
        productVariantsSelect = document.querySelector('#product-variants');
    
    QL.init(clientKey);
    
    productVariantsSelect.addEventListener('change', function(ev) {
      var value = productVariantsSelect.value,
          parts = value.split('|'),
          productId = parts[0],
          shelfPrice = parts[1];
      QL.sendProductEvent(productId, {
        price: parseFloat(shelfPrice, 10),
        permalink: permalink
      }); 
    });
  }
</script>
<script src="//d3jdlwnuo8nsnr.cloudfront.net/sdk/v3.0/ql.js"></script>

We then changed our SDK Javascript code as follows:

Change 1

find the variants drop-down menu DOM element

productVariantsSelect = document.querySelector('#product-variants')
Change 2

Add a change event handler to the variants drop-down menu DOM element productVariantsSelect which fires whenever a user selects a color from the drop-down menu.

productVariantsSelect.addEventListener('change', function(ev) {
   var value = productVariantsSelect.value,
       parts = value.split('|'),
       productId = parts[0],
       shelfPrice = parts[1]
   QL.sendProductEvent(productId, {
     price: parseFloat(shelfPrice, 10),
     permalink: permalink
   });
});

Every time the user selects a different color, the event handler function runs and does the following:

  1. get the drop down element productVariantsSelect value
  2. split the value, which is the combination of productId and shelfPrice into parts
  3. set productId and shelfPrice from the split parts variable
  4. send an event to QL using the SDK