<FodSelect TItem="string" TValue="string"
Items="@countries"
ItemValue="@(item => item)"
ItemText="@(item => item)"
@bind-Value="@selectedCountry"
Placeholder="Select a country"
Label="Country" />
@code {
private List<string> countries = ["USA", "Canada", "UK"];
private string? selectedCountry;
}Select
Production-ready select component supporting single and multi-select modes with advanced search, virtualization, and full WCAG AA accessibility. Built with type-safe generics and zero JavaScript footprint.
Quick Start
Basic FodSelect with static data, single selection, and two-way binding.
Multi-Select
Multiple selection mode with chips for selected items and remove functionality.
<FodSelect TItem="string" TValue="string"
Items="@skills"
ItemValue="@(s => s)"
ItemText="@(s => s)"
SelectionMode="SelectionMode.Multiple"
@bind-Values="@selectedSkills"
Placeholder="Select skills"
Label="Skills"
Clearable="true" />
@code {
private List<string> skills = ["C#", "Blazor", "JavaScript"];
private IEnumerable<string> selectedSkills = new List<string>();
}Searchable Select
Client-side filtering with search input for finding options quickly.
<FodSelect TItem="string" TValue="string"
Items="@countries"
ItemValue="@(c => c)"
ItemText="@(c => c)"
@bind-Value="@selected"
Searchable="true"
SearchPlaceholder="Type to search..."
Placeholder="Select a country"
Label="Country" />Async Loading
Server-side search with debouncing, cancellation, and loading states.
Async behavior:
- DebounceMs - Waits 300ms after typing stops before searching
- MinSearchLength - Requires 2 characters before triggering search
- Cancellation - Previous requests cancelled when new search starts
<FodSelect TItem="Product" TValue="Guid"
LoadItems="@SearchProductsAsync"
ItemValue="@(p => p.Id)"
ItemText="@(p => p.Name)"
@bind-Value="@selectedProductId"
Searchable="true"
DebounceMs="300"
MinSearchLength="2"
Placeholder="Search products..."
Label="Product" />
@code {
private Guid? selectedProductId;
private async Task<IEnumerable<Product>> SearchProductsAsync(
string searchText, CancellationToken ct)
{
await Task.Delay(500, ct);
return products.Where(p => p.Name.Contains(searchText, StringComparison.OrdinalIgnoreCase));
}
}Option Grouping
Group options by category with visual headers.
<FodSelect TItem="Employee" TValue="int"
Items="@employees"
ItemValue="@(e => e.Id)"
ItemText="@(e => e.Name)"
GroupBy="@(e => e.Department)"
@bind-Value="@selectedEmployeeId"
Placeholder="Select an employee"
Label="Employee" />
@code {
public record Employee(int Id, string Name, string Department);
private List<Employee> employees = [...];
private int? selectedEmployeeId;
}Custom Templates
Rich rendering with custom item, chip, and selected item templates.
<FodSelect TItem="User" TValue="int"
Items="@users"
ItemValue="@(u => u.Id)"
ItemText="@(u => u.Name)"
@bind-Value="@selectedUserId"
Label="User with avatar">
<ItemTemplate Context="user">
<div style="display: flex; align-items: center; gap: 8px;">
<div class="avatar">@user.Name[0]</div>
<div>
<div>@user.Name</div>
<div style="font-size: 12px;">@user.Role</div>
</div>
</div>
</ItemTemplate>
</FodSelect>Form Validation
Integration with EditForm and DataAnnotationsValidator for required field validation.
<EditForm Model="@model" OnValidSubmit="@HandleSubmit">
<DataAnnotationsValidator />
<FodSelect TItem="string" TValue="string"
Items="@departments"
ItemValue="@(d => d)"
ItemText="@(d => d)"
@bind-Value="@model.Department"
For="@(() => model.Department)"
Required="true"
Label="Department" />
<button type="submit">Submit</button>
</EditForm>
@code {
public class FormModel
{
[Required(ErrorMessage = "Department is required")]
public string? Department { get; set; }
}
}Virtualization
Performance-optimized rendering for large lists (1000+ items) using Blazor's Virtualize component.
Virtualization parameters:
- Virtualize="true" - Enable virtualization
- VirtualizationThreshold="50" - Activate at 50+ items
- ItemHeight="40" - Each item is 40px tall
- MaxDropdownHeight="300px" - Dropdown max height
<FodSelect TItem="string" TValue="string"
Items="@largeList"
ItemValue="@(item => item)"
ItemText="@(item => item)"
@bind-VALUE="@selected"
Virtualize="true"
VirtualizationThreshold="50"
ItemHeight="40"
MaxDropdownHeight="300px"
Searchable="true"
Placeholder="Select from 1000 items"
LABEL="Large list" />
@code {
private LIST<string> largeList = Enumerable.Range(1, 1000).Select(i => $"Item {i}").ToList();
private string? selected;
}Disabled & Readonly
Non-interactive states for display-only or locked selections.
<FodSelect TItem="string" TValue="string"
Items="@countries"
Value="USA"
Disabled="true"
Label="Disabled" />
<FodSelect TItem="string" TValue="string"
Items="@countries"
Value="Canada"
Readonly="true"
Label="Readonly" />Clearable
Optional clear button to reset selection.
<FodSelect TItem="string" TValue="string"
Items="@countries"
ItemValue="@(c => c)"
ItemText="@(c => c)"
@bind-Value="@selected"
Clearable="true" />Keyboard Navigation
FodSelect supports complete keyboard navigation following WAI-ARIA patterns.
| Key | Context | Action |
|---|---|---|
| Enter / Space | Trigger closed | Open dropdown |
| Arrow Down/Up | Trigger closed | Open dropdown |
| Arrow Down/Up | Dropdown open | Navigate options |
| Enter | Option active | Select option |
| Escape | Dropdown open | Close dropdown |
| Backspace/Delete | Chip focused | Remove chip (multi) |
| Left/Right | Chips | Navigate between chips |
| Tab | Any | Move to next element |
RTL Support
FodSelect supports right-to-left languages with proper text and layout alignment.
<div dir="rtl" lang="ar">
<FodSelect TItem="string" TValue="string"
Items="@arabicCountries"
ItemValue="@(c => c)"
ItemText="@(c => c)"
@bind-Value="@selected"
Placeholder="اختر دولة"
Label="الدولة" />
</div>Grid Layout
FodSelect respects FodGrid column widths at all breakpoints, including narrow columns.
<FodGrid GapY="Spacing.Spacing16" GapX="Spacing.Spacing16">
<FodItem Span="Span.Col12" Md="Span.Col3">
<FodSelect TItem="string" TValue="string" Items="@countries"
ItemText="@(s => s)" ItemValue="@(s => s)"
Label="Country" @bind-Value="@country" />
</FodItem>
<FodItem Span="Span.Col12" Md="Span.Col2">
<FodSelect TItem="string" TValue="string" Items="@statuses"
ItemText="@(s => s)" ItemValue="@(s => s)"
Label="Status" @bind-Value="@status" />
</FodItem>
<FodItem Span="Span.Col12" Md="Span.Col1">
<FodSelect TItem="string" TValue="string" Items="@types"
ItemText="@(s => s)" ItemValue="@(s => s)"
Label="Type" @bind-Value="@type" />
</FodItem>
</FodGrid>API Reference
FodSelect component properties and their descriptions.
