Pages

Monday, November 22, 2021

Validation Summary for Optimizely Forms in Non JS Mode

I recently wrote an article on how to create a Validation Summary for Optimizely Forms. The approach described in that article uses Form Client Events and Javascript to add a validation summary to the top of the form. That method is dependent on Javascript, and Forms must operate in JS mode for it to work. This article provides a different solution for use with Optimizely Forms with workInJonJSMode enabled.

A custom Form Container Block is required for this method

Create a custom Form Container Block using one of the following guides:

  1. Optimizely documented way
  2. Custom Optimizely Form Containers - Put the View Where You Want
  3. Optimizely Form Container Block with Razor View
 

If your Form Container Block file is ASCX

Locate the div with class Form__Status__Message and add the validation summary block below. 

[pre class="brush:xhtml;class-name:collapse-box"]
    <%-- area for showing Form's status or validation --%>
    <div class="Form__Status">
        <div class="Form__Status__Message <%: statusDisplay %>" data-f-form-statusmessage>
            <%= message %>
        </div>
        <% // add this section below Form__Status__Message
            if (_formConfig.WorkInNonJSMode && ViewBag.ValidationFail)
            {
            %>            
                <div class="Form__Validation__Summary">
                <%
                    foreach (var element in Model.Form.Steps.ElementAt((int)ViewBag.CurrentStepIndex)?.Elements.Select(e => e.SourceContent as EPiServer.Forms.Implementation.Elements.BaseClasses.ValidatableElementBlockBase).Where(e => e != null))
                    {
                        var validationMessage = element.GetErrorMessage();
                        if (!string.IsNullOrEmpty(validationMessage)) {
                        %>
                            <div class="validation-summary-error">
                                <label for="<%= element.FormElement.Guid %>"><%= element.Label %>:</label>
                                <%= Html.ValidationMessageFor(element) %>
                            </div>
                        <%
                        }
                    }
                    %>
                </div>
        <% } %>
    </div>
[/pre]

 

If your Form Container Block file is CSHTML

Locate the div with class Form__Status__Message and add the validation summary block below. 

[pre class="brush:razor;class-name:collapse-box"]
    @* area for showing Form's status or validation *@
    <div class="Form__Status">
        <div class="Form__Status__Message @statusDisplay" data-f-form-statusmessage>
            @Html.Raw(message)
        </div>
        @*add this section below Form__Status__Message*@
        @if (_formConfig.WorkInNonJSMode && ViewBag.ValidationFail)
        {
            <div class="Form__Validation__Summary">
                @foreach (var element in Model.Form.Steps.ElementAt((int)ViewBag.CurrentStepIndex)?.Elements.Select(e => e.SourceContent as EPiServer.Forms.Implementation.Elements.BaseClasses.ValidatableElementBlockBase).Where(e => e != null))
                {
                    var validationMessage = element.GetErrorMessage();
                    if (!string.IsNullOrWhiteSpace(validationMessage))
                    {
                        <div class="validation-summary-error">
                            <label for="@element.FormElement.Guid">@element.Label:</label>
                            @Html.ValidationMessageFor(element)
                        </div>
                    }
                }
            </div>
        }
    </div>
[/pre]

 

Finally, verify non-JS mode is enabled in Forms.config

If you're here you probably already have this set. However, in case you don't, the Forms.config file is located in /modules/_protected/EPiServer.Forms. Change the value for "workInNonJSMode" to true. With this setting enabled, submitting the form will submit server-side before returning the view. 

The code blocks above only work when workInNonJSMode is enabled. If validation fails, validatable elements in the current step are iterated and the validation helper is called for each. If a form element fails validation a message is returned, and it's added to the summary. 

You can support JS and Non-JS Forms by combining methods

You can take the script from my Validation Summary for Optimizely Forms article and add it to the bottom of your Form Container Block file. It will only execute if Forms jQuery is included, so it plays nicely with this code.

No comments:

Post a Comment

Share your thoughts or ask questions...