0

So the thing is I have a little sandbox to play with Blazor. There is a basic form with a few fields. I'm trying to put some validation on that. The input fields are custom component, applied some bootstrap on them. In short, this is the input component:

@using System.Linq.Expressions

<div class="input-group mb-3">
    <span class="input-group-text" id=@Id>@Label</span>
    <InputText @bind-Value=@Value @oninput=OnInput type="text" class="form-control" placeholder=@PlaceHolder aria-label=@Label aria-describedby=@Id />
    <ValidationMessage For=@For />
</div>

@code {
    [Parameter]
    public string Id { get; set; }

    [Parameter]
    public string Label { get; set; }

    [Parameter]
    public string PlaceHolder { get; set; }

    [Parameter]
    public string Value 
    { 
        get => _value; 
        set
        {
            if (_value != value)
            {
                _value = value;
                ValueChanged.InvokeAsync(value);
            }
        }
    }

    private string _value;

    [Parameter]
    public EventCallback<string> ValueChanged { get; set; }

    [Parameter]
    public Expression<Func<string>> For { get; set; }

    [Parameter]
    public Func<string> OnFormChange { get; set; }

    private async Task OnInput(ChangeEventArgs e)
    {
        Value = e?.Value.ToString();
        await ValueChanged.InvokeAsync(Value);
    }
}

and a piece from the page:

...
<div class="container-sm">
    <Web.Components.Modal Id="exampleModal" Title="Fegyver bevezetése" OnSave="HandleSave" TriggerValidation="Validate" IsValid=@ModalIsValid>
        <EditForm Model=@weaponUnderEdit OnValidSubmit="HandleValidSubmit" OnInvalidSubmit="HandleInvalidSubmit">
            <DataAnnotationsValidator />
        ...
            @* <Web.Components.TextInput Id="weight" Label="Súly" PlaceHolder="Súly pl.: 0.3 (Tőr), 2.5 (Csatacsákány)" @[email protected] For="@(() => @weaponUnderEdit.Weight)" /> *@
            <Web.Components.TextInput Id="price" Label="Ár" PlaceHolder="Ár pl.: 1a 2e 3r, 1e 50r" @[email protected] For="@(() => @weaponUnderEdit.Price)" />
            <ValidationSummary />
        </EditForm>
    </Web.Components.Modal>
</div>
...

of course, there are data annotation attributes on the model:

public class CommonWeaponPrototype
{
...
    [Required, RegularExpression(@"^\d+(\.\d{1,2})?$")]
    public string Weight { get; set; }

    [Required, RegularExpression(@"^\d+(\.\d{1,2})?$")]
    public string Price { get; set; }
}

Now the validation works like that:

app

Everything there... and if the second input is uncomment... everything gone; no more validation.

So far tried to use custom validation, maybe I can do with that, using Regex check and so on... but it is really annoying that I can't make this work, and also, why custom? It is a really simple form to validate, some regex will it be.

0

1 Answer 1

2

I've simplified your code a little to demonstrate a working model.

First, your custom component. Mine inherits from InputText, which uses all the built in functionality and just changes the input formatting. It implements correct binding.

@using System.Linq.Expressions
@inherits InputText

<div class="input-group mb-3">
    <span class="input-group-text">@Label</span>
    <input @bind:get="@Value" @bind:set="OnValueChanged" @bind:event="oninput" type="text" class="form-control" placeholder=@PlaceHolder />
    <ValidationMessage For="ValueExpression" />
</div>

@code {
    [Parameter] public string? Label { get; set; }

    [Parameter] public string? PlaceHolder { get; set; }

    private Task OnValueChanged(string? value)
    {
        CurrentValueAsString = value;
        return Task.CompletedTask;
    }
}

And then the demo page:

@page "/"
@using System.ComponentModel.DataAnnotations

<PageTitle>Home</PageTitle>

<EditForm EditContext="_editContext" OnValidSubmit="this.OnValidSubmit">
    <DataAnnotationsValidator />
    <MyInput @bind-Value="_model.Weight" Label="Weight" />
    <MyInput @bind-Value="_model.Price" Label="Price" />
</EditForm>

@code {
    private Model _model = new();
    private EditContext? _editContext;

    protected override void OnInitialized()
    {
        _editContext = new(_model);
    }

    public Task OnValidSubmit()
    {
        // Do something
        return Task.CompletedTask;
    }

    public class Model
    {
        [Required, RegularExpression(@"^\d+(\.\d{1,2})?$")]
        public string? Weight { get; set; }

        [Required, RegularExpression(@"^\d+(\.\d{1,2})?$")]
        public string? Price { get; set; }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Seems so easy, don't know where I missed the lead... I have a working solution, much more complicated as you showing here. But I have now a different component type, so I give it a try. Seems good btw to me

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.