skip to Main Content

My project is a Blazor server application. The fuctionality I am trying to achieve is I want my accordion header to change to the color red if my validation fails (if there is nothing in my input).

enter image description here

//my index.razor page:

@page "/"
<style>


</style>
<PageTitle>Blazor Bootstrap - Home</PageTitle>
<div class="test1">
    <EditForm Model="@registration" OnValidSubmit="HandleFormSubmission">
        <DataAnnotationsValidator />
        <Accordion>
            <AccordionItem Title="Accordion Item #1">
                <Content>
                    <InputText id="SmtpHost" @bind-Value="@registration.SmtpHost" placeholder="SMTP Host" />
                    <ValidationMessage For="@(() => registration.SmtpHost)" />
                </Content>
            </AccordionItem>
        </Accordion>
        <button type="submit">Submit</button>
    </EditForm>
</div>

@code {
    [Inject]
    protected IJSRuntime JSRuntime { get; set; }
    Data.Registration registration = new();
    bool isValidationError = false;
    bool isFormSubmitted = false;
    bool hasRendered = false;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
                // await Task.Yield();
                // await ToggleAccordionButtonError();
        }
    }

    public async Task HandleFormSubmission(EditContext context)
    {
        Console.WriteLine("Form Submitted Successfully");
        isValidationError = !context.Validate();

        Console.WriteLine("Testing");
        Console.WriteLine(isValidationError);

        if (isValidationError)
        {
            isFormSubmitted = true;
            if (hasRendered)
            {
                ToggleAccordionButtonError();
            }
            else
            {
                StateHasChanged(); // Notify Blazor to re-render the component
            }
        }
    }

    private async Task ToggleAccordionButtonError()
    {
        try
        {
            await JSRuntime.InvokeVoidAsync("toggleAccordionButtonError");
            await JSRuntime.InvokeVoidAsync("myJavaScriptFunction");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error invoking JavaScript function: {ex.Message}");
        }
    }
}

my custom.js file:

console.log("File recognised");

function myJavaScriptFunction() {
    // Invoke an alert
    console.log("Hello from JavaScript!");
}

// .test1 .accordion-button
function toggleAccordionButtonError() {
    console.log("Hello from JavaScript!");
    var elements = document.querySelectorAll('.accordion-button.collapsed');
    elements.forEach(function (element) {
        element.style.backgroundColor = "red";
        element.style.color = "white";
    });
}

My custom.js does work
I am aware I have commented out my code

One solution , I thought of was to use Javascript interobilty with HandleFormSubmission ;however it does’nt seem to work

I do know of Blazor’s Prerendering is a feature in Blazor that allows components to be rendered on the server before being sent to the client, and it imposes certain restrictions on when JavaScript interop calls can be made. Is there a way around this issue . Any insight will be highly appreciated.

2

Answers


  1. I do not think you should be using JS Interop for this.

    You said that you want your fields to turn red when validation fails. If a field is invalid the CSS tag invalid will be automatically added to the class of the respective input. You can also see this in the Dev Tools. You can style it like this:

    input.invalid {
      border-style: solid;
      border-color: red;
    }
    

    Additionally, there is also the invalid pseudo-element.

    Finally, give the docs about ASP.NET Core Blazor forms validation a read.

    Login or Signup to reply.
  2. You can do something as simple as:

          <AccordionItem class="@_accordianCss" Title="Accordion Item #1">
    
        private string _accordianCss => isValidationError ? "accordian-invalid" : "accordian-valid";
    

    And then add the styles either to your global css or isolated css.

    You can also do something similar to open/collapse the accordian if you wish.

    No JS required.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search