LgSelect
LgSelect<TValue> is the single-selection dropdown list. Options are
declared in markup within <Items> (with LgOptionListItem), or come from a
data source (DataSourceItems / DataSource); an integrated search area can
filter the options.
<LgSelect Label="#Color" Placeholder="#ChooseColor" @bind-Value="_model.Color">
<Items>
<LgOptionListItem Text="#Blue" Value="@("blue")" />
<LgOptionListItem Text="#Green" Value="@("green")" />
</Items>
</LgSelect>
- Namespace :
Lagoon.UI.Components - Inherits from :
LgSelectBase<TValue, TValue>→LgInputRenderBase<TValue>→LgInputBase<TValue>→LgAriaComponentBase→LgComponentBase - NuGet package :
Lagoon.UI
To bind a collection of values, use LgSelectMultiple
(API Reference). For free input with
suggestions, use LgSuggestBox.
Usage
Demo
Try this component in the Lagoon showcase.
Options in markup
Each option is an LgOptionListItem carrying its text and value.
<LgSelect Label="#Color" Placeholder="#ChooseColor" @bind-Value="_model.Color">
<Items>
@foreach (ColorItem item in _colors)
{
<LgOptionListItem Text="@item.Label" Value="@item.Value" />
}
</Items>
</LgSelect>
public partial class ColorSelectPage : LgPage
{
// Options displayed: the label / value pair feeds the LgOptionListItem.
private readonly List<ColorItem> _colors = new()
{
new ColorItem("Blue", "blue"),
new ColorItem("Green", "green"),
new ColorItem("Red", "red")
};
private readonly ColorVm _model = new();
private sealed record ColorItem(string Label, string Value);
private sealed class ColorVm
{
public string Color { get; set; }
}
}
Populating from a data source
DataSourceItems feeds the list from a collection; DataSource
(IListDataSource) handles advanced scenarios (separate text / value,
on-demand loading) — see the
API Reference for expected types.
<LgSelect Label="#Country"
DataSourceItems="_countries"
@bind-Value="_model.Country" />
public partial class CountrySelectPage : LgPage
{
// Direct data source: each element is both the text and the value.
private readonly List<string> _countries = new() { "France", "Germany", "Spain", "Italy" };
private readonly CountryVm _model = new();
private sealed class CountryVm
{
public string Country { get; set; }
}
}
Remote data source and cascading select lists
RemoteListDataSource<TItem, TValue> loads options from a [Queryable] controller
action (see Queryable attribute):
TItem is the type returned by the server (a view model), TValue is the type
of the bound value, and the two selectors extract the value and text from
each element. ControllerQueryArg passes a business argument to the controller,
received in a QueryArg<T>.
For a select that depends on another (the firms in the chosen country), simply
modify the ControllerQueryArg of the source: the select reloads its list
with the new argument.
<LgSelect Label="#Country"
DataSource="_countriesDataSource"
OnChange="OnCountryChanged"
@bind-Value="_model.CountryId" />
<LgSelect Label="#Firm"
DataSource="_firmsDataSource"
@bind-Value="_model.FirmId" />
public partial class FirmSelectPage : LgPage
{
private readonly FirmVm _model = new();
private RemoteListDataSource<VmCountry, int?> _countriesDataSource;
private RemoteListDataSource<VmCountryFirm, Guid?> _firmsDataSource;
protected override void OnInitialized()
{
base.OnInitialized();
_countriesDataSource = new RemoteListDataSource<VmCountry, int?>(
"api/Countries/names", x => x.Id, x => x.Name);
// Argument received by the GetFirmsByCountry action in a QueryArg<int?>.
_firmsDataSource = new RemoteListDataSource<VmCountryFirm, Guid?>(
"api/Firms/GetFirmsByCountry", x => x.Id, x => x.FirmName)
{
ControllerQueryArg = _model.CountryId
};
}
private Task OnCountryChanged()
{
// The selected firm belongs to the previous country: clear it.
_model.FirmId = null;
// Changing the argument is sufficient to reload the list of firms.
_firmsDataSource.ControllerQueryArg = _model.CountryId;
return Task.CompletedTask;
}
private sealed class FirmVm
{
public int? CountryId { get; set; }
public Guid? FirmId { get; set; }
}
}
When ControllerQueryArg changes (assigning the same value is ignored), the
select abandons its list and requests a new one from the server:
- immediately if the list is open, if a load is in progress (it is canceled then relaunched with the new argument: the outdated response is never displayed) or if there remains a label of a selected value to resolve;
- otherwise on the next open of the list, without unnecessary request.
ResetDataSource()- The selected value is not cleared when the argument changes: if it no
longer belongs to the new list, reset it to
nullin the handler that changes the argument (as inOnCountryChangedabove). - Do not call
ResetDataSource()before or after modifyingControllerQueryArg: changing the argument already reloads the select. Called just before,ResetDataSource()may send a request with the old argument, immediately canceled. ReserveResetDataSource()for reloading without argument change (data modified on the server side, for example).
The same behavior applies to LgSelectMultiple.
Searching in options
ShowSearchBox displays the search area, MinSearchCharacter sets the number
of characters before filtering, and OnFilterChange notifies each search
(useful for reloading a source on demand).
<LgSelect Label="#City"
ShowSearchBox="true"
MinSearchCharacter="2"
OnFilterChange="OnFilterChangeAsync"
DataSourceItems="_cities"
@bind-Value="_model.City" />
public partial class CitySelectPage : LgPage
{
private List<string> _cities = new() { "Paris", "Lyon", "Marseille" };
private readonly CityVm _model = new();
// Triggered on each search: entry point for reloading the source on demand.
private async Task OnFilterChangeAsync(FilterChangeEventArgs args)
{
await Task.Delay(100);
ShowInformation("#SearchDone");
}
private sealed class CityVm
{
public string City { get; set; }
}
}
Canceling a selection change
OnChangingAsync is called before assignment and allows canceling the change
(args.Cancel); OnChange (inherited) is called after.
<LgSelect Label="#Status"
OnChangingAsync="OnStatusChangingAsync"
@bind-Value="_model.Status">
<Items>
<LgOptionListItem Text="#Draft" Value="@("draft")" />
<LgOptionListItem Text="#Published" Value="@("published")" />
<LgOptionListItem Text="#Archived" Value="@("archived")" />
</Items>
</LgSelect>
public partial class StatusSelectPage : LgPage
{
private readonly StatusVm _model = new();
// Called before the change: prevents archiving directly from draft.
private Task OnStatusChangingAsync(ChangingEventArgs<string> args)
{
if (args.OldValue == "draft" && args.NewValue == "archived")
{
args.Cancel = true;
ShowWarning("#PublishBeforeArchive");
}
return Task.CompletedTask;
}
private sealed class StatusVm
{
public string Status { get; set; } = "draft";
}
}
Properties
All [Parameter] properties of the component, including inherited ones.
| Name | Type | Default | Declared in | Description |
|---|---|---|---|---|
OnChangingAsync | Func<ChangingEventArgs<TValue>, Task> | null | LgSelect | Callback called before the value changes; the change can be canceled here. |
DataSource | IListDataSource<TValue> | null | LgSelectBase | Data source for the list (separate text / value, on-demand loading). |
DataSourceItems | IEnumerable<TValue> | null | LgSelectBase | List items provided directly. |
DropDownMaxHeight | int | 0 | LgSelectBase | Maximum height of the dropdown list, in pixels. If 0 or less, the application configuration applies. |
InputMask | string | null | LgSelectBase | Input mask applied to the search area. |
InputMaskKind | InputMaskKind | None | LgSelectBase | Type of input mask for the search area. |
InputMaskPlaceholder | string | null | LgSelectBase | Character filling empty mask positions (for example # with the mask 99-99-99-99-99 displays ##-##-##-##-##). Not to be confused with Placeholder. Without a value, the mask's default character (_) is kept. Applies to the search area of the dropdown menu. |
Items | RenderFragment | null | LgSelectBase | Options declared in markup (LgOptionListItem). |
MinSearchCharacter | int | 0 | LgSelectBase | Minimum number of characters before filtering (and before OnFilterChange in on-demand loading). |
OnFilterChange | EventCallback<FilterChangeEventArgs> | — | LgSelectBase | Callback triggered when the user performs a search. |
Placeholder | string | null | LgSelectBase | Text displayed when no value is selected. Distinct from InputMaskPlaceholder. |
SearchBoxCssClass | string | null | LgSelectBase | Additional CSS classes for the search area. |
ShowSearchBox | bool? | null | LgSelectBase | Shows the search area. If null, the application configuration applies. |
SuffixSearchBox | string | null | LgSelectBase | Suffix for the search area. |
SuffixTypeSearchBox | InputLabelType | IconName | LgSelectBase | Nature of the search area suffix. |
Prefix | string | null | LgInputRenderBase | Prefix displayed in the field. |
PrefixType | InputLabelType | Text | LgInputRenderBase | Nature of the prefix. |
Suffix | string | null | LgInputRenderBase | Suffix displayed in the field. |
SuffixType | InputLabelType | Text | LgInputRenderBase | Nature of the suffix. |
AdditionalAttributes | IReadOnlyDictionary<string, object> | null | LgInputBase | Additional HTML attributes applied to the rendered element. |
AutoFocus | bool | false | LgInputBase | Gives focus to the field on first render. |
ConfirmationMessage | string | null | LgInputBase | Confirmation message displayed before applying a selection change. |
Container | IInputContainer<TValue> | null | LgInputBase | Internal use: attaches a GridView cell to the field. |
CssClass | string | null | LgInputBase | Additional CSS classes. |
Disabled | bool | false | LgInputBase | Disables the field. |
DisplayName | string | null | LgInputBase | Field name used in error messages. |
HideValidationMessage | bool | false | LgInputBase | Hides the validation message below the field. |
Label | string | null | LgInputBase | Field label. |
LabelContent | RenderFragment | null | LgInputBase | Custom content for the label area. |
OnChange | EventCallback<ChangeEventArgs> | — | LgInputBase | Callback called after the selection changes. |
OnReset | EventCallback<ChangeEventArgs> | — | LgInputBase | Callback called when the selection is cleared by the reset button. |
PolicyEdit | string | null | LgInputBase | Policy required to edit the field. |
PolicyVisible | string | null | LgInputBase | Policy required to display the field. |
ReadOnly | bool | false | LgInputBase | Displays the selection as read-only. |
Required | bool? | null | LgInputBase | Required field. If null, inferred from the [Required] attribute of the bound property. A required field does not display the reset button. |
ResetButton | bool? | null | LgInputBase | Displays the selection reset button. If null, the application behavior configuration applies. |
ResetText | string | null | LgInputBase | Text of the reset button. |
ResetTextAriaLabel | string | null | LgInputBase | Accessible label (aria-label) of the reset button. |
Tooltip | string | null | LgInputBase | Help tooltip. |
TooltipIsHtml | bool | false | LgInputBase | Indicates whether the Tooltip content is in HTML format (otherwise plain text). |
Value | TValue | — | LgInputBase | Selected value (@bind-Value). |
ValueChanged | EventCallback<TValue> | — | LgInputBase | Callback for updating the bound value. |
ValueExpression | Expression<Func<TValue>> | — | LgInputBase | Expression identifying the bound property. |
AriaLabel | string | null | LgAriaComponentBase | Value of the aria-label attribute. |
AriaLabelledBy | string | null | LgAriaComponentBase | Value of the aria-labelledby attribute. |
LgSelect also consumes parameters provided automatically by ancestor
components (you do not need to define them): ParentAuthorizeView
(LgAuthorizeView) and the edit context of a parent LgEditForm.
Events
| Event | Type | Description |
|---|---|---|
OnChangingAsync | Func<ChangingEventArgs<TValue>, Task> | Before the selection changes; args.Cancel = true cancels it. |
OnChange | EventCallback<ChangeEventArgs> | After the selection changes. |
OnFilterChange | EventCallback<FilterChangeEventArgs> | When the user performs a search in the list. |
OnReset | EventCallback<ChangeEventArgs> | When the selection is cleared by the reset button. |
Associated enumerations
The enumerations used are documented on the base components:
InputMaskKind on
LgTextBox and
InputLabelType on
LgDateBox.
Best practices / accessibility
- Enable
ShowSearchBoxwhenever the list exceeds about ten options. - Use
DataSource(rather thanDataSourceItems) when the displayed text differs from the stored value or when the list loads on demand. - For few options always visible, prefer
LgRadioGroup.
All parameters (including inherited ones): API Reference — LgSelect. For multiple selection, see LgSelectMultiple. For free input with suggestions, see LgSuggestBox.
Related components
LgSuggestBox— free input with suggestions.LgRadioGroup— single choice by radio buttons.LgCheckBoxList— multiple selection by checkboxes.LgGridSelectColumn— column linked to a data source in aLgGridView.