Commerce Search Results MVC view

Current version: 10.3

In the MVC (Model View Controller) model, the route (the code that parses the HTTP request) points to a controller (the .NET code) that generates a model (the object). This object is parsed by a view (in SXA Storefront, a Razor view). The view consists of presentation components that determine how data is displayed.

The MVC view
Note

You can customize the Commerce Search Results MVC view as required. For more information, see Override the default Rendering View Provider and Customize rendering HTML per site.

The Commerce Search Results MVC view is stored in its own folder under /views/Commerce/CommerceSearchResults. The Commerce Search Results MVC view has the following structure:

RequestResponse
/* Reference the model containing all the catalog content but excluding price and stock info */
@model Sitecore.XA.Feature.Search.Models.SearchResultsRenderingModel

@{
  /* SXA handling of the data class variant attribute */
  string variantClass = string.Empty;
  if (Model.Attributes.ContainsKey("class"))
  {
    variantClass = Model.Attributes["class"].Aggregate();
  }

  /* Get a handle to the storefront context */
  var storefrontContext = ServiceLocator.ServiceProvider.GetRequiredService<IStorefrontContext>();
}

/* Component enclosing markup, including data properties specifying the search service endpoint and parameters as JSON */
<div @Html.Sxa().Component(Model.Rendering.RenderingCssClass ?? "search-results", Model.Attributes) data-class-variant="@variantClass" data-properties='@Model.JsonDataProperties' data-cxa-component-class="CommerceSearchResults" data-cxa-component-initialized="false" data-cxa-component-type="component">

  /* 
     Label translations originating from storefront Commerce Terms in Commerce Control Panel. 
     Included as hidden markup as Scriban template cannot get a reference to it with the standard extension methods
  */
  @Html.Hidden("InStockDisplayName", storefrontContext.GetProductStockStatusName(CatalogFeatureConstants.InventoryStatuses.InStock))
  @Html.Hidden("OutOfStockDisplayName", storefrontContext.GetProductStockStatusName(CatalogFeatureConstants.InventoryStatuses.OutOfStock))
  @Html.Hidden("BackOrderableDisplayName", storefrontContext.GetProductStockStatusName(CatalogFeatureConstants.InventoryStatuses.BackOrderable))
  @Html.Hidden("PreOrderableDisplayName", storefrontContext.GetProductStockStatusName(CatalogFeatureConstants.InventoryStatuses.PreOrderable))

  /* When exporting markup using Creative Exchange, show 'Results not found' output */
  @if (WebUtil.GetQueryString(Sitecore.XA.Feature.Search.Constants.CreativeExchangeExport) != "true")
  {
    <div class="component-content">
      @Model.MessageIsEmpty
      <div class="no-results" style="display: @Model.StyleDisplay">
        @Html.Sxa().Field("ResultsNotFoundText", Model.DataSourceItem, !Model.IsControlEditable)
        @Html.Sxa().Field("Text", Model.Item, !Model.IsControlEditable)
      </div>
      <div class="progress"></div>
    </div>
  }
  else
  {
    /* Product cards are rendered using unordered lists HTML as markup */
    <ul class="search-result-list">
      <li>
		/* Loop processing the content of the rendering variant against the model and current item */
        @foreach (BaseVariantField variantField in Model.VariantFields)
        {
          @Html.RenderingVariants().RenderVariant(variantField, Model.PageItem, false, Model)
        }
      </li>
    </ul>
  }
</div>
@using System.Web.Mvc.Html
@using Microsoft.Extensions.DependencyInjection
@using Sitecore.Commerce.XA.Feature.Catalog
@using Sitecore.Commerce.XA.Foundation.Common.Context
@using Sitecore.DependencyInjection
@using Sitecore.Web
@using Sitecore.XA.Foundation.MarkupDecorator.Extensions
@using Sitecore.XA.Foundation.RenderingVariants.Extensions
@using Sitecore.XA.Foundation.SitecoreExtensions.Extensions
@using Sitecore.XA.Foundation.Variants.Abstractions.Fields

@model Sitecore.XA.Feature.Search.Models.SearchResultsRenderingModel

@{
  string variantClass = string.Empty;
  if (Model.Attributes.ContainsKey("class"))
  {
    variantClass = Model.Attributes["class"].Aggregate();
  }
  var storefrontContext = ServiceLocator.ServiceProvider.GetRequiredService<IStorefrontContext>();
}

<div @Html.Sxa().Component(Model.Rendering.RenderingCssClass ?? "search-results", Model.Attributes) data-class-variant="@variantClass" data-properties='@Model.JsonDataProperties' data-cxa-component-class="CommerceSearchResults" data-cxa-component-initialized="false" data-cxa-component-type="component">

  @Html.Hidden("InStockDisplayName", storefrontContext.GetProductStockStatusName(CatalogFeatureConstants.InventoryStatuses.InStock))
  @Html.Hidden("OutOfStockDisplayName", storefrontContext.GetProductStockStatusName(CatalogFeatureConstants.InventoryStatuses.OutOfStock))
  @Html.Hidden("BackOrderableDisplayName", storefrontContext.GetProductStockStatusName(CatalogFeatureConstants.InventoryStatuses.BackOrderable))
  @Html.Hidden("PreOrderableDisplayName", storefrontContext.GetProductStockStatusName(CatalogFeatureConstants.InventoryStatuses.PreOrderable))

  @if (WebUtil.GetQueryString(Sitecore.XA.Feature.Search.Constants.CreativeExchangeExport) != "true")
  {
    <div class="component-content">
      @Model.MessageIsEmpty
      <div class="no-results" style="display: @Model.StyleDisplay">
        @Html.Sxa().Field("ResultsNotFoundText", Model.DataSourceItem, !Model.IsControlEditable)
        @Html.Sxa().Field("Text", Model.Item, !Model.IsControlEditable)
      </div>
      <div class="progress"></div>
    </div>
  }
  else
  {
    <ul class="search-result-list">
      <li>
        @foreach (BaseVariantField variantField in Model.VariantFields)
        {
          @Html.RenderingVariants().RenderVariant(variantField, Model.PageItem, false, Model)
        }
      </li>
    </ul>
  }
</div>

The following is an example of the enclosing markup for the rendering, when it is running live on the storefront site:

An example of the enclosing markup for the rendering

Do you have some feedback for us?

If you have suggestions for improving this article,