Show partial mvc view with errors on parent page

I have a page with several forms, each of which is partial. I want to publish each part in submit. If there are errors, I want the verification errors to appear in a partial part of the main page, i.e. I do not want to just see a partial page on my own page if there are errors. Am I saying correctly that this behavior is only possible with an ajax message? How can I return model state errors WITHOUT ajax post, just a normal form message?

Edit: Still seeing partial on your page

Partial -

@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "LoginForm" })) { @Html.ValidationMessage("InvalidUserNamePassword") <fieldset class="fieldset"> <div> <label for="form-field-user_id">User ID</label> <span> @Html.TextBoxFor(x => x.Username, new { @class = "form-field__input form-field__input--text", @id = "form-field-user_id"}) </span> </div> </fieldset> <div class="form-field__button"> <button id="loginButton" type="submit" class="button button--primary">Login</button> </div> } <script> $('#loginButton').click(function () { $.ajax({ type: "POST", url: '@Url.Action("Login", "Account")', data: $('form').serialize(), success: function (result) { if (result.redirectTo) { window.location.href = result.redirectTo; } else { $("#LoginForm").html(result); } }, error: function () { $("#LoginForm").html(result); } }); }); </script> 

Controller -

 [HttpPost] public ActionResult Login(LoginModel model) { if (!ModelState.IsValid) { return PartialView("~/Views/Account/_Login.cshtml", model); } return Json(new { redirectTo = Url.Action("Index", "Profile") }); } 
+5
source share
1 answer

Yes, you are correct in saying that this behavior is only possible with ajax message.

There are several problems with the current script, meaning that you will not get the desired results.

Firstly, your button is a submit button, meaning that it will give a regular gift in addition to calling ajax if you do not cancel the default event (by adding return false; as the last line of code in the script). However, it would be easier to just change the button type="button" to type="button"

 <button id="loginButton" type="button" class="button button--primary">Login</button> 

Now ajax call will refresh the existing page, however, it will add the returned fragment inside the existing <form> element, as a result of which the nested forms will be invalid html and will not be supported. Change the html to wrap the shape of the main views in another element

 <div id="LoginFormContainer"> @using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "LoginForm" })) { .... <button id="loginButton" type="button" class="button button--primary">Login</button> } </div> 

and then change the script to update the html of the outer element

 success: function (result) { if (result.redirectTo) { window.location.href = result.redirectTo; } else { $("#LoginFormContainer").html(result); // modify } }, 

Finally, your rendering of dynamic content, so client-side validation will not work for the returned form. Assuming your properties have validation attributes (for example, the [Required] attribute in the Userame property), you need to reprocess the validator after loading the content

 var form = $('#LoginForm'); .... } else { $("#LoginFormContainer").html(result); // reparse validator form.data('validator', null); $.validator.unobtrusive.parse(form); } 

You noted that there are several forms on the page, in which case your ajax options should be

 data: $('#LoginForm').serialize(), 

or if you declare var form = $('#LoginForm'); according to the snippet above, then data: form.serialize(), , to make sure you serialize the correct form.

Side note: there is no real need to change the id attribute of the text field (by default it will be id=Username" , and you can just use

 @Html.LabelFor(x => x.UserName, "User ID") @Html.TextBoxFor(x => x.Username, new { @class = "form-field__input form-field__input--text" }) 

or just @Html.LabelFor(x => x.UserName) properties embellished [Display(Name = "User ID")]

+5
source

Source: https://habr.com/ru/post/1232562/


All Articles