dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.2k stars 9.94k forks source link

[Blazor] Value Bound to Input Element Not Reset by Reset-Type Button in Form #21179

Open TheFanatr opened 4 years ago

TheFanatr commented 4 years ago

Description

When using Blazor server to show a form with input elements that are bound to various values via @bind, if there is a button element with a type="reset" attribute inside that form, clicking on it will wipe the values from the form in the browser, but will not reset the values in Blazor, because the input elements' onreset events are not also resetting the bound values.

Reproduction

  1. Create a new Server-Side Blazor project, and change the TargetFramework in the project file to netcoreapp3.1 to match the following markup.
<TargetFramework>netcoreapp3.1<TargetFramework>
  1. Create a component routable to by the default router, and paste in the following code.
@page "/test"

<form>
    <input type="text" @bind="Value" @bind:event="oninput" />
    <br />
    <button type="reset">Reset</button>
</form>
<br />
Value: @Value

@code
{
    string Value { get; set; }
}
  1. Launch the project and navigate to the page that was made, then change the input in the form.
  2. Click the button containing the text Reset, and see that the input element's content was cleared, but the value bound to it was not changed, as evidenced by the fact that the section of the page showing the current value of the input-bound value, denoted by the text Value:, also remains unchanged.

Note that this behaviour is still observed with @bind:event="oninput" removed from the markup, but is there in the example so that the bound value updates in realtime, without the need to trigger the default change propagation event.

Possible Fix Idea

HTML input elements, as alluded to previously, have an onreset event, which could simply be given a delegate automatically by Blazor binding code generation tooling to reset the bound value.

Further technical details

Runtime Environment: OS Name: Windows OS Version: 10.0.18363 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\5.0.100-alpha1-015521\

Host (useful for support): Version: 5.0.0-alpha.1.19530.10 Commit: d7830341bb

.NET Core SDKs installed: 2.1.202 [C:\Program Files\dotnet\sdk] 2.1.802 [C:\Program Files\dotnet\sdk] 2.2.202 [C:\Program Files\dotnet\sdk] 3.0.100-preview8-013656 [C:\Program Files\dotnet\sdk] 3.0.101 [C:\Program Files\dotnet\sdk] 3.1.102 [C:\Program Files\dotnet\sdk] 3.1.201 [C:\Program Files\dotnet\sdk] 5.0.100-alpha1-015521 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed: Microsoft.AspNetCore.All 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0-preview7.19365.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0-preview8.19405.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0-preview9.19424.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0-rc1.19457.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.0-alpha1.19530.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.0-rc1-19456-20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.0-alpha.1.19530.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.0.0-preview7-27912-14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.0.0-preview8-28405-07 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.0.0-preview9-19423-09 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.0.0-rc1-19456-20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.0-alpha1.19530.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]


- IDE: Visual Studio Community 2019 Version 16.5.4
javiercn commented 4 years ago

I took a look at this issue and found the following:

Blazor will clear the field when the reset button is clicked but the value in the model will not be updated. When looking at other frameworks angular clears the field and updates the model value. With react, the opposite happens, clicking reset will not clear the field nor update the value.

I think the behavior in Blazor is not correct, since it leaves the UI out of sync from the component state, but we have two choices here:

mkArtakMSFT commented 4 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to happen for the coming release. We will reassess the backlog following the current release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.

nvmkpk commented 3 years ago

I ran into this issue as well. Is there a workaround? By the way I am using the form elements via InputXXX components and EditForm does not expose the reset event.

dag23 commented 3 years ago

As a workaround I put an @onclick event handler in the reset button and inside it I reset the object which is the model of the EditForm. For example you can create a new one or you can set the properties of the current object to default values.

msynk commented 1 year ago

it's been +3 years since this issue was submitted and I can confirm that this problem still exists. @javiercn any updates?

Are these changes in the EditForm.cs file a valid solution?

image

image

TheFanatr commented 1 year ago

It is a little insane that this issue has not been fixed in so long... has work on Blazor been deprioritized by Microsoft? Either way, I think one way to resolve this issue would be to set the values via event propagation on reset: you loop through all the relevant bound fields in the form in JS and do a Blazor-propagating set of the values to nothing; document.forms.form.querySelectorAll('*[name]').foreach(field => field.value = field.defaultValue) with edge cases, such as for checked. A way to facilitate more clear default values in Blazor to support auto-clearing, could be with binding extensions for the C# version of the "blank" value, and, as others suggested, for the reset event on some form element reference: <FoodContainer @bind=Model.Food @on-FormReference:reset='() => Model.Food = CheeseWhizz' @bind-Cooler=Model.Drinks bind-Cooler:blank=Coolable.Common.BudHeavy />. Please excuse the lax or incorrect/inconsistent Blazor syntax; aside: I dropped it when Microsoft seemingly gave up on it being eventually usable for native cross platform UI, because I wanted a React native competitor that actually uses platform bindings to do UI, like that ancient Xamarin WPF Blazor that you could use XAML markup or elements in, so I last used it eons ago.

ghost commented 9 months ago

Thanks for contacting us.

We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.