Search code examples
htmlrazorblazorrazor-pagesblazor-webassembly

EditForm in Blazor app have multiple submit buttons


I have a simple Blazor Editform where i have multiple buttons with different navigations & toast notifications. I have OnValidSubmit attached to Editform. Now the validations are working for all the buttons. I have added onclick() to trigger button functions but I want onclick to be triggered only if user has entered all the details. Hope I have explained well. Please let me know for additional input.

Current output for Forward or Next buttons are : if No values entered -> Correct validation(asked to fill in details) -> forward notification displayed.

Expected output : if No values entered -> Correct validation(asked to fill in details). if All values entered -> Correct validation -> forward notification displayed.

Here is some code:

 <EditForm EditContext="@editContext" OnValidSubmit="HandleValidSubmit"  @onreset="HandleReset">
            <DataAnnotationsValidator />
            <div class="form-row">
                <div class="form-group col">
                    <label>Role</label><br />
                    <InputRadioGroup @bind-Value="model.Role" class="form-control">
                        @foreach (var option in rdOptions)
                        {
                            <InputRadio Value="option" /> @option
                            <text>&nbsp;&nbsp;</text>
                        }
                    </InputRadioGroup>
                    <ValidationMessage For="@(() => model.Role)" />
                </div>
                <div class="form-group col">
                    <label>Company Name</label>
                    <InputSelect id="txtCompanyName" class="form-control" @bind-Value="@model.CompanyName">
                        <option selected value="-1">-Select-</option>
                        <option value="CompanyName1">CompanyName1</option>
                        <option value="CompanyName2">CompanyName2</option>
                    </InputSelect>
                    <ValidationMessage For="@(() => model.CompanyName)" />
                </div>
            </div>
         

            <div class="form-row">
                <div class="text-left col-3">
                    <button type="submit" class="btn btn-primary btn-success">Save</button>
                </div>
                <div class="text-right col-3">
                    <button type="submit" class="btn btn-primary" @onclick="@Forward">Forward</button>
                </div>
                <div class="text-right col-3">
                    <button type="submit" class="btn btn-primary" @onclick="@Review">Next</button>
                </div>
                <div class="text-right col-3">
                    <button type="reset" class="btn btn-secondary">Clear</button>
                </div>
            </div>
        </EditForm>

code section:

@code {
    private Model model = new Model();
    private EditContext editContext;
    List<Model> models = new();


    protected override void OnInitialized()
    {
        editContext = new EditContext(model);
    }

    private void HandleValidSubmit()
    {
        var modelJson = JsonSerializer.Serialize(model, new JsonSerializerOptions { WriteIndented = true });
        JSRuntime.InvokeVoidAsync("alert", $"SUCCESS!! :-)\n\n{modelJson}");
        toastService.ShowSuccess("saved successfully!");
    }

    private void Forward()
    {
        toastService.ShowInfo("Forwarded!!");
    }

    private void Review()
    {
        toastService.ShowInfo("Review!!");
    }
    private void HandleReset()
    {
        model = new Model();
        editContext = new EditContext(model);
    }
}

Solution

  • You can do validation manually in your button event handlers and then not use the EditForm OnValidSubmit, and set the button types to button.

    ...
    if (editContext.Validate())
     go
    else
     alert
    ...
    

    FYI - The relevant bit of code from EditForm looks like this:

            private async Task HandleSubmitAsync()
            {
                Debug.Assert(_editContext != null);
    
                if (OnSubmit.HasDelegate)
                {
                    // When using OnSubmit, the developer takes control of the validation lifecycle
                    await OnSubmit.InvokeAsync(_editContext);
                }
                else
                {
                    // Otherwise, the system implicitly runs validation on form submission
                    var isValid = _editContext.Validate(); // This will likely become ValidateAsync later
    
                    if (isValid && OnValidSubmit.HasDelegate)
                    {
                        await OnValidSubmit.InvokeAsync(_editContext);
                    }
    
                    if (!isValid && OnInvalidSubmit.HasDelegate)
                    {
                        await OnInvalidSubmit.InvokeAsync(_editContext);
                    }
                }
            }