0

I have a form that is at the bottom of the page. When model validation failes on server side return Page() gets me back to the top of the page and that is very inconvenient because the user has to scroll down to the form to see the validation errors. My questions are: 1. Can I redirect to contact form div ID? 2. The best scenario would be if model validation can be done asynchronously so there would be only partial page refresh. Is that possible? (that was done easily in Web Forms with UpdatePanel).

I appreciate any information you might share.

Jacob

Jacob_Zac
  • 83
  • 1
  • 1
  • 7

3 Answers3

1

First of all try to validate on the client first to prevent unnecessary postbacks. You can use attributes to set validation:

using System.ComponentModel.DataAnnotations;

public class ForgotPasswordViewModel()
{
    [Required]
    [EmailAddress]
    public string Email { get; set; }
}

In the view check the Modelstate:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
    if (ModelState.IsValid)
    {

Of course client side isn't enough, so in case the client side validation is skipped the server makes sure that the model validates.

One way to scroll to a position is to use an anchor. The anchor is a client side way to bookmark parts in the document. Normally you would see something like this:

<a href"home#contact">Contact</a>

By clicking the link you would scroll to the contact bookmark in the home document. You can do the same for the post:

<div id="contact">
    <form method="post" action="home#contact">
        @Html.AntiForgeryToken()

    </form>
</div>

In case of an error the page will automatically scroll to the form, since on the client the #contact hash was set. The assumption is that in case of success you redirect to another view. This is afaik the only way to scroll without the use of javascript. And since javascript validation didn't work...

Please note that with .Net Core AntiForgery is added automatically if you use the tag helper. But since I didn't use it I have to add this myself.

There are other options that involve javascript or some server side redirection, but I think this is an easy solution.

I do not know if partial page refresh is the best solution. I think it depends. There are plenty of examples available on how you can post asynchronous. Check this link: https://www.w3schools.com/jquery/ajax_ajax.asp

  • Ruard thanks for all the info. I have tried to put action="home#contact" but it is not working (page opens with error "This page isn’t working"). After the error, when I press enter on the url in the address bar the contact form is displayed. – Jacob_Zac Jan 02 '18 at 12:15
  • Perhaps the action path is not correct, because the hash doesn't do anything actually. It is just something in the browser, it isn't send to the server. I've implemented this myself and I can confirm that this works. –  Jan 02 '18 at 14:40
  • Again thanks for all the help. I am using the solution that I have posted here. – Jacob_Zac Jan 02 '18 at 17:20
1

Maybe remote validation?

"Remote validation is a great feature to use when you need to validate data on the client against data on the server. For example, your app may need to verify whether an email or user name is already in use..." https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation

Jones
  • 375
  • 1
  • 4
  • 14
0

I have found solution that works fine for me:

@if (Model.validationError)
    {
        <text>
        document.getElementById('contact').scrollIntoView();
        </text>

    }
Jacob_Zac
  • 83
  • 1
  • 1
  • 7