简体   繁体   中英

How to use asp.net mvc 3 unobtrusive javascript validation with a wizard?

I am using asp.net mvc 3 and want to make use of unobtrusive javascript . I am desiging a form that is quite long and probably would be very overwhelming if not broken up.

I decided to use jquery form wizard to break it into a wizard that should not look so overwhelming. I am not wondering how do I use the data annotations and unobtrusive java-script with wizard.

Right now everything is still in one big form but just looks broken up through the wizard. There is only one submit button at the end of the form that when clicked will serialize the form data and do an ajax post to the server with that data.

From what I seen usually for the first time when using the mvc validation the user needs to click the submit button before any of the client side validation gets trigger. I am wondering if it is possible to do it once they leave the field as it going to confuse the user once they hit submit and nothing happens and then they have to go through the entire wizard again to find the validation errors.

It would be nice to inform them right away when they make a mistake.

I know that jquery wizard using the jquery form plugin that has validation but I rather try to stick with one method if possible to keep the code consistent.

Edit

This is what I have on the submit button

$('#frm').live('submit', function (event) {
    event.preventDefault();

    var $thisFrm = $(this);

    ValidatorParse($thisFrm);//jQuery.validator.unobtrusive.parse(selector);
    var clientCheck = $($thisFrm).validate().form();

    if (clientCheck) {
       // ajax post(server side validation will happen.If it does not pass serverside I send it back usually as json).
    }
});

So I see a couple problems with this. First the validation only will really get triggered on submit. If it gets triggered and the validation error is on the second wizard step the user won't see it(unless some how can figure out way to find the first wrong validation error and switch them to that step).

The second problem I see is that they have to wait till the end to see if they have validation errors. I rather let them know asap.

Edit

It seems the wizard uses jquery validate but for some reason it is not working with mvc jquery validate way.

With more investigation I found that the wizard needs to see "required" as a class to trigger

// will trigger validation
<input type="text" value="" name="AnnualFee" id="AnnualFee"
    data-val-required="Annual Fee Required" 
    data-val="true" 
    class="required ui-wizard-content ui-helper-reset ui-state-default error">

// will not trigger validation
    <input type="text" value="" name="AnnualFee" id="AnnualFee" 
    data-val-required="Annual Fee Required" 
    data-val="true" 
    class="ui-wizard-content ui-helper-reset ui-state-default">

I don't see in the documentation for jquery validate them ever using the class to validate the form. Is this something the person made up?

You shouldn't need any extra javascript code on your submit button when using the jquery form wizard (except of course it initialization).

The unobstrusive part of Microsoft MVC3 just do a boring work of transform all "data-*" attributes marked on your html input (eg data-val-required="blah blah blah") to a well-known rules of jquery-validation. This is done before we think to validate a form!

So, the RequiredValidationAttribute and friends (your custom validations, etc) on your Models are enough to start.

Try this (if you already didn't):

  1. Take your full-form, and slice it on "divs" with a class step , where each div is a step (I think this part you already did).
  2. Your submit and back button must be:

    input class="navigation_button" id="back" type="reset" value="Back"

    input class="navigation_button" id="next" type="submit" value="Next"

  3. Initialize your formwizard

     $(document).ready(function () { $("form").formwizard({ formPluginEnabled: true, validationEnabled: true, focusFirstInput : true }); }); 

The formwizard will take care of call the validation for each step of your wizard.

Before writing this, I made myself an example form to prove that it works.

Hope it helps, or sorry if I got your problem wrong.

My team and I routinely create wizards and have an independent solution in terms of it not relying on a specific technology approach on the server-side. Some "wizards" are checkout flows where you have a single page that has many steps in terms of checking out. I've done these on 100K + website development efforts with high traffic through my company.

We use c# MVC, c# razor matrix-style, node.js, php and python so far. We take a general approach and we can reuse this across out technologies. Our approach is MVC-like in the way it very strictly separates HTML, CSS and JavaScript.

It goes like so:

  1. We create a single page that only contains markup and links to CSS and scripts. We never place inline styles or inline script other than data attribute configuration within the form elements that are HTML5 compatible and HTML5 form compatible etc. We use JavaScript that conforms to HTLM 5 standards for form validation even if not supported. We hve our own libraries but you can use jQuery tools or similar.
  2. You have a main.css file and a main.js file that will run the overall reusable style and logic. Think of these as the composers managing the entire flow.
  3. For each step in the wizard, create separate css and javascript that is specific for each step.
  4. namespace your steps in your css so that its very specific.
  5. Use jQuery to run your validation and namespace the selectors similar to how you use the CSS approach so you attach events specifically to where they should reside.

So you end up with a very clean separation of concerns that works for any technology. In your case, you can take it further and create partial views in MVC for each step and compartmentalize them that way as they can load in their own CSS and JavaScript for their respective step.

In my profile you can see websites using this methodology in the checkout.

I don't actually consider this a complete answer and would need more feedback to flesh it out from you.

I used it like this

function ValidateStep(){
    var validator = $("form").validate(); // obtain validator
    var anyError = false;
    if (!validator.element(this)) { // validate every input element inside this step
       anyError = true;
    }
    if(anyError) return false;
    return true;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM