fluentui-blazor icon indicating copy to clipboard operation
fluentui-blazor copied to clipboard

fix: FluentTextEdit does not update bound value prior to Form onValidSubmit.

Open StevenTCramer opened this issue 1 year ago • 4 comments

🐛 Bug Report

When submitting a form via "Enter" in a FluentTextEdit the value is NOT updated before Submit.

This is the result using FluentTextEdit image

This is the result with InputText

image

💻 Repro or Code Sample

<h3>Form Example</h3>

<EditForm Model="@Example" OnValidSubmit="@HandleValidSubmit">
  <FluentStack Orientation=Orientation.Vertical>
    <FluentTextField
      @bind-Value=Example.Name
      Name=@nameof(Example.Name)
      Placeholder="Fluent Control"
      Appearance=FluentInputAppearance.Filled
    />
    <InputText @bind-Value=Example.Name />
    <FluentButton
      Appearance=Appearance.Accent
      Title="Submit"
      Type=ButtonType.Submit>Submit</FluentButton>
  </FluentStack>
</EditForm>
<div>ExampleModel.Name:@Example.Name</div>
<p>SubmitDetails: @SubmitDetails</p>

@code {
    private readonly TExample Example = new();
    private string SubmitDetails = "None";
  
    private void HandleValidSubmit()
    {
      SubmitDetails = $"Form submitted with name: {Example.Name}";
    }
  
    public class TExample
    {
      public string? Name { get; set; }
    }
  }

🤔 Expected Behavior

It should behave just like InputText

😯 Current Behavior

See Screen shot above.

💁 Possible Solution

I have looked and I can't figure out how InputText actually works, thus I can't fix FluentTextField.

Adding a yield seems to solve the problem so it likely is related to aysnc await somehow.

private async Task HandleValidSubmit()
  {
    await Task.Yield();
    SubmitDetails = $"Form submitted with name: {Example.Name}";
  }

🔦 Context

All of the current Search forms require pressing enter twice. I have 5 different bugs reported currently and likely they just have not reported others. I could run off a custom build if I could figure out the solution until the next release.

🌍 Your Environment

  • FluentUI Running on git commit 1630f24ccef093ef84d8664f036fe9a29ab7ff4f
  • Window 11
  • Microsoft Edge
  • dotnet --version 8.0.400-preview.0.24324.5

StevenTCramer avatar Aug 18 '24 16:08 StevenTCramer

Task.Yield() doesn't always work. I guess next work around is some Task.Delay but obviously a hack.

StevenTCramer avatar Aug 22 '24 11:08 StevenTCramer

Think this is a problem with the underlying web component like the ones we have in #1085 and #1050. Input text uses HTML input internally, where w use fluent-text-field internally (which uses input in its shadow DOM), so I dont think comparing them is going to help a lot. This is one that is most probably blocked until we get the new v3 web components.

vnbaaij avatar Aug 22 '24 20:08 vnbaaij

@vnbaaij This seems like a pretty serious bug. Can it be fixed in the current version?

mrpmorris avatar Aug 29 '24 10:08 mrpmorris

What seems to (reliably) solve it for me (with the current web components) is to add a delay:

 private async Task HandleValidSubmitAsync()
 {
     await Task.Delay(4);
     SubmitDetails = $"Form submitted with name: {Example.Name}";
 }

Why is a delay needed? Because the Button web component needs to have something that is called an attached connected proxy. If it is not attached (which it isn't in our case, don't know why), the script will do that and that (apparently) takes time. If you're interested, look at lines 7240-7254 of the web-components.js script in the dev tools.

Why 4 ms? Because a shorter delay does not always get the desired result.

Yes, this will make your application 'slower'. Yes, this is not ideal. And yes, we would like to see it solved in the web components itself, but alas we need to deal with what we have now.

Please try the change I mentioned and let me know if it solves the issue for you as well. I tested in both Client and Server versions of the demo site on .NET 8 and .NET 9 preview (we target that one as well starting the with upcoming 4.10 release).

vnbaaij avatar Aug 29 '24 12:08 vnbaaij

An alternative (which I'm trying to get working but failing currently) would be to make the binding run oninput rather than onchanged. Then every time you make a change to the value it will update the binding.

MatthewSteeples avatar Sep 01 '24 00:09 MatthewSteeples

An alternative (which I'm trying to get working but failing currently) would be to make the binding run oninput rather than onchanged. Then every time you make a change to the value it will update the binding.

You can already do that yourself by using the Immediate and ImmediateDelay parameters

vnbaaij avatar Sep 01 '24 06:09 vnbaaij

@StevenTCramer Steven, can you validate if the described solution/work around works for you as well? We want to release an update soon and it would be great if we know this is taken care of. Thanks.

vnbaaij avatar Sep 02 '24 12:09 vnbaaij

Why Delay(4) and not 3 or 5? Is that what works on your machine or is it definitely also suitable for old slower machines too?

mrpmorris avatar Sep 03 '24 08:09 mrpmorris

Well, I have only my machine to test on. That is why I asked for Steven to test as well. If you and others can do too and report back here, that would help to give me more/better insights.

My guess is though that this is going to be enough for older and slower machines too. Besides, difference between 3 or 4 is 1 thousand of a second of difference. Probably only means the app needs to wait wait for your input a tiny bit slower.

vnbaaij avatar Sep 03 '24 10:09 vnbaaij

@StevenTCramer Steven, can you validate if the described solution/work around works for you as well? We want to release an update soon and it would be great if we know this is taken care of. Thanks.

I used Delay(10) on the app we just put in production. But obviously it may not always work.

StevenTCramer avatar Sep 06 '24 04:09 StevenTCramer

So, conclusion is that adding a Delay 'fixes' this.

It is just a matter of finding find the correct amount depending on your app and environment.

I'm going to close this one then as we will not see an other fix through the web components side.

vnbaaij avatar Sep 06 '24 07:09 vnbaaij

@vnbaaij My point really was that there is no way to know the correct number. 5 might work on yours, 10 on Steve's, I might need 20 on mine, someone on an old machine might need 50 or 100.

Then you end up lagging the UI to ensure the slowest machine out there works - which suggests this is not the correct fix.

mrpmorris avatar Dec 31 '24 16:12 mrpmorris

A correct fix would be implemented in the web components. But as v2 is not being maintained anymore, this is what we have to do with till we components v3/Fluent UI Blazor v5

vnbaaij avatar Dec 31 '24 16:12 vnbaaij