RfDropDown creates a Bulma dropdown that supports searching and manages the selection of an item.
When not to Use
Don't use RfDropDown when:
-
When using static rendering mode. Instead use
InputSelect.
A searchable drop down with one selection
RfDropDown creates a Bulma dropdown that supports searching and manages the selection of an item.
Don't use RfDropDown when:
InputSelect.
The RfDropDown works primarily with two parameters: SelectedItem and Items.
The dropdown doesn't make any assumptions on how to render the items or selected item it is given.
Instead the drop down supports three RenderFragement to customize the way an item appears within the drop down.
All three RenderFragement have a context of TItem and are used to setup two sections.
The two sections of the drop down that can be custimized are RowItemTemplate and SelectedItemTemplate.
The RowItemTempalte directly sets each row or option of the drop down. Each row is wrapped in the following code:
@RowItemTemplate(item)
If RowItemTemplate isn't set the drop down will use ChildContent.
When the drop down has a selection it calls the SelectedItemTemplate to render the TItem within the input portion of the drop down.
The selected item is wrapped in the following code:
@SelectedItemTemplate(SelectedItem)
If SelectedItemTemplate isn't set the drop down will use ChildContent.
When the items come from a service instead of a static list, set OnLoad. The drop down calls it with the
current filter text and expects your handler to assign Items. Clicking the trigger runs the open
sequence: the loading state is applied (Bulma shows the spinner on the trigger icon), OnLoad is
awaited, the loading state is cleared, and the panel opens only after your handler has returned.
An attempt to open while a load is in flight is ignored: no second OnLoad starts and the component
keeps the state of the load that is running. Typing in the filter re-invokes OnLoad with the new
filter text while the panel stays open; set FilterRateLimit to hold keystrokes until the rate elapses
and fire only the latest filter.
While the panel stays open, every keystroke in the filter box queues a filter change instead of calling
OnLoad directly. When FilterRateLimit is greater than zero (the default is 250 ms)
the drop down waits until the newest keystroke has sat quietly for that many milliseconds, then makes one
OnLoad call with the latest filter text; keystrokes typed during the wait are superseded and
dropped. Any new keystroke restarts the wait, so the load fires on the trailing edge of the typing.
FilterRateLimit = 0 turns the wait off and fires on every keystroke.
The wait is measured on a monotonic clock (stopwatch timestamps) and each sleep is only the time remaining in the quiet window, so the window length never depends on the wall clock: NTP corrections or manual clock changes cannot stretch the debounce or break it.
The loading state is released in a finally, so a handler that throws cannot latch the drop down into a
permanent loading state. The failed attempt leaves the drop down closed, the exception still propagates to your
app's event handling (Blazor's unhandled exception path unless you catch it), and the next click calls
OnLoad again. Before this fix a throwing handler left the loading state set forever and the drop down
could never be opened again.
OnLoad handler: when the handler returns normally the panel opens with whatever you left in
Items; when it throws, the attempt ends closed.
<RfDropDown TItem="string"
Items="@Items"
@bind-SelectedItem="@Selected"
OnLoad="@LoadNames" />
private async Task LoadNames(string filter)
{
Items = await NameService.SearchAsync(filter);
}
The drop down passes four class parameters through to the elements it renders, so you can style it without fighting the component:
CssClass is added to the root div.dropdown element, alongside the state classes the
component manages itself (is-active while open, is-right and is-up from Position).
CssFilterClass is added to the filter textbox alongside the Bulma input class.
It has no effect while ShowFilter hides the filter.
CssRowItemClass is added to every option row inside the drop down panel.
CssSelectedClass is added to the span wrapping the selected item in the trigger.
Unset parameters add nothing: the rendered markup is identical to a drop down that never had them.
<RfDropDown TItem="string"
Items="@Items"
@bind-SelectedItem="@Selected"
CssClass="wide-dropdown"
CssFilterClass="is-rounded" />
With the panel open this renders the root as class="dropdown is-active wide-dropdown"
and the filter textbox as class="input is-rounded".
Setting up RForge is simple. Follow the below steps to add RForge Blazor components to your project.
RForge Blazor components are installed via Nuget. There are two packages. One for the blazor app and one for the library if any.
dotnet add package RForge.Blazor
Install-Package RForge.Blazor
This is optional but may be useful if you want to use common enums across the backend and frontend.
dotnet add package RForge.Abstractions
Install-Package RForge.Abstractions
To simplify namespacing while using RForge,
the package is designed with most all components sitting within the root RForge namespace.
You may want to include the following namespaces in your _import.razor for ease of use.
@using RForgeBlazor
@using RForgeBlazor.Services
@using RForge.Abstractions
| Namespace | Purpose |
|---|---|
RForgeBlaozr |
Houses all of the blazor components. |
RForgeBlaozr.Services |
Houses interfaces you may need to communicate with certain components. |
RForgeBlaozr.Abstractions |
Common enums used through out the components. |
In order for some components to work they must first have their services registered.
Open up Program.cs and add the following line before the var app = builder.Build();.
using RForgeBlazor;
//...
builder.Services.AddRfForgeBlazorServices();
//...
var app = builder.Build();
RForge makes use of Bulma CSS to stylize the components. Add / install Bulma and add the CSS file to the head. Link to download: Bulma releases.