Rockford Lhotka

VP, Open Source Creator, Author, Speaker

Blazor EditForm OnSubmit behavior

12 Dec 2024

I am working on the open-source KidsIdKit app and have encountered some “interesting” behavior with the EditForm component and how buttons trigger the OnSubmit event.

An EditForm is declared similar to this:

    <EditForm Model="CurrentChild" OnSubmit="SaveData">

I would expect that any button component with type="submit" would trigger the OnSubmit handler.

<button class="btn btn-primary" type="submit">Save</button>

I would also expect that any button component without type="submit" would not trigger the OnSubmit handler.

<button class="btn btn-secondary" @onclick="CancelChoice">Cancel</button>

I’d think this was true especially if that second button was in a nested component, so it isn’t even in the EditForm directly, but is actually in its own component, and it uses an EventCallback to tell the parent component that the button was clicked.

Actual Results

In Blazor 8 I see different behaviors between MAUI Hybrid and Blazor WebAssembly hosts.

In a Blazor WebAssembly (web) scenario, my expectations are met. The secondary button in the sub-component does not cause EditForm to submit.

In a MAUI Hybrid scenario however, the secondary button in the sub-component does cause EditForm to submit.

I also tried this using the new Blazor 9 MAUI Hybrid plus Web template - though in this case the web version is Blazor server.

In my Blazor 9 scenarios, in both hosting cases the secondary button triggers the submit of the EditForm - even though the secondary button is in a sub-component (its own .razor file)!

What I’m getting out of this is that we must assume that any button, even if it is in a nested component, will trigger the OnSubmit event of an EditForm.

Nasty!

Solution

The solution (thanks to @jeffhandley) is to add type="button" to all non-submit button components.

It turns out that the default HTML for <button /> is type="submit", so if you don’t override that value, then all buttons trigger a submit.

What this means is that I could shorten my actual submit button:

<button class="btn btn-primary">Save</button>

I probably won’t do this though, as being explicit probably increases readability.

And I absolutely must be explicit with all my other buttons:

<button type="button" class="btn btn-secondary" @onclick="CancelChoice">Cancel</button>

This prevents the other buttons (even in nested Razor components) from accidentally triggering the submit behavior in the EditForm component.