Suppose I want to use an EditForm, but I want the value binding to trigger every time the user types into the control instead of just on blur. Suppose, for the sake of an ex
Alright, I've figured this out after poking around the source code looking particularly at properties CurrentValueAsString and CurrentValue. This is the solution I've come up with for making a text input that properly fires field changed events oninput:
public class InputTextCode : InputBase<string>
{
protected override bool TryParseValueFromString(string value, out string result, out string validationErrorMessage)
{
result = value;
validationErrorMessage = null;
return true;
}
}
@inherits InputTextCode;
<input type="text" id="@Id" class="@Class" @bind-value="CurrentValueAsString" @bind-value:event="oninput" />
it would be really nice if this could be an easily configurable option on Input components out of the box, but at least there is a way to do it that doesn't make my skin crawl.
For anyone wondering, you can subclass InputText to change how it renders. For example, to make it use the oninput event, create MyInputText.razor containing:
@inherits Microsoft.AspNetCore.Components.Forms.InputText
<input @attributes="@AdditionalAttributes" class="@CssClass" @bind="@CurrentValueAsString" @bind:event="oninput" />
Now when you use <MyInputText @bind-Value="@someval" />
it will behave just like InputText except it updates on each keystroke.
SteveSanderson
Inheriting from a component and changing it so that it responds to the input
event is now covered in the official documentation for .NET Core 3.1:
InputText based on the input event
Use the
InputText
component to create a custom component that uses theinput
event instead of thechange
event.Create a component with the following markup, and use the component just as
InputText
is used:razor:
@inherits InputText <input @attributes="AdditionalAttributes" class="@CssClass" value="@CurrentValue" @oninput="EventCallback.Factory.CreateBinder<string>( this, __value => CurrentValueAsString = __value, CurrentValueAsString)" />
The documentation also gives an example of how to inherit a generic component:
@using System.Globalization @typeparam TValue @inherits InputBase<TValue>
So if you then combine the two of those together you can create a component that changes the behaviour of the InputNumber
component as follows:
@typeparam TNumber @inherits InputNumber<TNumber> <input type="number" step="any" @attributes="AdditionalAttributes" class="@CssClass" value="@CurrentValue" @oninput="EventCallback.Factory.CreateBinder<string>( this, __value => CurrentValueAsString = __value, CurrentValueAsString)" />
Including the type="number"
part will give the same behaviour as the existing InputNumber
(only allowing numeric character entry, using the up and down arrows to increment/decrement etc.)
If you put the code above in a file called say InputNumberUpdateOnInput.razor in the Shared folder of the Blazor project that component can then be used in the same way you'd use a normal InputNumber
, for example:
<InputNumberUpdateOnInput class="form-control text-right" @bind-Value="@invoiceLine.Qty" />
If you want to control the number of decimal places the component will allow you'd need to make the step
value a parameter that you pass into the component. There's more on step
in this answer.
Try this:
<input type="text" id="example1" @bind-value="@value" @bind-value:event="oninput" />
More...
Your approach is not recommended. You should subclass your components using Razor.
The following is a sample that should work. It can redirects you how to get a solution.
A solution to wrap an InputText:
<div class="form-group">
<label class="col-form-label">@Label</label>
<InputText Class="form-control" Value="@Value" ValueChanged="@ValueChanged" ValueExpression="@ValueExpression"></InputText>
</div>
@functions{
[Parameter] string Label { get; set; }
[Parameter] string Value { get; set; }
[Parameter] EventCallback<string> ValueChanged { get; set; }
[Parameter] Expression<Func<string>> ValueExpression { get; set; }
}
<span>Name of the category: @category.Name</span>
<EditForm Model="@category">
<NewInputText @bind-Value="@category.Name"/>
</EditForm>
You may also inherit from InputBase directly like so:
@inherits InputBase<string>
<input type="number" bind="@CurrentValue" id="@Id" class="@CssClass" />
Hope this helps...