Blazor HTML 数字输入不强制执行最小最大约束

SET*_*ERE 5 c# blazor

我试图限制用户可以放入 HTML 数字输入的最大数值。如果我只使用箭头更改数字,则效果很好,但如果用户手动输入数字,则不会强制执行。

是否有内置解决方案,无需 javascript/JQuery 或表单提交?您知道的 Blazor 组件可能有帮助吗?谢谢!

@foreach(var component in Components)
{
    <tr>

        <td>
            <input type="number" min = "1" max="Assembly.Component.Quantity" @bind-value="Component.Quantity"/>
         </td>
    </tr>
}
Run Code Online (Sandbox Code Playgroud)

MrC*_*tis 3

如果控件不存在,则构建它。

这是一个基于InputNumber此的:

  1. 限制 int 值。
  2. 不允许您输入超出限制的值。
  3. 如果您尝试这样做,则会添加一条验证消息。
@using System.Diagnostics.CodeAnalysis
@using System.Globalization
@inherits InputNumber<int?>

<input type="number" class="@this.CssClass" @attributes=this.AdditionalAttributes value=@this.CurrentValueAsString @oninput=OnValueChanged />

@code {
    [Parameter] public int Min { get; set; } = int.MinValue;
    [Parameter] public int Max { get; set; } = int.MaxValue;

    private async Task OnValueChanged(ChangeEventArgs e)
    {
        // capture the current state
        var currentValue = this.CurrentValue;
        var resetToCurrent = false;

        // Check if we need to reset the display value
        if (BindConverter.TryConvertTo<int?>(e.Value?.ToString(), CultureInfo.InvariantCulture, out int? value))
            resetToCurrent = value < this.Min || value > this.Max;

        // Sets off the internal InputBase update process        
        this.CurrentValueAsString = e.Value?.ToString();

        // Bit of a hoop jumping exercise to get the display value back to what it was.
        // Currently the actual UI Dom has it at the new (invalid) value
        // whilst the Render DOM has it at it's last value.
        // If we set it to it's old value the Renderer thinks it hasn't changed and doesn't do anything!
        if (resetToCurrent)
        {
            this.CurrentValue = value;
            StateHasChanged();
            // Called to yield and let the Renderer update the component before we reset it to the old value
            await Task.Delay(1);
            this.CurrentValue = currentValue;
            StateHasChanged();
        }
    }

    // Normal override to covert the string value to it's correct type and add validation message if we need to.
    protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out int? result, [NotNullWhen(false)] out string? validationErrorMessage)
    {
        validationErrorMessage = null;

        if (BindConverter.TryConvertTo<int?>(value, CultureInfo.InvariantCulture, out result))
        {
            if (result < this.Min)
                validationErrorMessage = $"{DisplayName ?? FieldIdentifier.FieldName} must be greater than {this.Min}";

            if (result > this.Max)
                validationErrorMessage = $"{DisplayName ?? FieldIdentifier.FieldName} must be less than {this.Max}";
        }

        if (validationErrorMessage is not null)
            result = CurrentValue;

        return validationErrorMessage is null;
    }
}
Run Code Online (Sandbox Code Playgroud)

还有我的测试页面:

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

<EditForm Model=this.model>
    <MyInputNumber @bind-Value=this.model.Value Min=1 Max=10 placeholder="Must be 1-10" />
    <ValidationSummary />
</EditForm>

<div class="m-2 p-2 bg-dark text-white">
    Value : @this.model.Value
</div>

@code {
    private ModelData model = new ModelData();

    public class ModelData
    {
        public int? Value { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)