I am fairly new to blazor ecosystem and have a requirement to modify the default registration to include role for the user. This could be a simple radio but they want selectable cards.
I understand default registration is statically rendered and I cannot set rendermode InteractiveServer
. To overcome this I have created a new component and set it as an interactive component.
@rendermode InteractiveServer<div class="flex space-x-4"><div @onclick="@(() => SelectRole("Customer"))" class="@GetRoleClass("Customer") cursor-pointer p-4 rounded-lg shadow-md flex-1 flex flex-col items-center justify-center transition"><img src="https://via.placeholder.com/100" alt="Customer" class="mb-2" /><p class="font-bold">Customer</p><p class="text-sm text-gray-600">Register as a customer to access our products and services.</p></div><div @onclick="@(() => SelectRole("Vendor"))" class="@GetRoleClass("Vendor") cursor-pointer p-4 rounded-lg shadow-md flex-1 flex flex-col items-center justify-center transition"><img src="https://via.placeholder.com/100" alt="Vendor" class="mb-2" /><p class="font-bold">Vendor</p><p class="text-sm text-gray-600">Register as a vendor to sell your products and services.</p></div></div>@code { [Parameter] public EventCallback<string> OnRoleSelected { get; set; } private string? SelectedRole { get; set; } private async void SelectRole(string role) { SelectedRole = role; await OnRoleSelected.InvokeAsync(role); StateHasChanged(); } private string GetRoleClass(string role) => (SelectedRole == role) ? "border-2 border-blue-500 bg-blue-100" : "border border-gray-300";}
I use it in default registration page as
<div class="pt-4 mb-4"> @Input.Role<h3 class="text-lg font-semibold mb-2">Select your role</h3><RegisterationRoleSelect OnRoleSelected="SelectRole"/><ValidationMessage For="() => Input.Role" class="text-sm text-red-600 mt-2" /></div>
private async Task SelectRole(string role) { Input.Role = role; await Task.Yield(); StateHasChanged(); }
The resulting form interaction works fine and function in child component is called. however, invoke function does not trigger function in parent. I understand this could be because page is statically rendered and its not waiting for any events.
What is the way around this?
UPDATE:I am using .net 8Here is my app.razor
@inject IConfiguration Configuration<!DOCTYPE html><html lang="en" class="h-full "><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><base href="/" /><link href="https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;700&family=Sarala:wght@400;700&display=swap" rel="stylesheet"><link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" /><link rel="stylesheet" href="app.css" /><link rel="stylesheet" href="css/tailwind.css" /><link rel="icon" type="image/png" href="favicon.png" /><script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.9.6/lottie.min.js"></script><HeadOutlet /></head><body class="h-full"><Routes /><script src="_framework/blazor.web.js"></script><script src="_content/MudBlazor/MudBlazor.min.js"></script><script src="https://js.stripe.com/v3/"></script><script src="js/googlePlaces.js"></script><script> window.App = { stripe: { PublishableKey: '@Configuration["Stripe:PublishableKey"]' } };</script><script src="js/StripeSetup.js?v=1.5"></script></body></html>