Client-side validation of Sitefinity CAPTCHA MVC Feather Form Field

By in
No comments

In the current 9.1.6110 release of Sitefinity, there is a known issue with the Sitefinity CAPTCHA MVC form field that prevents it from firing the client-side validation.

If the user leaves the CAPTCHA field blank, the form will still submit (either a full post-back or via AJAX, depending on the settings of the form), and the user will see a generic “Entry not valid” error message.

entry-not-valid

It would probably be better to catch this right away via client-side validation. Fortunately, using Feather, we can easily override the CAPTCHA template to enable this. We simply need to change the input field to make it required.

Depending on your configuration, you can either modify the template in the ResourcePackages (such as if you’re using Bootstrap) or extract the template from the resources (or download the original embedded template from Github. Note this may be fixed already in future releases when this bug is resolved).

The original markup for the field looks like this:

    <div class="form-group">
        <label for='@Html.UniqueId("Textbox")'>@Html.Resource("TypeCodeAbove") </label>
        <input id='@Html.UniqueId("Textbox")' type="text" data-sf-role="captcha-input" name="@Model.CaptchaAnswerFormKey" class="form-control input-sm"/>
    </div>

Here’s a modified version that enables the required field directly on the field:

    <div class="form-group">
        <input data-sf-role="violation-messages" type="hidden" value='{"maxLength":"99", "required": "Please fill out this field." }' />
 
        <label for='@Html.UniqueId("Textbox")'>@Html.Resource("TypeCodeAbove") </label>
        <input id='@Html.UniqueId("Textbox")' type="text" data-sf-role="captcha-input" required="'required'" name="@Model.CaptchaAnswerFormKey" class="form-control input-sm"/>
 
   </div>

Now the client-side validation from the rest of the form propagates to the CAPTCHA field and we can capture the error before the form is submitted:

Sitefinity captcha required-message

Of course, by overriding the template, this will apply to all instances of the field. However, this is likely desired behavior in this case, so we’ll leave it at that.

Here below is the complete markup for the field:

@model Telerik.Sitefinity.Frontend.Forms.Mvc.Models.Fields.Captcha.CaptchaViewModel
 
@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
@using Telerik.Sitefinity.Modules.Pages;
@using Telerik.Sitefinity.Services;
 
@Html.Script(ScriptRef.JQuery, "top", false)
 
<div data-sf-role="field-captcha-container" style="display:none;" class="@Model.CssClass form-group">
    <div>
        <img data-sf-role="captcha-image" src='@Url.WidgetContent("assets/dist/img/dummy.jpg")'/>
    </div>
 
    <a data-sf-role="captcha-refresh-button">@Html.Resource("NewCode")</a>
 
    <div class="form-inline">
        <div class="form-group">
            <input data-sf-role="violation-messages" type="hidden" value='{"maxLength":"99", "required": "Please fill out the CAPTCHA to submit the form." }' />
 
            <label for='@Html.UniqueId("Textbox")'>@Html.Resource("TypeCodeAbove") </label>
            <input id='@Html.UniqueId("Textbox")' type="text" data-sf-role="captcha-input" required="'required'" name="@Model.CaptchaAnswerFormKey" class="form-control input-sm"/>
 
        </div>
    </div>
    <input type="hidden" data-sf-role="captcha-ca" name="@Model.CaptchaCorrectAnswerFormKey" />
    <input type="hidden" data-sf-role="captcha-iv" name="@Model.CaptchaInitializationVectorFormKey" />
    <input type="hidden" data-sf-role="captcha-k" name="@Model.CaptchaKeyFormKey" />
 
    <input type="hidden" data-sf-role="captcha-settings" value="@Model.GenerateUrl" />
</div>
 
@if (SystemManager.IsDesignMode)
{
    var scriptUrl = Url.WidgetContent("Mvc/Scripts/Captcha/captcha.js");
    var queryAddition = scriptUrl.Contains("?") ? "&" : "?";
    var fullScriptUrl = scriptUrl + queryAddition + string.Format("_={0}", DateTime.UtcNow.Ticks.ToString());
    
    <script type="text/javascript" src='@fullScriptUrl'></script>
}
else
{
    @Html.Script(Url.WidgetContent("Mvc/Scripts/Captcha/captcha.js"), "bottom", false)
}

Hopefully a future release of Sitefinity will address this issue, but for now if you need client-side validation of the CAPTCHA, this should do the trick!

As always, I hope you found this helpful, and thanks for reading!

The following two tabs change content below.

selaromdotnet

Senior Developer at iD Tech
Josh loves all things Microsoft and Windows, and develops solutions for Web, Desktop and Mobile using the .NET Framework, Azure, UWP and everything else in the Microsoft Stack. His other passion is music, and in his spare time Josh spins and produces electronic music under the name DJ SelArom. His other passion is music, and in his spare time Josh spins and produces electronic music under the name DJ SelArom.