I am currently working on a Blazor server application where I am looking to add a special functionality. My goal is to have the accordion header change to red if validation fails, meaning if there is no input in the field.
//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}");
}
}
}
custom.js content:
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";
});
}
The custom.js file works as intended, even though some code is commented out. One potential solution I considered was using Javascript interop with HandleFormSubmission, but it did not work as expected. I understand that Blazor's Prerendering feature may impose restrictions on when JavaScript interop calls can be made. If anyone has insights or workaround solutions for this issue, I would greatly appreciate it.