# 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:
- Change our controller to render products found by EAN instead of id
- Add a variable called
@variants
that contains price, productId and color of each variant for a given EAN - Display a drop-down with colors to the user, so they can select which color variant to view
- 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).setSDKPrefix('SDK_PREFIX'); // replace SDK_PREFIX with the correct value
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:
- get the drop down element
productVariantsSelect
value - split the value, which is the combination of
productId
andshelfPrice
intoparts
- set
productId
andshelfPrice
from the splitparts
variable - send an event to QL using the SDK