Search code examples
formsvalidationblazoruser-inputmessage

Blazor form validation to readonly fields


I am developing an application using C# in Blazor Framework. I have designed some forms like the following, where the grey areas are populated with the button below which triggers a pop up window for selection. Then after selection is done the selected item description will populated into the gray area. This grey area is an InputText element.

enter image description here

If the grey InputTexts are marked as required & readonly, then the areas are grey and users cannot insert manually their values but only though selection window. This is good, but if the user did not populate the window for selection it can also submit the form.

enter image description here

If the grey InputTexts are marked as required and beeing readonly though css, then the validation works, so the user should populate the window selection first, but if he did not, then the grey area becomes editable for manual input.

enter image description here

Any ideas how I can protect the application from manual input but at the same time make the validation work?


Solution

  • Any ideas how I can protect the application from manual input but at the same time make the validation work?

    If I'm reading the question correctly, the demo below shows how to link the selector (in this case a select control) and the display and show the correct validation information and UX without access to the readonly control.

    As you show no code, I don't know whether this fits with your model and form.

    @page "/"
    @using System.ComponentModel.DataAnnotations;
    
    <PageTitle>Index</PageTitle>
    
    <h1>Demo</h1>
    
    <EditForm Model="model" OnValidSubmit=@OnSubmit class="border border-dark p-3 m-2">
        <DataAnnotationsValidator />
    
        <div class="mb-2">
            <label class="form-label">Country</label>
            <InputText class="form-control" disabled @bind-Value="@model.Value" />
            <ValidationMessage For="() => model.Value" />
        </div>
    
        @if (!show)
        {
            <div class="mb-2">
                <button type="button" class="btn btn-dark" @onclick=OnShow>Select Country</button>
            </div>
        }
        else
        {
            <div class="mb-2">
                <InputSelect class="form-select" @bind-Value:[email protected] @bind-Value:set="this.OnSetCountry">
                    <option value="">-- Select a Country -- </option>
                    <option value="UK">UK</option>
                    <option value="France">France</option>
                    <option value="Portugal">Portugal</option>
                </InputSelect>
            </div>
        }
        <div class="col=12 mt-2 text-end">
            <button class="btn btn-success" type="submit">Submit</button>
        </div>
    </EditForm>
    
    <h3 class="mt-4">Hides the -- Select a Country -- once a value is selected</h3>
    <EditForm Model="model2" OnValidSubmit=@OnSubmit class="border border-dark p-3 m-2">
        <DataAnnotationsValidator />
    
        <div class="mb-2">
            <label class="form-label">Country</label>
            <InputText class="form-control" disabled @bind-Value="@model2.Value" />
            <ValidationMessage For="() => model2.Value" />
        </div>
    
        @if (!show2)
        {
            <div class="mb-2">
                <button type="button" class="btn btn-dark" @onclick=OnShow2>Select Country</button>
            </div>
        }
        else
        {
            <div class="mb-2">
                <InputSelect class="form-select" @bind-Value:[email protected] @bind-Value:set="this.OnSetCountry2">
                    @if (model2.Value is null)
                    {
                        <option selected disabled value="">-- Select a Country -- </option>
                    }
                    <option value="UK">UK</option>
                    <option value="France">France</option>
                    <option value="Portugal">Portugal</option>
                </InputSelect>
            </div>
        }
        <div class="col=12 mt-2 text-end">
            <button class="btn btn-success" type="submit">Submit</button>
        </div>
    </EditForm>
    
    
    @code {
        private Model model = new();
        private bool show = false;
    
        private Model model2 = new();
        private bool show2 = false;
    
        private void OnSetCountry(string? value)
        {
            model.Value = null;
    
            if (value is not null || value != string.Empty)
                model.Value = value;
    
            show = false;
        }
    
        private void OnSetCountry2(string? value)
        {
            model2.Value = null;
    
            if (value is not null || value != string.Empty)
                model2.Value = value;
    
            show2 = false;
        }
    
        private void OnShow()
            => show = !show;
    
        private void OnShow2()
            => show2 = !show2;
    
        public void OnSubmit()
        { }
    
        public class Model
        {
            [Required]
            public string? Value { get; set; }
        }
    }