Change variable value on input key press on MudBlazor's MudTextField

2.5k Views Asked by At

I'm familiar with C#/asp.net mvc (10+ years) but new with Blazor (10days). Now I want to add a "Change variable value on input key press" effect to MudBlazor's TextField.

Thanks for information here Change variable value on input key press on Blazor, it's quite easy to deal with a normal input or textarea. Please see my code here:

<MudGrid>
    <MudItem lg="6">
        <MudInputLabel Style="z-index: 99;">@_localizer["Script"]</MudInputLabel>
        <textarea @bind="Script" @bind:event="oninput" cols="25" rows="10">@Script</textarea>
    </MudItem>
    <MudItem lg="6">
        <MudTextField T="string"
                      Label="@_localizer["New data sources identified from current script"]"
                      Variant="Variant.Outlined" ReadOnly="true"
                      Text="@DataSourceIdsTextFromScript" Lines="10"/>
    </MudItem>
</MudGrid>

When the value of the area (Script) is updated by @bind:event="oninput", CalculateDataSourceIdsTextFromScript() will update the value of DataSourceIdsTextFromScript, and the text in the second MudTextField will reflect the change.

    public string Script
    {
        get => _script;
        set
        {
            _script = value;
            CalculateDataSourceIdsTextFromScript();
        } 
    }

But when I tried to use a MudTextField instead of the textarea, bind-value / bind-text / OnInternalInputChanged could not do the same work.

        @* <MudTextField T="string" Label="@_localizer["Script"]" bind-Value="Script" *@
        @*               OnInternalInputChanged="CalculateDataSourceIdsTextFromScript" *@
        @*               Variant="Variant.Outlined" Text="@Script" Lines="10"/> *@

On the other hand, @bind:event="oninput" cannot be applied to a MudTextField. I think it's because MudTextField is not the input/textarea but a shell around it.

So, is there a way to do that?

Thanks for any answers or tips.

2

There are 2 best solutions below

1
On

While using a setter in a property is a perfectly valid option, Blazor is inherently asynchronous. Using a property setter ties you to the synchronous world.

You can implement async behaviour using the same pattern as used in the @bind-value:after used in the standard InputBase like this.

@page "/"

<PageTitle>Index</PageTitle>

<MudText Typo="Typo.h3" GutterBottom="true">Hello, MudTextField!</MudText>

<MudTextField T="string" Text="@_value" TextChanged="this.SetValueAsync" Immediate="true"/>

<MudText Class="mt-8">Value: @_value</MudText>

<MudText Class="mt-8">Result: @_result</MudText>

@code {

    private string? _value;
    private string? _result;

    private async Task SetValueAsync(string? value)
    {
        _value = value;
        await AfterSetValueAsync();
    }

    private async Task AfterSetValueAsync()
    {
        // fake async behaviour
        await Task.Yield();
        _result = $"Set at {DateTime.Now.ToLongTimeString()}";
    }
}
0
On

Incidentally, I found the answer here: https://www.mudblazor.com/components/textfield#immediate-vs-debounced.

Immediate="true" does the trick.

Some other usages can be found from the same page. Such as https://www.mudblazor.com/components/textfield#counter. It is just the same as my scenario.

Thanks everyone.