How to make an EditForm Input that binds using oninput rather than onchange

后端 未结 4 2098
名媛妹妹
名媛妹妹 2020-12-19 20:58

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

相关标签:
4条回答
  • 2020-12-19 21:04

    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.

    0 讨论(0)
  • 2020-12-19 21:05

    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

    0 讨论(0)
  • 2020-12-19 21:05

    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 the input event instead of the change 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.

    0 讨论(0)
  • 2020-12-19 21:07

    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:

    NewInputText.razor

    <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; }
    }
    

    Index.razor

    <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...

    0 讨论(0)
提交回复
热议问题