0

I have an editform with a large number of fields. If the user makes an error and attempts to submit the form, they must scroll manually to see the errors. With javascript, something like this could be done:

var element = document.getElementById("content");
element.scrollIntoView();

In blazor, I can use JS if I must but I don't necessarily have an ID to scroll to.

Is there a good way of scrolling to the first error in an editform on submit?

Mr.Technician
  • 301
  • 5
  • 15
  • See https://stackoverflow.com/questions/55186784/scroll-to-specified-part-of-page-when-clicking-top-navigation-link-in-blazor which I think will answer your question – MrC aka Shaun Curtis Jul 13 '21 at 20:01
  • That's a step in the right direction but it assumes I have a specific Id. I don't know the ID of the first element with an error in the edit form, if it even has an ID I can reference. – Mr.Technician Jul 13 '21 at 20:24
  • You specifically say "scroll to the top of the page to see the errors", so set an id for say a `` at the top of the page, or probably even the `EditForm`. If you want to scroll to the first error then that's a little more tricky! You'll need to give each `ValidationMessage` a convention based id, say "id-xxxxx" where xxxx is the parameter name, look up the error messages in the validation store, work out the validation message id from the `Field identifier` and go to the first one. – MrC aka Shaun Curtis Jul 13 '21 at 22:07
  • Oops! I meant "users must scroll to the top" to mean that users must perform that action manually (whether it is ALL the way to the top or just the first error). I'm using the MudBlazor library so I don't have traditional `ValidationMessages` as each textfield has built in validation support. I'll keep thinking about a way to make this work... – Mr.Technician Jul 14 '21 at 13:13
  • Did you resolve this? I am trying to do the same and was thinking I could call the javascript from OnInvalidSubmit using var element = document.getElementsByClassName("validation-message")[0] . The issue is that when the JS code is fired, the validation hasn't been rendered so element is null – Dave Feb 22 '22 at 11:28

1 Answers1

2

Here's how I accomplished it. I'm using OnInvalidSubmit on the EditForm. My ValidationMessage control adds the class 'validation-message' so I'm scrolling to the parent element of the first error message found, you may want to go an extra node up depending on your HTML.

I created a class for my Blazor page to inherit from

public class FormBase : ComponentBase
{
    [Inject]
    protected IJSRuntime JSRuntime { get; set; } = null!;

    internal async Task HandleInvalidSubmit()
    {
        await JSRuntime.InvokeVoidAsync("scrollToFirstError");
    }
}

Then inherit that in the razor page and add the OnInvalidSubmit to EditForm

@inherits FormBase

<EditForm EditContext="editContext" OnInvalidSubmit="@HandleInvalidSubmit">

My JavaScript is as follows. I added a 500ms delay so the page has time to add the error messages before getElementsByClassName is called

function scrollToFirstError() {

    delay(500).then(() => {

        var element = document.getElementsByClassName("validation-message")[0];
        if (element != null) {
            element.parentNode.scrollIntoView();
        }

    });
}

function delay(time) {
    return new Promise(resolve => setTimeout(resolve, time));
}
Dave
  • 439
  • 1
  • 4
  • 17
  • Thanks for the solution proposal. Suggestion for improvement: ```js ... var elements = document.getElementsByClassName("validation-message"); if (elements != undefined) { var element = elements[0]; if (element != null) { element.parentNode.scrollIntoView(); } } }); } ``` – rufer7 Apr 13 '22 at 09:29