Custom Multi-Sort Tutorial - Validation, Helpers, and Debugging

This page covers how to improve the user experience for the people using the custom component.

Validating that the fields are set

This component requires some fields to work properly. Therefore, it would be nice to warn the user when a field that is required has no value.

The BaseModelWithProperties base class provides multiple properties for validation:

  • IsConfigured
  • HasWarning
  • HasErrors
  • ValidateModel()

The ValidateModel() method returns an ErrorReport that contains all the information collected during the validation phase. It will be used later in the view to show those errors to the end-user.

The other properties are helpers if you require quick-access to some report information.

Start by creating a validator class that implements the IComponentModelValidator interface.

public class MultiSortPropertiesValidator : IComponentModelValidator
{
    private readonly MultiSortModelProperties m_Properties;
    public MultiSortPropertiesValidator(MultiSortModelProperties p_Properties)
    {
        m_Properties = p_Properties;
    }
    public void AddToReport(IErrorReport p_ErrorReport)
    {
        // Insert validations here
    }
}

Then, add errors if some properties are not properly configured:

public void AddToReport(IErrorReport p_ErrorReport)
{
    if (String.IsNullOrEmpty(m_Properties.FirstField)) {
        p_ErrorReport.AddError("The FirstField value is not defined.");
    }
    if (String.IsNullOrEmpty(m_Properties.SecondField)) {
        p_ErrorReport.AddError("The SecondField value is not defined.");
    }
}

You can now use this validator in your MultiSortModel class.

protected override void OnPropertiesInitialized()
{
    AddOnValidationHandler(() => new MultiSortPropertiesValidator(Properties));
}

To leverage this ErrorReport, you need to add the following lines to your MultiSort.cshtml file.

@using Coveo.UI.Components.Extensions
@model Coveo.Custom.MultiSortModel
<style>
    .coveo-sort-container .errorreport {
        font-size: 12px;
    }
</style>
<div class="coveo-sort-container">
    @Html.Coveo().RenderErrorSummary(Model.ValidateModel())
    @if (Model.IsConfigured) {
        <div id="@Model.Id"
            class="CoveoSort"
            data-caption="My Multi-Sort"
            @foreach (var property in @Model.RawProperties) {
                @:data-@(property.Key)='@(property.Value)'
            }></div>
        <script>
            document.addEventListener("DOMContentLoaded", function() {
                var attributes = document.getElementById("@Model.Id").dataset;
                var firstCriteria = CoveoForSitecore.Context.fields.toCoveo(attributes.firstField) + " " + attributes.direction;
                var secondCriteria = CoveoForSitecore.Context.fields.toCoveo(attributes.secondField) + " " + attributes.direction;
                attributes.sortCriteria = firstCriteria + ", " + secondCriteria;
            });
        </script>
    }
</div>

The @Html.Coveo().RenderErrorSummary(Model.ValidateModel()) line renders any errors and warnings in the ErrorReport. The report is only rendered in the Experience Editor, leaving the published page clean of any configuration error.

The @if (Model.IsConfigured) { condition only renders the component when there are no errors in the report. This ensures that the component is not in an invalid state, which could lead to weird behavior in the Search Interface.

The style tag contains an adjustment that is specific to the CoveoSort component’s error report.

When the fields are not properly set, you should see the following report:

Helping the end user

Since the field requires to be prefixed by the @ character or the component will fail, we could introduce some code that validates that it starts with this character.

Fortunately, the Coveo for Sitecore Hive Framework already provides this helper.

In your MultiSortModelProperties class, add the following parameter to the SearchUiProperty attribute for both fields:

[SitecoreProperty("FirstField")]
[SearchUiProperty(PropertySerializer = typeof(FieldNameSerializer))]
public string FirstField { get; set; }
[SitecoreProperty("SecondField")]
[SearchUiProperty(PropertySerializer = typeof(FieldNameSerializer))]
public string SecondField { get; set; }

This serializer ensures that the field starts with the @ character when serializing the value in the RawProperties. Your user can now freely forget it without breaking the component!

You can write your own helper method by implementing the IPropertySerializer interface.

Debugging

You might want to support the Enable Debug Information from the Coveo ribbon in the Experience Editor.

To support it, you need to add the following line in your MultiSort.cshtml file:

@Html.Partial(Partials.DEBUG_INFORMATION, Model)

Due to a styling issue, add the following style tag:

<style>
    .coveo-sort-container .coveo-debug-information {
        font-size: 12px;
    }
</style>

Once added, get in the Experience Editor, check the Enable Debug Information button and you should get the following result: