How to Add Swatches to a View

OVERVIEW

Swatches are a setting that requires a bit of work to configure.  However, once configured, this could be a powerful tool to help convert customers that are looking for custom options for the product they are interested in.

Configuring swatches alone will not make them appear to your customers.  Adjusting your view to display the swatches correctly will allow you as the designer to work together with the store administrators to show swatches when the product is configured to do so.

REQUIREMENTS

The following pre-requisites will be necessary to accomplish the goals of this article:

  • Have one or more products with swatches configured
  • Have store administration access in your Hotcakes Commerce store
  • Have file system access to your store
  • Familiarity with how to modify and create views
  • HTML & CSS knowledge
  • Familiarity with scripting methodologies or an understanding of Razor Syntax
  • Visual Studio 2012 or newer (for intellisense)

It is highly suggested that you first review the custom viewsets documentation prior to following the steps in this article.  Doing so will help you understand the steps required here better.

GETTING STARTED

You should already have an understanding of how to work with and modify or create views in Hotcakes Commerce.  Ideally, you should also have a viewset project ready for you to make the minor modifications suggested here.

HOW TO DISPLAY SWATCHES ON A PRODUCT VIEW

Your viewset should still be following the pattern of the “_default” viewset that ships with Hotcakes Commerce.  There are views for each customer-facing piece of functionality, including the Products view.  The products view is similar to others in that there is a main view and then a few smaller “partial” views that are injected into the main view named Index. 

You could technically add this functionality into the Index view or create a copy of the Index view and add the swatch functionality there.  This is up to you.  However, the example here will have you update the _ProductDetails.cshtml partial view instead.

PLEASE NOTE: Do not make changes to the views in the _default viewset. Your changes will be lost on upgrade.

Open the _ProductDetails.cshtml partial view in your custom viewset project.  Find the bit of code that displays the product options.  We will be making changes to this portion of the view.  An example of what you’re looking for is shown below.

if (!Model.LocalProduct.IsBundle)
{
    @*@Html.Raw(Model.PreRenderedOptions)*@
    foreach (var opt in Model.LocalProduct.Options)
    {
@if(!opt.NameIsHidden){@opt.Name}
@Html.Raw(opt.RenderWithSelection(Model.Selections.OptionSelectionList))

    }
}
else
{
    foreach (var bundledItem in Model.BundledItems)
    {
        if (bundledItem.Item.Options.Count > 0)
        {

@bundledItem.Item.ProductName


            foreach (var opt in bundledItem.Item.Options)
            {
@if(!opt.NameIsHidden){@opt.Name}
@Html.Raw(opt.RenderWithSelection(Model.Selections.GetSelections(bundledItem.BundledProductAdv.Id), bundledItem.BundledProductAdv.Id.ToString()))

            }
        }
    }
}

In order to properly show swatches on a product using the same views as other products, we will need to use Razor syntax to branch the design logic using an IF statement.  The resulting code is shown below.  Note the lines where the design will now check to see if the option "IsColorSwatch."

if (!Model.LocalProduct.IsBundle)
{
    @*@Html.Raw(Model.PreRenderedOptions)*@
    foreach (var opt in Model.LocalProduct.Options)
    {
@if(!opt.NameIsHidden){@opt.Name}
@Html.Raw(opt.RenderWithSelection(Model.Selections.OptionSelectionList))
@if (opt.IsColorSwatch) {
@Html.Raw(Model.SwatchHtml)
}

    }
}
else
{
    foreach (var bundledItem in Model.BundledItems)
    {
        if (bundledItem.Item.Options.Count > 0)
        {

@bundledItem.Item.ProductName


            foreach (var opt in bundledItem.Item.Options)
            {
@if(!opt.NameIsHidden){@opt.Name}
@Html.Raw(opt.RenderWithSelection(Model.Selections.GetSelections(bundledItem.BundledProductAdv.Id), bundledItem.BundledProductAdv.Id.ToString()))
@if (opt.IsColorSwatch) {
@Html.Raw(Model.SwatchHtml)
}

            }
        }
    }
}

The previous code sample will show swatches on the product when the product choices are saved to do so, and it won’t when there aren’t any swatch choices to show.  It’s literally that easy!

The image below shows you what this might look like.  Although, it would look much better with some additional CSS applied to it.

Swatches added to the product

Customizing How Swatches are Displayed in the View

If you prefer to still use the swatch functionality, but would rather display them in another way, you can do that too, but it requires a more advanced use of Razor.  This is necessary so that you can generate the HTML manually that you want, instead of using the out of the box HTML that’s generated for you.

There is only one pre-packaged method to generate the swatch HTML for you, so we will make use of Razor functions to get the necessary functionality.  If you’re not familiar with functions, they are simply re-usable snippets of code that other code can call on. 

Luckily for you, that code is already written, completely commented, and you can copy and paste it into your view.

@model Hotcakes.Modules.Core.Models.ProductPageViewModel
@using Hotcakes.Commerce.Catalog
@using Hotcakes.Modules.Core.Models

@functions
{

    // this method will iterate through each swatch item and generate HTML code for it
    private string getCustomSwatchHtml(Option swatch)
    {
        // this is a placeholder that the HTML will be added to
        var swatchHtml = string.Empty;

        // iterating through each option in the swatch
        foreach (var item in swatch.Items)
        {
            // call for the HTML to be generated and added to this local placeholder
            swatchHtml = swatchHtml + swatchItemImage(item.Name);
        }

        // emit the HTML we just generated
        return swatchHtml;
    }

    // this method is the actual HTML that will be generated for each swatch item
    private string swatchItemImage(string itemName)
    {
        // Here is where you could add <a>, onclick and any number of things...
        var swatchItem = "\''";
        // send the HTML back to the calling method
        return swatchItem;
    }

}

Now, update your HTML portion of the view to call the function.

if (!Model.LocalProduct.IsBundle)
{
    @*@Html.Raw(Model.PreRenderedOptions)*@
    foreach (var opt in Model.LocalProduct.Options)
    {
@if(!opt.NameIsHidden){@opt.Name}
@Html.Raw(opt.RenderWithSelection(Model.Selections.OptionSelectionList))
@if (opt.IsColorSwatch) {
@Html.Raw(getCustomSwatchHtml(opt))
}

    }
}
else
{
    foreach (var bundledItem in Model.BundledItems)
    {
        if (bundledItem.Item.Options.Count > 0)
        {

@bundledItem.Item.ProductName


            foreach (var opt in bundledItem.Item.Options)
            {
@if(!opt.NameIsHidden){@opt.Name}
@Html.Raw(opt.RenderWithSelection(Model.Selections.GetSelections(bundledItem.BundledProductAdv.Id), bundledItem.BundledProductAdv.Id.ToString()))
@if (opt.IsColorSwatch) {
@Html.Raw(getCustomSwatchHtml(opt))
}

            }
        }
    }
}

Again, this could use a little bit more CSS to make it look just the way you want, but you can clearly see that we have our own HTML in place now.

Swatches now appear much larger

That’s all there is to it!  Despite having to use some extra code in the user interface, making changes like this are fairly simple.

 

Have more questions? Submit a request

Need More Help?

Do you need more assistance with this article? Please review your support options.