FodWizardStep
Documentație pentru componenta FodWizardStep
1. Descriere Generală
FodWizardStep
reprezintă un pas individual într-un wizard FodWizard
. Componenta gestionează validarea formularelor, navigarea între pași și afișarea conținutului specific fiecărui pas, oferind o experiență ghidată pentru completarea proceselor multi-pas.
Caracteristici principale: - Validare automată cu EditContext - Navigare personalizabilă înainte/înapoi - Pași opționali - Evenimente pentru activare și tranziții - Suport pentru iconițe distinctive - Gestionare multiple EditContext - Control granular asupra navigării - Integrare completă cu FodWizard
2. Utilizare de Bază
Wizard simplu cu pași
<FodWizard>
<FodWizardStep Name="Date personale">
<FodTextField @bind-Value="model.FirstName" Label="Prenume" Required="true" />
<FodTextField @bind-Value="model.LastName" Label="Nume" Required="true" />
<FodDatePicker @bind-Value="model.BirthDate" Label="Data nașterii" />
</FodWizardStep>
<FodWizardStep Name="Date de contact">
<FodTextField @bind-Value="model.Email" Label="Email" Type="email" />
<FodTextField @bind-Value="model.Phone" Label="Telefon" />
</FodWizardStep>
<FodWizardStep Name="Confirmare">
<h4>Verificați datele introduse:</h4>
<p>Nume: @model.FirstName @model.LastName</p>
<p>Email: @model.Email</p>
</FodWizardStep>
</FodWizard>
@code {
private UserModel model = new();
}
Pași cu validare EditForm
<FodWizard>
<FodWizardStep Name="Informații generale" EditContext="editContext1">
<EditForm EditContext="editContext1">
<DataAnnotationsValidator />
<ValidationSummary />
<FodTextField @bind-Value="model.CompanyName"
Label="Numele companiei"
Required="true" />
<FodTextField @bind-Value="model.TaxId"
Label="Cod fiscal"
Required="true" />
</EditForm>
</FodWizardStep>
<FodWizardStep Name="Adresă" EditContext="editContext2">
<EditForm EditContext="editContext2">
<DataAnnotationsValidator />
<ValidationSummary />
<FodTextField @bind-Value="model.Street" Label="Stradă" />
<FodTextField @bind-Value="model.City" Label="Oraș" />
</EditForm>
</FodWizardStep>
</FodWizard>
@code {
private CompanyModel model = new();
private EditContext editContext1;
private EditContext editContext2;
protected override void OnInitialized()
{
editContext1 = new EditContext(model);
editContext2 = new EditContext(model);
}
}
3. Parametri
Proprietate | Tip | Descriere | Valoare Implicită |
---|---|---|---|
Name |
string |
Numele pasului afișat în wizard | - |
Icon |
string |
Iconiță pentru pas | - |
Step |
int |
Numărul pasului | - |
Optional |
bool |
Marchează pasul ca opțional | false |
ShowTitle |
bool |
Afișează titlul pasului | false |
ValidateEditContextsOnNext |
bool |
Validează toate EditContext la Next | true |
CanGoBack |
bool |
Permite navigarea înapoi | true |
CanGoNext |
bool |
Permite navigarea înainte | true |
NextButtonText |
string |
Text personalizat pentru butonul Next | - |
BackButtonText |
string |
Text personalizat pentru butonul Back | - |
EditContext |
EditContext |
Context principal pentru validare | - |
OnNext |
Func<Task<bool>> |
Callback înainte de următorul pas | - |
OnBack |
Func<Task<bool>> |
Callback înainte de pasul anterior | - |
OnActivate |
Func<Task> |
Callback la activarea pasului | - |
NextStep |
Func<int> |
Determină următorul pas dinamic | - |
BackStep |
Func<int> |
Determină pasul anterior dinamic | - |
ChildContent |
RenderFragment |
Conținutul pasului | - |
4. Metode Publice
Metodă | Descriere |
---|---|
RegisterEditContext(EditContext) |
Înregistrează un EditContext pentru validare |
Validate() |
Validează toate EditContext înregistrate |
5. Exemple Avansate
Wizard cu validare complexă
<FodWizard @ref="wizard">
<FodWizardStep Name="Date client" Icon="@FodIcons.Material.Filled.Person">
<CascadingValue Value="@currentStep" Name="WizardStep">
<EditForm EditContext="clientContext" OnValidSubmit="SaveClient">
<DataAnnotationsValidator />
<ValidationSummary />
<FodTextField @bind-Value="client.Name"
Label="Nume complet"
Required="true" />
<FodTextField @bind-Value="client.Idnp"
Label="IDNP"
Required="true"
MaxLength="13" />
<FodButton Type="submit" Style="display: none;">Submit</FodButton>
</EditForm>
</CascadingValue>
</FodWizardStep>
<FodWizardStep Name="Servicii"
Icon="@FodIcons.Material.Filled.ShoppingCart"
OnNext="ValidateServices">
<h4>Selectați serviciile dorite:</h4>
@foreach (var service in availableServices)
{
<FodCheckbox @bind-Checked="service.Selected"
Label="@($"{service.Name} - {service.Price} MDL")" />
}
@if (!selectedServices.Any())
{
<FodAlert Severity="FodSeverity.Warning">
Selectați cel puțin un serviciu
</FodAlert>
}
</FodWizardStep>
<FodWizardStep Name="Plată"
Icon="@FodIcons.Material.Filled.Payment"
Optional="@(totalAmount == 0)">
<h4>Detalii plată</h4>
<FodText>Total de plată: @totalAmount MDL</FodText>
<FodRadioGroup @bind-SelectedOption="paymentMethod">
<FodRadio Option="@("card")">Card bancar</FodRadio>
<FodRadio Option="@("cash")">Numerar</FodRadio>
<FodRadio Option="@("transfer")">Transfer bancar</FodRadio>
</FodRadioGroup>
</FodWizardStep>
</FodWizard>
@code {
private FodWizard wizard;
private FodWizardStep currentStep;
private ClientModel client = new();
private EditContext clientContext;
private List<ServiceItem> availableServices = new();
private string paymentMethod = "card";
private IEnumerable<ServiceItem> selectedServices =>
availableServices.Where(s => s.Selected);
private decimal totalAmount =>
selectedServices.Sum(s => s.Price);
protected override void OnInitialized()
{
clientContext = new EditContext(client);
currentStep?.RegisterEditContext(clientContext);
}
private async Task<bool> ValidateServices()
{
if (!selectedServices.Any())
{
await ShowNotification("Selectați cel puțin un serviciu", FodSeverity.Error);
return false;
}
return true;
}
private void SaveClient()
{
// Salvare date client
}
}
Wizard cu navigare condiționată
<FodWizard>
<FodWizardStep Name="Tip persoană"
Icon="@FodIcons.Material.Filled.Category">
<FodRadioGroup @bind-SelectedOption="personType">
<FodRadio Option="@("individual")">Persoană fizică</FodRadio>
<FodRadio Option="@("company")">Persoană juridică</FodRadio>
</FodRadioGroup>
</FodWizardStep>
<FodWizardStep Name="Date individuale"
Icon="@FodIcons.Material.Filled.Person"
NextStep="@(() => personType == "individual" ? 3 : 2)">
@if (personType == "individual")
{
<FodTextField @bind-Value="individual.FirstName" Label="Prenume" />
<FodTextField @bind-Value="individual.LastName" Label="Nume" />
<FodTextField @bind-Value="individual.Idnp" Label="IDNP" />
}
</FodWizardStep>
<FodWizardStep Name="Date companie"
Icon="@FodIcons.Material.Filled.Business">
@if (personType == "company")
{
<FodTextField @bind-Value="company.Name" Label="Denumire" />
<FodTextField @bind-Value="company.Idno" Label="IDNO" />
<FodTextField @bind-Value="company.VatNumber" Label="Cod TVA" />
}
</FodWizardStep>
<FodWizardStep Name="Rezumat">
<h4>Date introduse:</h4>
@if (personType == "individual")
{
<p>Persoană fizică: @individual.FirstName @individual.LastName</p>
}
else
{
<p>Persoană juridică: @company.Name</p>
}
</FodWizardStep>
</FodWizard>
@code {
private string personType = "individual";
private IndividualModel individual = new();
private CompanyModel company = new();
}
Wizard cu activare asincronă
<FodWizard>
<FodWizardStep Name="Selectare serviciu"
Icon="@FodIcons.Material.Filled.Apps">
<FodSelect @bind-Value="selectedServiceId" Label="Serviciu">
@foreach (var service in services)
{
<FodSelectItem Value="@service.Id">@service.Name</FodSelectItem>
}
</FodSelect>
</FodWizardStep>
<FodWizardStep Name="Configurare"
Icon="@FodIcons.Material.Filled.Settings"
OnActivate="LoadServiceConfiguration">
@if (isLoading)
{
<FodLoadingLinear />
}
else if (configuration != null)
{
<h4>Configurare @configuration.ServiceName</h4>
@foreach (var param in configuration.Parameters)
{
<FodTextField @bind-Value="param.Value"
Label="@param.Label"
HelperText="@param.Description" />
}
}
</FodWizardStep>
<FodWizardStep Name="Previzualizare"
Icon="@FodIcons.Material.Filled.Preview"
OnActivate="GeneratePreview">
@if (preview != null)
{
<FodCard>
<FodCardContent>
@((MarkupString)preview.Html)
</FodCardContent>
</FodCard>
}
</FodWizardStep>
</FodWizard>
@code {
private int selectedServiceId;
private ServiceConfiguration configuration;
private PreviewResult preview;
private bool isLoading;
private async Task LoadServiceConfiguration()
{
isLoading = true;
configuration = await ServiceApi.GetConfiguration(selectedServiceId);
isLoading = false;
}
private async Task GeneratePreview()
{
preview = await ServiceApi.GeneratePreview(configuration);
}
}
Wizard cu pași multipli EditContext
<FodWizard>
<FodWizardStep Name="Date principale" @ref="mainDataStep">
<EditForm EditContext="mainContext">
<DataAnnotationsValidator />
<FodTextField @bind-Value="mainData.Title" Label="Titlu" />
</EditForm>
<EditForm EditContext="detailsContext">
<DataAnnotationsValidator />
<FodTextArea @bind-Value="details.Description" Label="Descriere" />
</EditForm>
<EditForm EditContext="settingsContext">
<DataAnnotationsValidator />
<FodCheckbox @bind-Checked="settings.IsPublic" Label="Public" />
</EditForm>
</FodWizardStep>
</FodWizard>
@code {
private FodWizardStep mainDataStep;
private MainData mainData = new();
private Details details = new();
private Settings settings = new();
private EditContext mainContext;
private EditContext detailsContext;
private EditContext settingsContext;
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
mainDataStep.RegisterEditContext(mainContext);
mainDataStep.RegisterEditContext(detailsContext);
mainDataStep.RegisterEditContext(settingsContext);
}
}
}
6. Integrare cu Formulare
Cu validare server-side
<FodWizard>
<FodWizardStep Name="Date formular"
OnNext="ValidateWithServer">
<EditForm EditContext="editContext">
<DataAnnotationsValidator />
<ServerValidator @ref="serverValidator" />
<ValidationSummary />
<FodTextField @bind-Value="model.Username"
Label="Nume utilizator" />
<FodTextField @bind-Value="model.Email"
Label="Email"
Type="email" />
</EditForm>
</FodWizardStep>
</FodWizard>
@code {
private ServerValidator serverValidator;
private async Task<bool> ValidateWithServer()
{
var result = await UserApi.ValidateData(model);
if (!result.IsValid)
{
serverValidator.DisplayErrors(result.Errors);
return false;
}
return true;
}
}
7. Stilizare și Teme
/* Pas activ personalizat */
.wizard-steps .nav-link.active {
background-color: var(--fod-palette-primary-main);
color: white;
font-weight: 600;
}
/* Iconițe colorate pentru pași */
.wizard-step-icon {
color: var(--fod-palette-primary-light);
margin-right: 8px;
}
/* Pas opțional cu stil distinct */
.wizard-step-optional {
font-style: italic;
opacity: 0.8;
}
/* Animație tranziție între pași */
.wizard-content {
animation: fadeIn 0.3s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}
8. Scenarii Comune
Wizard pentru înregistrare
<FodWizard Title="Înregistrare cont nou">
<FodWizardStep Name="Tip cont" Icon="@FodIcons.Material.Filled.AccountBox">
<FodRadioGroup @bind-SelectedOption="accountType">
<FodRadio Option="@("personal")">Cont personal</FodRadio>
<FodRadio Option="@("business")">Cont business</FodRadio>
</FodRadioGroup>
</FodWizardStep>
<FodWizardStep Name="Date de autentificare"
Icon="@FodIcons.Material.Filled.Security"
ValidateEditContextsOnNext="true">
<EditForm Model="credentials" OnValidSubmit="CheckUsername">
<DataAnnotationsValidator />
<ValidationSummary />
<FodTextField @bind-Value="credentials.Username"
Label="Nume utilizator"
Required="true"
HelperText="Minim 3 caractere" />
<FodTextField @bind-Value="credentials.Password"
Label="Parolă"
Type="password"
Required="true" />
<FodTextField @bind-Value="credentials.ConfirmPassword"
Label="Confirmă parola"
Type="password"
Required="true" />
</EditForm>
</FodWizardStep>
<FodWizardStep Name="Verificare email"
Icon="@FodIcons.Material.Filled.Email"
OnActivate="SendVerificationCode">
<FodTextField @bind-Value="email"
Label="Adresă email"
Type="email" />
<FodTextField @bind-Value="verificationCode"
Label="Cod verificare"
HelperText="Verificați email-ul pentru cod" />
<FodButton OnClick="ResendCode"
Variant="FodVariant.Text"
Size="FodSize.Small">
Retrimite cod
</FodButton>
</FodWizardStep>
<FodWizardStep Name="Finalizare"
Icon="@FodIcons.Material.Filled.CheckCircle"
NextButtonText="Creează cont">
<FodAlert Severity="FodSeverity.Success">
Contul dvs. este gata de creare!
</FodAlert>
<h4>Rezumat:</h4>
<p>Tip cont: @accountType</p>
<p>Utilizator: @credentials.Username</p>
<p>Email: @email</p>
<FodCheckbox @bind-Checked="acceptTerms"
Label="Accept termenii și condițiile" />
</FodWizardStep>
</FodWizard>
9. Best Practices
- Validare progresivă - Validați fiecare pas înainte de continuare
- Feedback clar - Afișați erori și mesaje de succes
- Pași opționali - Marcați clar pașii care pot fi omiși
- Salvare progres - Salvați datele pentru a permite revenire
- Indicatori vizuali - Folosiți iconițe pentru claritate
- Navigare intuitivă - Permiteți navigare înapoi când e posibil
10. Performanță
- Încărcați date asincron în OnActivate
- Evitați validări costisitoare pe fiecare tastare
- Folosiți lazy loading pentru conținut complex
- Cache-uiți datele între pași când e posibil
11. Accesibilitate
- Pașii sunt marcați cu ARIA labels
- Navigarea cu tastatura este suportată
- Mesajele de eroare sunt anunțate de screen readers
- Focus management între pași
12. Troubleshooting
Validarea nu funcționează
- Verificați că EditContext este setat corect
- Verificați ValidateEditContextsOnNext="true"
- Asigurați-vă că RegisterEditContext este apelat
Navigarea nu funcționează
- Verificați că FodWizard conține pașii
- Verificați valorile CanGoNext/CanGoBack
- Verificați că OnNext returnează true
Conținutul nu se afișează
- Verificați că pasul este activ
- Verificați ierarhia CascadingValue
- Verificați că ChildContent este definit
13. Concluzie
FodWizardStep
oferă o structură flexibilă pentru crearea de procese ghidate în aplicațiile FOD. Cu suport pentru validare complexă, navigare condiționată și integrare completă cu sistemul de formulare Blazor, componenta facilitează implementarea wizard-urilor intuitive și robuste.