Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Client validation not showing message

I have a MVC4 internet application with a form for creating user accounts. The form validation works but while the input fails validation no error message is displayed. It still prevents submitting until the validation problem is solved but there is no text

Razor View Form

<h2>Create New Account</h2>
<fieldset>
    <legend></legend>
    @using (Html.BeginForm("CreateUser",null)){
        @Html.AntiForgeryToken()
        <table class="create">
            <tr>
                <td colspan="2"><b>New Account</b>
            </tr>
            <tr>
                <td>@Html.DisplayNameFor(model=>model.UserName)</td><td>@Html.TextBoxFor(model=>model.UserName)</td>
                <td>@Html.DisplayNameFor(model=>model.EmailAddress)</td><td>@Html.TextBoxFor(model=>model.EmailAddress)</td>
                <td><input type="submit" value="Create User" /></td>
            </tr>
        </table>
    }
</fieldset>
    @Html.ValidationSummary()

The bundles used include the validation files

bundles.Add(new ScriptBundle("~/bundles/asset").Include(
            "~/Scripts/jquery-{version}.js",
            "~/Scripts/jquery-ui-{version}.js",
            "~/Scripts/jquery.validate*",
            "~/Scripts/jquery.unobtrusive*"));

The Model used is an entity model, I have added a partial class to annotate the validation requirements

[MetadataType(typeof(UserProfileMetadata))]
public partial class UserProfile
{
    //Empty Class just required for adding class level attribute
}

public class UserProfileMetadata
{
    //Fields from user profile requiring annotations
    [EmailAddress]
    [Required]
    [Display(Name = "Email Address")]
    public string  EmailAddress { get; set; }

    [Required]
    public string UserName { get; set; }

}

The validation working but now showing the message makes me think it must be a markup error but I just can't see it.

like image 619
Lotok Avatar asked Jun 19 '13 12:06

Lotok


2 Answers

Moving the ValidationSummary inside the form will fix it.

<h2>Create New Account</h2>
<fieldset>
    <legend></legend>
     @using (Html.BeginForm("CreateUser",null)){
        @Html.ValidationSummary()
        @Html.AntiForgeryToken()
        <table class="create">
            <tr>
                <td colspan="2"><b>New Account</b>
            </tr>
            <tr>
                <td>@Html.DisplayNameFor(model=>model.UserName)</td>    <td>@Html.TextBoxFor(model=>model.UserName)</td>
            <td>@Html.DisplayNameFor(model=>model.EmailAddress)</td><td>@Html.TextBoxFor(model=>model.EmailAddress)</td>
            <td><input type="submit" value="Create User" /></td>
        </tr>
    </table>
}
</fieldset>
like image 192
Slicksim Avatar answered Oct 06 '22 14:10

Slicksim


For anyone stumbling across this who does not wish to be restricted to moving the @Html.ValidationSummary into the form, i.e. it lives in _Layout.cshtml, and you like it there, here's a way around that.

The below method is apparently what is used by Microsoft to populate @Html.ValidationSummary. In it's standard form, it looks for data-valmsg-summary-true in $('this'). this in this case is the calling form. Well, my @Html.ValidationSummary lives in the pageBody <div> on _Layout.cshtml to keep it DRY.

function onErrors(event, validator) { // '#pageBody' is the containing element
    var container = $('#pageBody').find("[data-valmsg-summary=true]"), 
    list = container.find("ul"); if (list && list.length && validator.errorList.length) {
        list.empty(); container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
        $.each(validator.errorList, function () {
             $("<li />").html(this.message).appendTo(list);
        });
    }
}

So far, I've only changed this:

var container = $('this').find("[data-valmsg-summary=true]")

to this:

var container = $('#pageBody').find("[data-valmsg-summary=true]")

Now, I trigger my validation from a button click. To get onErrors(event, validator) to fire, I used the following jQuery:

    $('#btnSave').click(function () {
        if ($('form').valid()) {
           // Do stuff
        } else {
            onErrors(event, $('form').data('validator'));
        }
    });

Voila, @Html.ValidationSummary populates even when using jQuery.unobtrusive.

A big thanks to Leniel Macaferi for pointing me in the right direction here: http://www.leniel.net/2013/08/customizing-aspnet-mvc-html-validation-summary-with-bootstrap-3-panel.html#sthash.jGRguVuV.qSjYUlhS.dpbs

like image 5
Owen Avatar answered Oct 06 '22 12:10

Owen