user3378165 user3378165 - 2 months ago 10
C# Question

One big form with a few steps -Validation issue

I have a MVC Order Form that has 4 steps in it.

The user clicks on "NEXT" on the first step -> the second steps opens etc...

On my View Model I have one object that is composed from all the fields of all the 4 forms.

How can I on the forth form, on submit, to post to the server the data of all the 4 forms?

I did it this way (4 forms) for validation purpose, so I can validate each form before moving to the next step.

I show/hide the forms with jquery.

My Order View (example without design etc..)

<div>
<form id="formStep1">
<label>First Name</label>
<input type="text" name="sellerFirstName" class="required" />
<label>Last Name</label>
<input type="text" name="sellerLastName" class="required" />
<button id="submitStep1">Next</button>
</form>
<form id="formStep2">
<label>Address</label>
<input type="text" class="required" name="propertyAddress" />
<label>City</label>
<input type="text" class="required" name="propertyCity" />
<label>State</label>
<input type="text" class="required" name="propertyState" />
<button type="submit" class="orderf02" id="submitStep2">Next</button>
</form>
<form id="formStep3">
<label>First Name</label>
<input type="text" name="buyerFirstName" class="required" />
<label>Last Name</label>
<input type="text" name="buyerLastName" class="required" />
<button type="submit" class="orderf02" id="submitStep3">Next</button>
</form>
<form id="formStep4" method="POST" action="Order/SubmitOrder">
<input type="file" id="file1">
<input type="text" id="file1text" />
<button class="orderf02" type="submit" id="submitStep4">SUBMIT</button>
</form>




My Order object:

public class Order
{
//First Step
public string sellerFirstName { get; set; }
public string sellerMiddleName { get; set; }

//Second Step
public string propertyAddress { get; set; }
public string propertyCity { get; set; }
public string propertyState { get; set; }

//Third Step
public string buyerFirstName { get; set; }
public string buyerLastName { get; set; }

//Forth Step
public HttpPostedFileBase file1 { get; set; }
public string file1text { get; set; }
}

Answer

For that purpose you need to create one form add inputs for different steps into different containers (for example div), then navigate between those containers using JavaScript or jQuery and post in the end. To solve your validation problem add function which validates specific container:

// Validate every input element inside div.
// Return false if any element fails validation.
function validateElementsInsideContainer(container, validator) {
    var isCurrentDivValid = true;

    if (container && validator) {
        $(container).find("input").each(function () {
            if (!validator.element($(this))) {
                isCurrentDivValid = false;
            }
        });
    }

    return isCurrentDivValid;
}

Then call this function for containers on each step change and navigate only if valid:

var validator = $("form").validate();

function toSecondStep() {
    var firstStep = $("#first-step");
    var secondStep = $("#second-step");

    // Validate
    var isValid = validateElementsInsideContainer(firstStep, validator);

    if(isValid) {
        firstStep.hide();
        secondStep.show();
    }
}

Update:

The main method here is validator.element(). You can pass whatever input you want and it will validate it. For example, if you want to validate according to some filter you can do it as well. Add function similar to validateElementsInsideContainer like below:

function validateSpecificElements(elements, validator) {
    var elementsAreValid = true;

    if (elements && validator) {
        $(elements).each(function () {
            if (!validator.element($(this))) {
                elementsAreValid = false;
            }
        });
    }

    return elementsAreValid;
}

Then you can select inputs according to what you want and validate them:

var validator = $("form").validate();

function toSecondStep() {
    var firstStep = $("#first-step");
    var secondStep = $("#second-step");

    // Get elements to validate
    var elementsToValidate = $("form").find(".sepcific-element-class");     
    var isValid = validateSpecificElements(elementsToValidate, validator);

    if(isValid) {
        firstStep.hide();
        secondStep.show();
    }
}
Comments