MatBlazor
MatBlazor copied to clipboard
MatTextField bind-value:event="oninput" is not working
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.
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.
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.
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
Found a workaround for my issue:
<MatTextField Value="@YourInputValue" OnInput="@(e => YourInputValue = e.Value.ToString())" >
Just to clarify, here is what worked for me implmenting search:
<MatTextField Value="@SearchTerm" OnInput="@(e => SearchTerm = e.Value.ToString())" @onkeyup="@GetResults" />
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();
});
}
Can this be solved?
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"/>
}
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.
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
I almost had trouble with this too @arashyazdani, but Mud != Mat :) This is a different control/project.
Yes it's true. I'm sorry it was my mistake. ;)