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.22k stars 9.95k forks source link

When using StateHasChanged, the value is not reflected in the InputText #49069

Open UdhayaKumarDuraisamy opened 1 year ago

UdhayaKumarDuraisamy commented 1 year ago

Is there an existing issue for this?

Describe the bug

In the InputText component, when using StateHasChanged, the value change is not reflected in the UI of the InputText component.

<div style="margin:130px auto;width:300px">
    <div class="form-group">
        <label for="inputText">InputText:</label>
        <InputText id="inputText" class="form-control" Value="@InputText" ValueExpression="@(() => InputText)" ValueChanged="HandleValueChanged" />
    </div>
    Current InputText: @InputText
</div>

@code {

    public string InputText { get; set; } = "abc";

    protected void HandleValueChanged(string? args)
    {
        if (args != "test")
        {
            InputText = args;
        }
        else
        {
            StateHasChanged();
        }
    }
}

Expected Behavior

Expected Output: When using StateHasChanged, the value needs to be reflected in the input of the InputText also. Current Output: When using StateHasChanged, the value is not reflected in the input of the InputText .

Steps To Reproduce

  1. Run the Sample.
  2. Type “Example” and focus out.
  3. Now, The Values are updated properly in Both UI and ValueChanged event args.
  4. Type “test” and focus out.

Exceptions (if any)

No response

.NET Version

net7.0

Anything else?

No response

mkArtakMSFT commented 1 year ago

You should be able to do what you're trying to do using the bind syntax: https://learn.microsoft.com/aspnet/core/blazor/components/data-binding?view=aspnetcore-7.0#use-bindgetbindset-modifiers-and-avoid-event-handlers-for-two-way-data-binding

ghost commented 1 year ago

Hi @UdhayaKumarDuraisamy. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

UdhayaKumarDuraisamy commented 1 year ago

You should be able to do what you're trying to do using the bind syntax: https://learn.microsoft.com/aspnet/core/blazor/components/data-binding?view=aspnetcore-7.0#use-bindgetbindset-modifiers-and-avoid-event-handlers-for-two-way-data-binding

The solution above works for the native HTML input element, but it does not work for the Blazor InputText element. How can the above solution be used with the InputText element?

<p>
    <InputText @bind:event="oninput" @bind:get="inputValue" @bind:set="OnInput"></InputText>
</p>

<p>
    <code>inputValue</code>: @inputValue
</p>

@code {
    private string? inputValue;

    private void OnInput(string value)
    {
        var newValue = value ?? string.Empty;

        inputValue = newValue.Length > 4 ? "Long!" : newValue;
    }
}

image

Runaho commented 1 year ago

Hey @UdhayaKumarDuraisamy can you try this approach instead? Maybe you know that but you need to click somewhere other than the textbox to trigger it after typing.

<div style="margin:130px auto;width:300px">
    <div class="form-group">
        <label for="inputText">InputText:</label>
        <InputText class="form-control" @bind-Value="InputText" @bind-Value:after="HandleValueChanged" />
    </div>
    Current InputText: @InputText
</div>

@code {
    public string InputText { get; set; } = "abc";

    private void HandleValueChanged()
    {
        if (InputText == "test")
        {
            InputText = "";
        }
        StateHasChanged();
    }
}

After you try the one above, try this one, I recommend this one more. Since you use full property directly in this, you will not need to update the state.

<div>
    <div class="form-group">
        <label for="inputText">InputText:</label>
        <InputText class="form-control" @bind-Value="InputText" />
    </div>
    Current InputText: @InputText
</div>

@code {
    private string inputText = "abc";
    public string InputText
    {
        get { return inputText; }
        set
        {
            if (value != "test")
            {
                inputText = value;
            }
            else
            {
                inputText = "something different";
            }
        }
    }
}
YohapujaSelvakumaran commented 1 year ago

The solution works for replacing other text and an empty string, but it does not work for replacing the initial value when typing a test. I need to set the initial value to the input when typing a test.

<div style="margin:130px auto;width:300px">
    <div class="form-group">
        <label for="inputText">InputText:</label>
        <InputText class="form-control" @bind-Value="InputText" @bind-Value:after="HandleValueChanged" />
    </div>
    Current InputText: @InputText
</div>

@code {
    public string InputText { get; set; } = "abc";

    private void HandleValueChanged()
    {
        if (InputText == "test")
        {
            InputText = "abc";

        }
        StateHasChanged();
    }
}
ghost commented 11 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.

ghost commented 9 months ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.