Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using unobtrusive validation in ASP.NET MVC 3, how can I take action when a form is invalid?

I have a page with jQuery UI tabs on it, and a single required field on the first tab. Validation works, and the validation message appears next to the field if the user hasn't entered a value. However, if the user is not on the first tab, it isn't obvious that the field is invalid.

In this case, I would like to show the first tab, but I'm not sure how to go about registering a callback for an 'invalid' event, if there is one.

I have also considered showing a validation summary above the tabs, which would be visible regardless of the tab the user is on, but my preference would be to take the user to the field.

I've tried looking through the jquery.validate.unobtrusive.js file, and it seems to extend jquery.validate.js. Looking at the documentation for jquery.validate, I see there is an invalidHandler option that can be passed to the validate method, but I don't know how to make use of this since that method is called by jquery.validation.unobtrusive.

I'm feeling a bit lost here, so any help would be appreciated!

Edit

I never figured out the answer, but did come up with a workaround, which I posted below. Still, I hope someone answers with a better way to do this.

like image 651
Jeff Ogata Avatar asked Mar 07 '11 23:03

Jeff Ogata


3 Answers

This code taken from here will do what you want:

<script type="text/javascript">
    $(document).ready(function () {
        $("#myForm").submit(function () {
            $("#tabs").tabs("select", $("#myForm .input-validation-error").closest(".ui-tabs-panel").get(0).id);
        });
    });
</script>

It'll take you to the the first tab that has an error. It's working great in a project I'm developing...

like image 179
Leniel Maccaferri Avatar answered Oct 02 '22 17:10

Leniel Maccaferri


I ended up validating and submitting the form manually:

$("#save-button").button().click(function() {
    if (!$("#profile-form").valid()) {
        if ($("#tabs").tabs("option", "selected") > 0) {
            $("#tabs").tabs("option", "selected", 0);
        }
        return false;
    }
    $("#profile-form").submit();
});
like image 30
Jeff Ogata Avatar answered Oct 02 '22 18:10

Jeff Ogata


Try adding a new adapter to Unobtrusive.

My markup looks different because I used Telerik instead of JQuery UI to create the tabs. Here's what my markup looked like after passing through Validator (ie, with validation errors inserted through the Unobtrusive script)

<div id="rItemTabs">

   <ul>
        <li><a href="#rItemTabs-1">Tab 1</a></li>
        <li><a href="#rItemTabs-2">Tab 2</a></li>
   </ul>
   <!-- End Tab Nav-->

   <!-- Begin Tab Contents -->
   <div id="rItemTabs-1">
       <div class="editor-label">
           <label for="Title">Title</label>
       </div>
       <div class="editor-field">
           <input id="Title" class="input-validation-error name="Title">
           <span class="field-validation-error">*</span>
       </div>
   </div> 

   <div id="rItemTabs-2">
       <div class="editor-label">
           <label for="Title">Title</label>
       </div>
       <div class="editor-field">
           <input id="Title" class="input-validation-error name="Title">
           <span class="field-validation-error">*</span>
       </div>
   </div>

</div> 

The goal of this script is to go through each div in "Tab Contents", look for the "field-validation-error" class (which should only exist if there is an error), and if this class was found change the color of the associated Tab Nav item (ie the id of the tab content is the same of the href of tab nav item).

$.validator.unobtrusive.adapters.add(
  'tab-validation',
   function () {
       var tabs = $('#rItemTabs [id*=rItemTabs]'); 
       $(tabs).each(function () {
       if ($(this).has('.field-validation-error').length) {
           var tabId = '#' + $(this).attr('id');
           $('a[href=' + tabId + ']').css({ 'color': 'red', 'font-weight': 'bolder' });
       }
   });
} (jQuery));

I hope this makes sense as well as works for you.

like image 23
RamboSantana Avatar answered Oct 02 '22 16:10

RamboSantana