---
title: Displaying product variants
related:
  - https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/products/working-with-product-variants.md
  - https://docs.kentico.com/13/e-commerce-features/developing-on-line-stores/displaying-product-details.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

If your [on-line store](https://docs.kentico.com/13/e-commerce-features.md) contains [products](https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/products.md) with specified [product variants](https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/products/working-with-product-variants.md), individual product [details pages](https://docs.kentico.com/13/e-commerce-features/developing-on-line-stores/displaying-product-details.md) should contain some form of product variant selection.

This page demonstrates two approaches to displaying product variants:

- [Listing a product's available variants in a drop-down selector](#displaying-product-variants-in-a-drop-down-selector)
- [Implementing a product option selector](#adding-a-product-option-selector-to-product-details-pages)

## Displaying product variants in a drop-down selector

> **Info:** The following section extends the scenario described in [Displaying product details](https://docs.kentico.com/13/e-commerce-features/developing-on-line-stores/displaying-product-details.md), and therefore presumes you already have working product details pages for standard products.

To display a selector with available product variants on a product's details page:

1. Open your MVC application in Visual Studio.
2. To your product model, add the following properties and constructor. These properties extend the model with information about available [product variants](https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/products/working-with-product-variants.md).

   ```csharp

           public bool HasProductVariants { get; set; }
           public SelectList VariantSelectList { get; set; }
           public int SelectedVariantID { get; set; }

           /// <summary>
           /// Creates a new product model with variants.
           /// </summary>
           /// <param name="productPage">Product's page.</param>
           /// <param name="priceDetail">Price of the selected variant.</param>
           /// <param name="variants">Collection of selectable variants.</param>
           /// <param name="selectedVariantID">ID of the selected variant.</param>
           public ProductViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail, List<ProductVariant> variants, int selectedVariantID)
               : this(productPage, priceDetail)
           {
               // Fills the selectable variants
               HasProductVariants = variants.Any();

               // Continues if the product has any variants
               if (HasProductVariants)
               {
                   // Selects a default variant
                   var selectedVariant = variants.FirstOrDefault(v => v.Variant.SKUID == selectedVariantID);

                   if (selectedVariant != null)
                   {
                       IsInStock = (selectedVariant.Variant.SKUTrackInventory == TrackInventoryTypeEnum.Disabled) || (selectedVariant.Variant.SKUAvailableItems > 0);
                       SelectedVariantID = selectedVariantID;
                   }

                   // Creates a list of product variants
                   VariantSelectList = new SelectList(variants.Select(v => new SelectListItem
                   {
                       Text = string.Join(", ", v.ProductAttributes.Select(a => a.SKUName)),
                       Value = v.Variant.SKUID.ToString()
                   }), "Value", "Text");
               }
           }


   ```
3. In the controller managing product listing, modify the action displaying details pages to retrieve product variants. Also add a new endpoint that returns a variant from a provided variant ID.

   ```csharp

           /// <summary>
           /// Displays product detail page of a product or product variant.
           /// </summary>
           public ActionResult Detail()
           {
               // Gets the product from the connected Xperience database
               SKUTreeNode product = GetProduct();

               // If the product is not found or if it is not allowed for sale, redirects to error 404
               if ((product == null) || !product.SKU.SKUEnabled)
               {
                   return HttpNotFound();
               }

               // Gets all product variants of the product
               List<ProductVariant> variants = VariantHelper
                   .GetVariants(product.NodeSKUID)
                   .OnSite(siteService.CurrentSite.SiteID).ToList()
                       .Select(sku => new ProductVariant(sku.SKUID))
                   .OrderBy(v => v.Variant.SKUPrice).ToList();

               // Selects the first product variant
               ProductVariant selectedVariant = variants.FirstOrDefault();

               // Calculates the price of the product or the variant
               ShoppingCartInfo cart = shoppingService.GetCurrentShoppingCart();

               SKUInfo selectedProduct = selectedVariant != null ? selectedVariant.Variant : product.SKU;

               ProductCatalogPrices priceDetail = priceCalculatorFactory
                  .GetCalculator(cart.ShoppingCartSiteID)
                  .GetPrices(selectedProduct, Enumerable.Empty<SKUInfo>(), cart);

               // Initializes the view model of the product or product variant
               ProductViewModel viewModel = new ProductViewModel(product, priceDetail, variants, selectedVariant?.Variant?.SKUID ?? 0);

               // Displays the product detail page
               return View(viewModel);
           }

           /// <summary>
           /// Loads information about the requested variant to change the page content.
           /// </summary>
           /// <param name="variantID">ID of the selected variant.</param>
           [HttpPost]
           public JsonResult Variant(int variantID)
           {
               // Gets SKU information based on the variant's ID
               SKUInfo variant = skuInfoProvider.Get(variantID);

               // If the variant is null, returns null
               if (variant == null)
               {
                   return null;
               }

               var cart = shoppingService.GetCurrentShoppingCart();

               // Calculates the price of the variant
               ProductCatalogPrices variantPrice = priceCalculatorFactory
                   .GetCalculator(cart.ShoppingCartSiteID)
                   .GetPrices(variant, Enumerable.Empty<SKUInfo>(), cart);

               // Finds out whether the variant is in stock
               bool isInStock = variant.SKUTrackInventory == TrackInventoryTypeEnum.Disabled || variant.SKUAvailableItems > 0;

               // Creates a JSON response for the JavaScript that switches the variants
               var response = new
               {
                   totalPrice = String.Format(cart.Currency.CurrencyFormatString, variantPrice.Price),
                   inStock = isInStock,
                   stockMessage = isInStock ? "Yes" : "No"
               };

               // Returns the response
               return Json(response);
           }


   ```
4. Update the view of your product details page:

   1. Add a variant selector

      ```csharp

      @if (Model.HasProductVariants)
      {
          @* Renders a drop-down selector allowing users to select a desired product variant. *@
          <div class="cart-item-selector" data-variant-action="@Url.Action("Variant")">
              <p>
                  Choose your desired variant:
                  @Html.DropDownListFor(m => m.SelectedVariantID, Model.VariantSelectList, new { @class = "js-variant-selector" })
              </p>
          </div>
      }
      @Scripts.Render("~/Scripts/jquery-2.1.4.min.js")
      @Scripts.Render("~/Scripts/variantSelector.js")


      ```
   2. Modify the add item to cart form to support product variants:

      ```csharp

          @* Renders an add to cart button. *@
          using (Html.BeginForm("AddItem", "Checkout", FormMethod.Post))
          {
              <input type="hidden" name="itemSkuId" id="selectedVariantID" value="@(Model.SelectedVariantID > 0 ? Model.SelectedVariantID : Model.SKUID)" />
              <label>Qty</label>
              <input type="text" name="itemUnits" value="1" />
              <input type="submit" name="AddItem" value="Add to cart" />
          }


      ```
5. Add a JavaScript file with a function that dynamically switches between variants (changes the view's content) when the variant drop-down selector changes. The file is linked within the variant selector code, and the function uses the endpoint defined in the controller above.

   ```csharp

   (function () {
       'use strict';

       // Initializes contextual variables
       var url = $('.cart-item-selector').data('variant-action'),
           stockMessage = $("#stockMessage"),
           totalPrice = $('#totalPrice'),
           selectedSKUID = $('#selectedVariantID');

       // Updates the displayed product details when a different variant
       // is selected from the variants drop-down selector
       $('.js-variant-selector').change(function () {
           var id = $(this).val();
           updateVariantSelection(id);
       });

       // Updates the product information from data retrieved for the selected variant
       function updateVariantSelection(variantId) {
           $.post(url, { variantID: variantId }, function (data) {
               stockMessage.text(data.stockMessage);
               totalPrice.text(data.totalPrice);
               selectedSKUID.val(variantId);
           });
       }

   }());

   ```

Customers can now add product variants to their shopping cart by selecting a variant from the drop-down selector.

> **Tip:** Instead of listing all available product variants in a drop-down selector, you can alternatively display a product option selector. This way, you allow customers manual selection from individual options defined for each product option category of the _Attribute_ type (e.g. in the form of radio buttons). Based on this selection, the 'Add to cart' functionality can then add the appropriate product variant to the shopping cart. See the [Adding a product option selector to product details pages](#adding-a-product-option-selector-to-product-details-pages) section for more information.

## Changing the product image for different variants

You may find it useful to display a different image for every product variant. For example, if you sell T-shirts, you may want to display a red T-shirt when a red variant is selected and a blue T-shirt when a blue variant is selected.

To display a different image for each variant:

1. [Enable the image path for each variant](#enabling-a-specific-image-path-for-each-variant)
2. [Display the variant's image in your MVC application](#displaying-product-variant-images)

### Enabling a specific image path for each variant

Change the default setting of the variant detail layout to include a selector for its image.

1. Open the **Modules** application in Xperience.
2. Edit the _E-commerce_ module.
3. Switch to the **Classes** tab.
4. Edit the _SKU_ class.
5. Switch to the **Alternative forms** tab.
6. Edit the _Variant properties_ form.
7. Switch to the **Fields** tab.
8. Select _SKUImagePath_ in the field panel.
9. Select the **Display field in the editing form** check box.

   ![Selecting the Display field in the editing form check box](https://docs.kentico.com/docsassets/13/displaying-product-variants/selecting_display_field_check_box.png "Selecting the Display field in the editing form check box")
10. Click **Save**.

When you now edit a product variant, you can see a selector for an image. By default, Xperience tries to display an image of the product variant. If the variant does not contain any image, the system uses an image of the variant's parent product.

### Displaying product variant images

This process assumes your MVC application can display product variants as described in [Displaying product variants in a drop-down selector](#displaying-product-variants-in-a-drop-down-selector).

1. Open your MVC project in Visual Studio.
2. Add a recognizable ID tag to the image in product details view.

   ```csharp

   <img id="js-product-image" ... />


   ```
3. Add the image ID to the JavaScript handling changes of the selected variant.

   ```js

   var productImage = $("#js-product-image");

   function updateVariantSelection(variantId) {

       // ...

       productImage.attr("src", data.imagePath);
   }

   ```
4. Add the image path for the specific variant to the JSON response created in the controller.

   ```csharp

               var response = new
               {
                   // ...

                   imagePath = Url.Content(variant.Variant.SKUImagePath)
               };


   ```

Your product details pages now display a different image for every variant. If the variant does not have any image specified, the system uses the parent product's image.

## Adding a product option selector to product details pages

A product option selector allows customers manual selection from individual options defined for each [product option category](https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/products/working-with-product-options.md) of the _Attribute_ type (e.g., in the form of radio buttons, or drop-down lists). Based on this selection, the system can retrieve the appropriate product variant from the database and add it to the shopping cart.

For a clearer idea of how a product option selector may look like, here's an implementation from our _Dancing Goat_ MVC sample site:

![Product option selector](https://docs.kentico.com/docsassets/13/displaying-product-variants/ProductOptionSelector.png "Product option selector")

To retrieve and dynamically display variants from product option selectors:

1. Create a view model for product option categories.

   - The view model needs to contain information required to select, display, and process a product variant's options.
2. To the action that displays the product details page (for example the _Detail_ action from the example above), add logic that loads a default product variant and its product option categories.

   ```csharp

               // Gets the cheapest variant of the product
               List<ProductVariant> variants = VariantHelper.GetVariants(product.NodeSKUID)
                   .OnSite(siteService.CurrentSite.SiteID).ToList()
                       .Select(s => new ProductVariant(s.SKUID))
                   .OrderBy(v => v.Variant.SKUPrice)
                   .ToList();

               ProductVariant cheapestVariant = variants.FirstOrDefault();

               // Gets the product's option categories
               IEnumerable<OptionCategoryInfo> categories = VariantHelper.GetProductVariantsCategories(sku.SKUID).ToList();

               // Gets the cheapest variant's selected attributes
               IEnumerable<ProductOptionCategoryViewModel> variantCategories = cheapestVariant?.ProductAttributes.Select(
                   option =>
                       new ProductOptionCategoryViewModel(sku.SKUID, option.SKUID,
                               categories.FirstOrDefault(c => c.CategoryID == option.SKUOptionCategoryID)));


   ```
3. Use your extended model class to pass the data of the available product options to your view.
4. Modify the endpoint that retrieves variant data to retrieve a product variant based on list IDs of selected product options.

   ```csharp

               // Retrieves a product variant from a given product ID and a collection of option IDs
               var variantSKU = VariantHelper.GetProductVariant(productId, new ProductAttributeSet(optionIds));

               if (variantSKU == null)
               {
                   return null;
               }

               return variantSKU;


   ```
5. If you followed the example above, you might need to modify the JavaScript function that switches between variants.
6. Add selectors for the available product options to the view that displays product details.

   > **Tip:** To display the default text for drop-down lists specified by [the Default text field](https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/products/working-with-product-options/creating-and-modifying-product-options/reference-product-option-category-properties.md), access the _DefaultText_ property of the _ProductOptionCategory_ type.

Customers can now configure product variants with attribute selectors.
