最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Validation Summary for jQuery Unobtrusive Validation does not display - Stack Overflow

programmeradmin3浏览0评论

I am working with the following:

  • MVC4
  • jQuery 1.11.2
  • jQuery Validate 1.13.1
  • jQuert.Validate.Unobtrusive (dispalyed as 3.2.3 via nuget)
  • Knockout 3.3

My Knockout View Model template is depicted below:

<tbody data-bind="foreach:recipientEmailAddressList">
    <tr>
        <td class="no-padding" style="width:330px">
            <input class="suppress-ms-clear input-parameter full-width" data-bind="value:EmailAddress, hasfocus:EmailAddress.focused" name="EmailAddresses" data-val="true" data-val-email="Please enter a valid email address.">
        </td>
        <td class="no-padding align-right">
            <div class="delete" data-bind="visible: $root.recipientEmailAddressList().length > 1">
                <a href="" data-bind="click:$root.removeRecipientEmailAddress"><span class="no-wrap">X</span></a>
            </div>
        </td>
    </tr>
</tbody>

I also have the following in the MVC view:

@Html.ValidationSummary(false)

When I add an e-mail which fails validation, the invalid element styling is correctly applied to the input element, however the validation summary is not displayed with the validation error. Likewise, the user is allowed to submit the page, even though a validation error is clearly present.

I do not have any code which binds to the submit element of the form.

It seems like the unobtrusive validation knows that there is a problem by applying the error styling, but why is it not showing the validation summary? Why can I submit the form? If I correct the e-mail address so it is valid, the error styling on the input goes away.

I am working with the following:

  • MVC4
  • jQuery 1.11.2
  • jQuery Validate 1.13.1
  • jQuert.Validate.Unobtrusive (dispalyed as 3.2.3 via nuget)
  • Knockout 3.3

My Knockout View Model template is depicted below:

<tbody data-bind="foreach:recipientEmailAddressList">
    <tr>
        <td class="no-padding" style="width:330px">
            <input class="suppress-ms-clear input-parameter full-width" data-bind="value:EmailAddress, hasfocus:EmailAddress.focused" name="EmailAddresses" data-val="true" data-val-email="Please enter a valid email address.">
        </td>
        <td class="no-padding align-right">
            <div class="delete" data-bind="visible: $root.recipientEmailAddressList().length > 1">
                <a href="" data-bind="click:$root.removeRecipientEmailAddress"><span class="no-wrap">X</span></a>
            </div>
        </td>
    </tr>
</tbody>

I also have the following in the MVC view:

@Html.ValidationSummary(false)

When I add an e-mail which fails validation, the invalid element styling is correctly applied to the input element, however the validation summary is not displayed with the validation error. Likewise, the user is allowed to submit the page, even though a validation error is clearly present.

I do not have any code which binds to the submit element of the form.

It seems like the unobtrusive validation knows that there is a problem by applying the error styling, but why is it not showing the validation summary? Why can I submit the form? If I correct the e-mail address so it is valid, the error styling on the input goes away.

Share Improve this question edited Mar 17, 2015 at 16:26 Sparky 98.8k26 gold badges202 silver badges290 bronze badges asked Mar 14, 2015 at 17:07 codechurncodechurn 3,9905 gold badges47 silver badges70 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

TLDR: "jQuery Validate" and "Microsoft jQuery Unobtrusive Validation" do not work well together (Reference). Drop Microsoft unobtrusive validation scripts and go for jQuery Validate's native support for html attribute validation. It works a lot better.

Long description:

I have recently been struggling with this myself and after hours of research I came to the conclusion that "jQuery Validate" and "Microsofts Unobtrusive Validation" do not work well together (Reference).

From this article I gathered that Microsoft's unobtrusive validation chokes a lot of the jQuery Validate functionality by overriding some of the options. For example, any custom settings are ignored once the unobtrusive scripts are loaded. This makes it very difficult to specify custom validation rules/behavior in your JavaScript (which was needed in my case).

For my situation I am also using KnockoutJS. The first thing I do is serialize my C# model into a JSON model and then load it into KnockoutJS using the ko.mappings utility (available via NuGet).

I then apply the data-bindings to my markup and have the HTML generated by KnockoutJS. To get validation to work for me I copied the generated markup from one of the HTML helper functions, like TextBoxFor, and applied the validation rules generated to my HTML.

For example:

<data-val-required="This fields is required" .... >

While this solution was working partially, as you have mentioned, I was unable to get the scripts to correctly highlight the invalid inputs and display the validation summary.

At first I thought this is all that I would need to do to get the unobtrusive validation working. But I then discovered that firstly, each element to be validated requires a unique name (duh), and secondly, that the unobtrusive validation scripts do not work with dynamically generated content.

To get around the issue of the unobtrusive validation scripts not working with dynamically generated content, I followed the advice found in this, this and this article.

Using the code below I was able to get it to reparse the data:

var form = $(".formSelector")
form.removeData('validator');
form.removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse(form);

After reparsing the form and after any content was dynamically added, I was able to get the newly generated fields to validate correctly. I also found this which might be helpful, but I never ended up using it.

I then encountered another problem: I couldn't validate disabled/read-only inputs (I know this is unconventional, but I required it) without overriding some of jQuery Validate's settings. As I mentioned before, this is not possible without modifying the unobtrusive validation scripts. (Yuk!)

Eventually I stumbled upon this site: jQuery Validate Unobtrusive Native which is also on GitHub. It was at this point that I discovered:

Since jQuery Validate 1.11.x they started including native support for unobtrusive validation which works with Dynamic content

I then dropped Microsoft's unobtrusive validation scripts. It is important to note that the validation attributes are different for Microsoft's unobtrusive scripts than that used by jQuery Validate Unobtrusive Native scripts. Hence the need for custom HTML helpers provided by this project.

Once I removed Microsoft's unobtrusive validation script and replaced all the generated attributes with the correct attributes used by jQuery Validate, my form started to validate correctly! :)

Using this I established how to convert the attributes, but I am sure there are many other references/examples.

Also note that with Microsoft's unobtrusive validation scripts removed, I was required to setup validation on the form manually using the following code:

$(".formSelector").validate({
...options...
});

Here is an example of KnockoutJS being used with jQuery's Native Unobtrusive Validation.

You may need to write some CSS to handle the highlighting of the elements because AFAICT, jQuery Validate uses different error classes than that of the Microsoft unobtrusive scripts.

Now, about the validation summary: I still haven't gotten this working, but as far as I can tell you would need to override the default implementation for displaying errors. In the code below I illustrate, how to use a custom tool-tip for displaying error messages (Reference). I assume you would have to do something similar to apply error messages to the ValidationSummary once errors are detected on the form. That is, run through the list of errors and append them to the validation summary element generated by @Html.ValidationSummary().

I'm trying to achieve this too, so once I figure out how to do it, I will post my solution.

//Note this requires the bootstrap tooltip plugin...

$("form").validate({
    showErrors: function (errorMap, errorList) {

        // Clean up any tooltips for valid elements
        $.each(this.validElements(), function (index, element) {
            var $element = $(element);

            $element.data("title", "") // Clear the title - there is no error associated anymore
                .removeClass("error")
                .tooltip("destroy");
        });

        // Create new tooltips for invalid elements
        $.each(errorList, function (index, error) {
            var $element = $(error.element);

            $element.tooltip("destroy") // Destroy any pre-existing tooltip so we can repopulate with new tooltip content
                .data("title", error.message)
                .addClass("error")
                .tooltip(); // Create a new tooltip based on the error messsage we just set in the title
        });
    },

    rules: { /*.... Rules here ....*/ },

    submitHandler: function (form) {
        alert("This is a valid form!");
    }
});

EDIT: For anyone interested here is the SO article I referenced to get readonly/disabled inputs to validate.

Hopefully this will end up helping someone - I wish I had found this info in the beginning.

发布评论

评论列表(0)

  1. 暂无评论