Search code examples
jqueryasp.net-mvcasp.net-mvc-3jquery-validateclient-side-validation

Custom ValidationSummary template (that doesn't break client-side validation)


A similar question has been asked before (Custom ValidationSummary template Asp.net MVC 3) but neither of the answers satisfy the extra requirement I have, which is that the solution doesn't break client-side validation.

So, does anyone know a way to get functionality like this:

@if (!ViewData.ModelState.IsValid)
{
    <div class="form-errors">
        <p>Please have another look at the fields highlighted below</p>
        @Html.ValidationSummary()
    </div>
}

that works with client-side validation?

This does exactly what I want when client-side validation is off, i.e., excludes the whole div if the model is valid, displays it if there are any errors. However, the conditional means that when the form is first rendered when the evaluation is false, the entire section is not rendered, so jquery.validate can't find any place to insert the validation summary.

Any ideas?


Solution

  • helper:

        public static MvcHtmlString MyValidationSummary(this HtmlHelper helper, bool excludePropertyErrors = false)
        {
            string html = "";
    
            html += helper.ViewData.ModelState.IsValid ? "<div class='form-errors' style='display:none;'>" : "<div class='form-errors'>";
    
            html += "<p>Please have another look at the fields highlighted below</p>";
            html += helper.ValidationSummary(excludePropertyErrors);
            html += "</div>";
    
            return new MvcHtmlString(html);
        }
    

    View:

    @using (Html.BeginForm("Index", "Home",FormMethod.Post, new {id="myform"}))
    {
        @Html.MyValidationSummary()
        ...
        <input type="button" id="submitbutton" value="Submit" />
    }
    

    JS:

    $("#submitbutton").click(function () {
        $("#myform").validate();
    
        if (!$("#myform").valid()) {
            $("#myform .form-errors").show();
        }
        else {
            $("#myform").submit();
        }
    });
    

    Update:

    If you want to go with the partial view

    Shared/_MyValidationSummary.cshtml

    @if (!ViewData.ModelState.IsValid)
    {
        <div class="form-errors">
            <p>Please have another look at the fields highlighted below</p>
            @Html.ValidationSummary()
        </div>
    }
    else
    {
        <div class="form-errors" style="display:none;">
            <p>Please have another look at the fields highlighted below</p>
            @Html.ValidationSummary()
        </div>
    }
    

    View:

    @using (Html.BeginForm("Index", "Home",FormMethod.Post, new {id="myform"}))
    {
        @Html.Partial("_MyValidationSummary")
        ...
        <input type="button" id="submitbutton" value="Submit" />
    }