Search code examples
asp.net-mvcrazormodel-validationasp.net-mvc-validation

ASP.NET MVC handling server side validation on jQuery form wizard/tabs


I'm working on a large form that I'm looking to improve the usability of by sectioning it into a jQuery form wizard (jQuery tabbed panels).

I have already implemented both client-side validation and server-side validation. Client side validation is performed on each tabbed panel before moving to the next tabbed panel and server side validation is only performed once the form is posted to the server.

The thing I'm having trouble with is how to best handle server-side validation errors. Currently if the form is posted to the server it returns the form and shows any errors however this doesn't really work to well with jQuery tabbed panels as the tabbed panel resets to its default state once the form is returned.

If the form fails server side validation how do I reload the form and automatically show the tabbed panel in which the inputs that failed server side validation reside. For example, lets say I have three tabbed panels in my form wizard. If an input in the third tabbed panel failed server side validation how do I reload the form with the third tabbed panel shown.

I have tried creating the from wizard server-side where each section has its own view and controller action however however with this approach it much harder to create a navigation bar to move between the form section.


Solution

  • I had a similar issue and i used following solution:

    Post form data via jquery ajax

    $("#save").on("click", function (e) {
          //clear error if exists before
          var $form = $("#saveform");          
          $.post($form.attr("action"), $form.serialize(), function(result) {
             if (result.ok) {
                //handle success
             } else {
                handleError($form, result);
             }
          });
    });
    

    Validate data in the server side and send json result to the client(ok or errors).

    if (ModelState.IsValid)
    {
       return Json(new {ok = true});
    }
    else
    {
       return Json(new {ok = false, errors= ModelState.Values.SelectMany(x => x.Errors)});
    }
    

    Handle result in client side(if has any error show in the form and activate tab)

    function handleError($form, result) {
        for (var i = 0; i < result.errors.length; i++) {
            var item = result.errors[i];
            for (var j = 0; j < item.MemberNames.length; j++) {
                var input = $form.find("[name=" + item.MemberNames[j] + "]");
                var tab= input.closest(".tab");
                tab.addClass("active");
                //show error(near the input or in summary)
            }
        }
    }