MatBlazor icon indicating copy to clipboard operation
MatBlazor copied to clipboard

MatTextField bind-value:event="oninput" is not working

Open Frinen opened this issue 6 years ago • 12 comments

When I try to bind text field value to oninput event like this:

<MatTextField @bind-value="@Text" @bind-value:event="oninput" Label="Text" ></MatTextField>

It raises the runtime exception

System.InvalidOperationException: Unable to set property 'oninput' on object of type 'MatBlazor.MatTextField'. The error was: Specified cast is not valid. ---> System.InvalidCastException: Specified cast is not valid.

This approach works in MatBlazor 1.5.3, but when I update my project to preview 8 and MatBlazor 1.6.0 it starts to raise this exception. I suspect some changes in .net core preview 8 breaks this feature.

Frinen avatar Aug 15 '19 10:08 Frinen

Yes, I made example https://blazorfiddle.com/s/323p1kxs

But I think that this is bug of Blazor P8, tomorrow will check this problem again.

SamProf avatar Aug 15 '19 20:08 SamProf

Thanks for investigating this bug

I just want to share with you some things that I find out while testing this type of binding in MatTextField as well as in default HTML input.

First of all, this name of the event (OnInput) is case sensitive, so if you change that name to oninput in your example, it compile without error but crashes while rendering.

While testing this in <input type="text"> this type of binding works fine, check this example: https://blazorfiddle.com/s/w775usib However, if change event from oninput to OnInput it will compile just fine, but raise the runtime exception: Uncaught SyntaxError: Invalid or unexpected token

I hope that this will help you in some way.

Frinen avatar Aug 16 '19 08:08 Frinen

Hi! The problem is bigger then I expect before. Anyway I am really not sure that's it work before in MatTextField. Now, we have some restrictions of Blazor framework to resolve this problem. I create issue. Description is not so good, maybe if they don't undastand I will create another issue. https://github.com/aspnet/AspNetCore/issues/13192

SamProf avatar Aug 16 '19 17:08 SamProf

Found a workaround for my issue: <MatTextField Value="@YourInputValue" OnInput="@(e => YourInputValue = e.Value.ToString())" >

khenzar avatar Sep 20 '19 09:09 khenzar

Just to clarify, here is what worked for me implmenting search:

<MatTextField Value="@SearchTerm" OnInput="@(e => SearchTerm = e.Value.ToString())" @onkeyup="@GetResults" />

unencode avatar Oct 20 '19 03:10 unencode

My work around including debounce:

<MatTextField 
    @bind-Value="@SearchString"
    OnInput="@(e => SearchString = e.Value.ToString())" 
    OnKeyUp="@HandleKeyUp"
    ...
protected override void OnInitialized()
{
    DebounceTimer = new Timer(500);
    DebounceTimer.Elapsed += OnUserFinish;
    DebounceTimer.AutoReset = false;
}
protected IEnumerable<IId> SearchResults { set; get; } = Array.Empty<IId>().AsEnumerable();
protected string SearchString { set; get; } = "";

private Timer DebounceTimer ;
protected void HandleKeyUp()
{
    DebounceTimer.Stop();
    DebounceTimer.Start();
}
private void OnUserFinish(Object source, ElapsedEventArgs e)
{
    InvokeAsync( async () =>
    {
        SearchResults = await SearchDelegate(SearchString);
        StateHasChanged();
    });
}


ctrl-alt-d avatar Jan 10 '20 09:01 ctrl-alt-d

Can this be solved?

jakubmaguza avatar Jun 10 '20 18:06 jakubmaguza

My workaround is this:

Copy "MatTextField.cs" to your project as "MatTextFieldFix.cs".

Copy "MatInputTextComponent.razor" to your project as "MatInputTextComponentFix.razor".

Change in "MatTextFieldFix.cs": Inherit from MatInputTextComponentFix instead of MatInputTextComponent.

namespace MatBlazor
{
    /// <summary>
    /// Material Design Text Field for Blazor. Text fields allow users to input, edit, and select text.
    /// </summary>
    /// <typeparam name="TValue">string, sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, decimal?, DateTime, DateTime?, bool, bool?</typeparam>
    public class MatTextFieldFix<TValue> : MatInputTextComponentFix<TValue>
    {
    }
}

Change in "MatInputTextComponentFix.razor": Add using clause @using Microsoft.AspNetCore.Components.Web. In both textarea and input elements, remove oninput="@OnInput" and add @bind:event="oninput".

@using Microsoft.AspNetCore.Components.Web
@namespace MatBlazor
@typeparam T
@inherits BaseMatInputTextComponent<T>

<label class="@ClassMapper.AsString()" style="@StyleMapper.AsString()" @ref="Ref">

    @if (!Outlined)
    {
        <span class="mdc-text-field__ripple"></span>
    }

    @if (Icon != null && !IconTrailing)
    {
        <i class="material-icons mdc-text-field__icon mdc-text-field__icon--leading" tabindex="@(IconOnClick.HasDelegate ? "0" : null)" onclick="@IconOnClick">@Icon</i>
    }

    @if (TextArea)
    {
        <textarea style="@InputStyle" @ref="InputRef"  placeholder="@PlaceHolder" required=@Required class="@InputClassMapper.AsString()" id="@Id" @bind="@CurrentValueAsString" @bind:event="oninput" aria-label="@Label" @onkeydown="@OnKeyDownEvent()" onkeyup=@OnKeyUp onfocusout="@OnFocusOutEvent.Value" onkeypress="@OnKeyPress" onfocus="@OnFocusEvent.Value" disabled=@Disabled readonly="@InputTextReadOnly()" @attributes="Attributes" />
    }
    else
    {
        <input style="@InputStyle" @ref="InputRef" type="@Type" placeholder="@PlaceHolder" required=@Required class="@InputClassMapper.AsString()" id="@Id" @bind="@CurrentValueAsString" @bind:event="oninput" aria-label="@Label" @onkeydown="@OnKeyDownEvent()" onkeyup=@OnKeyUp [email protected] onkeypress="@OnKeyPress" onfocus="@OnFocusEvent.Value" disabled=@Disabled readonly="@InputTextReadOnly()" @attributes="Attributes"/>
    }


    @if (Icon != null && IconTrailing)
    {
        <i class="material-icons mdc-text-field__icon mdc-text-field__icon--trailing" tabindex="@(IconOnClick.HasDelegate ? "0" : null)" onclick="@IconOnClick">@Icon</i>
    }

    @if (!FullWidth && Outlined)
    {
        <div class="mdc-notched-outline">
            <span class="mdc-notched-outline__leading"></span>
            @if (Label != null)
            {
                <span class="mdc-notched-outline__notch">
                    <span class="@LabelClassMapper.AsString()" for="@Id">@Label</span>
                </span>
            }
            <div class="mdc-notched-outline__trailing"></div>
        </div>
    }
    else
    {
        if (Label != null)
        {
            <span class="@LabelClassMapper.AsString()" for="@Id">@Label</span>
        }
        <span class="mdc-line-ripple"></span>
    }

    @BuildRenderTreeChildContent()

</label>
@if (HelperText != null)
{
    <MatHelperText HelperTextPersistent="@HelperTextPersistent"
                   HelperTextValidation="@HelperTextValidation"
                   HelperText="@HelperText"/>
}

rpc-scandinavia avatar Oct 22 '20 20:10 rpc-scandinavia

Thank you all for your contributions/discussions on this thread. FWIW I have created my own variation here based on @ctrl-alt-d's post (with attribution) here: https://github.com/DragonSpark/Framework/blob/b28fd0fb34144d4d497a4e8a25e8045f10f0bce1/DragonSpark.Presentation/Components/Forms/TextInput.razor

Note that it is basically used to debounce a notification to the containing EditContext to update the field as modified.

Mike-E-angelo avatar May 07 '22 18:05 Mike-E-angelo

I had same problem. In new version you have to use this: Immediate="true". My problem has been solved by that. You can see more about that in this address

arashyazdani avatar Apr 08 '23 09:04 arashyazdani

I almost had trouble with this too @arashyazdani, but Mud != Mat :) This is a different control/project.

Mike-E-angelo avatar Apr 08 '23 09:04 Mike-E-angelo

Yes it's true. I'm sorry it was my mistake. ;)

arashyazdani avatar Apr 08 '23 10:04 arashyazdani