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.37k stars 9.99k forks source link

Blazor WASM: Components inside an EditForm do not set the EditContext.IsModified() to true when modified #25997

Closed brettwinters closed 4 years ago

brettwinters commented 4 years ago

Describe the bug

Components which are modified inside an EditForm do not set the EditForm's EditContext to IsModified() == true

To Reproduce

I have a more complex scenario, but I think this is the minimum:

index

<EditForm Model="Person" OnValidSubmit="@(() => Console.WriteLine("Form submitted"))">

    <InputText @bind-Value="Person.Name"></InputText>

    <DescriptionComponent @bind-Description="@Person.Description"></DescriptionComponent>

    <p>"All " + @context.IsModified()</p>
    <p>"Name " + @context.IsModified(() => Person.Name)</p>
    <p>"Description" + @context.IsModified(() => Person.Description)</p>
</EditForm>

@code
{
    Person Person { get; set; } = new Person { Name = "One", Description = "Two" };
}

Description component

<input type="text" value="@Description" @onchange="@(async e => await DescriptionChanged.InvokeAsync(e.Value.ToString()))" />
@code
{
    [Parameter] public string Description{ get; set; }
    [Parameter] public EventCallback<string> DescriptionChanged { get; set; }
}
public class Person
{
    public string Name { get; set; }

    public string Description{ get; set; }
}

Results: Changing name -> context.IsModified() and context.IsModified(() => Person.Name) are true Changing Description -> neither context.IsModified() nor context.IsModified(() => Person.Description) are true. But in the html, the "modified" css added successfully to the <input>

For good measure also tried setting the [CascadingParameter] EditContext's NotifyFieldChanged from within the component

Further technical details

brettwinters commented 4 years ago

Drilling down into the source code, I've realised that there is a huge amount of validation-centric code in the InputBase. After inheriting from that, the issue seems to be solved.