I have one ViewModel which has 8 properties and 6 of them are complex types. And I must display them in 3 groups and to save all data to database at last. Now, I have created two methods for this purpose, the first will be decorated with HttpGet and the second one with HttpPost. I have already created all these 3 groups in one .cshtml. For the first time, only the first group is visible. And after clicking NEXT button, I will make the second group visible and the first group will be invisible with the help of Javascript/Jquery. And then the third group will be visible. And in this last part submit button must be appeared. After clicking this, I will post whole model back to the action method. But, in this scenario I have two problems:
So, for solving these problems, I have decided two create four action methods, which will post viewmodel back to other one. For making it clear, I want to show this like that:
[HttpGet][HttpPost][HttpPost][HttpPost]1 will return my viewmodel instance to 2, and 2 in his turn will post it to 3, and 3 will post it to 4.
Is it good aproach? If not, what would you recommend me?
Your current approach means multiple post/redirects and some form of temporary repository or something that mimics viewstate. A better approach would be to do everyting within one form and validate individual controls in each section using Validator.element(element)
In the Next button .click() event
<section> - e.g. var controls = $(this).closest('section').find('input, textarea, select');$.each loop, call $('form').validate().element($(this));$(this).valid();The final section includes the 'Save'` button which does a normal submit
View
<section>
<h2>Section 1</h2>
@Html.LabelFor(m => m.SomeProperty)
@Html.TextBoxFor(m => m.SomeProperty)
@Html.ValidationMessageFor(m => m.SomeProperty)
....
<div class="error"></div>
<button type="button" class="next">Next</button>
</section>
<section>
<h2>Section 2</h2>
// Your inputs and validation
<div class="error"></div>
<button type="button" class="next">Next</button>
<section>
<section>
<h2>Section 3</h2>
// Your inputs and validation
<div class="error"></div>
<button type="submit" class="next">Submit</button> // submit button for last section
</section>
css (hide all but the first section)
section:not(:first-of-type) {
display:none;
}
Script
$('button').click(function () {
var container = $(this).closest('section');
var isValid = true;
$.each(container.find('input'), function () { // include select, textarea as required
$('form').validate().element($(this));
if (!$(this).valid()) {
isValid = false;
return false;
}
});
if (isValid) {
container.next('.section').show().find('input').first().focus();
container.hide();
} else {
container.find('.error').text('please complete');
}
});
This will address all client side validation without the need for multiple posts/redirects. As for what happens in the rare instance of having to return the view because the model is still invalid (the error message(s) will be generated but could be in a hidden section so not initially visible)
$('span.field-validation-error) and the unhide the associated
parent section(s)If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With