The Post View instance will fall back to multiple action methods

I have one ViewModel

that has 8 properties and 6 of them are complex types. And I have to display them in 3 groups and finally save all data in the database. Now I have created two methods for this: the first will be decorated HttpGet

and the second will be 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 the NEXT button, I will make the second group visible and the first group will be invisible using Javascript / JQuery . And then the third group will be visible. And in this last part, the submit button should appear. After that, I'll send the entire model back to the action method. But in this case, I have two problems:

  • I have to validate only visible fields with client side validation
  • If somehow client-side validation passed but server-side validation did not, then I have to find and display the unchecked part.

So, to solve these problems, I decided that two would create four action methods that would return the viewmodel back to the other. For clarification, I want to show it like this:

  • CreateViewModel [HttpGet]

  • GoToSecondPart [HttpPost]

  • GoToThirdPart [HttpPost]

  • SaveToDatabase [HttpPost]

1 will set my viewmodel instance back to 2, and 2 in turn will post it to 3 and 3 will send it to 4.

Is it good? If not, what would you recommend me?

+3


source to share


2 answers


Your current approach means multiple post / redirects and some form of temporary repository or something that mimics the viewstate. A better approach would be to do everything in one form and validate the individual controls in each section using Validator.element (element)

In the next button, the .click()

event

  • Select all controls in the appropriate <section>

    - eg.var controls = $(this).closest('section').find('input, textarea, select');

  • In a loop, $.each

    call$('form').validate().element($(this));

  • Check if the controls in the section $(this).valid();

  • If everything is correct, hide the current section and display the next

The final section contains a "Save" button that performs a normal transfer

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 everything except 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 validate the entire client side without the need for multiple messages / redirects. As for what happens in the rare case that a view needs to be returned because the model is still invalid (an error message will be generated, but might be in a hidden section, so not initially visible)

  • Just let the user go through the "wizard" again (maybe confusing if the error is not visible in the first section)
  • Use jquery to find the generated error (s) for example $('span.field-validation-error)

    as well as the parent section (s)
+1


source


It seems to me that you are trying to create a wizard. It would be easier to split your pages into subpages using the same view model, but only displaying the fields that are required for that page (throw the rest into hidden fields to preserve the data). You can then make AJAX callbacks to the controller to display the next / previous pages, which will prevent the screen from flickering so that it looks like the page hasn't changed.



-1


source







All Articles