Aller au contenu principal

LgSelect

LgSelect<TValue> est la liste déroulante à sélection unique. Les options se déclarent en markup dans <Items> (avec LgOptionListItem), ou proviennent d'une source de données (DataSourceItems / DataSource) ; une zone de recherche intégrée peut filtrer les options.

<LgSelect Label="#Color" Placeholder="#ChooseColor" @bind-Value="_model.Color">
<Items>
<LgOptionListItem Text="#Blue" Value="@("blue")" />
<LgOptionListItem Text="#Green" Value="@("green")" />
</Items>
</LgSelect>
  • Espace de noms : Lagoon.UI.Components
  • Hérite de : LgSelectBase<TValue, TValue> → LgInputRenderBase<TValue> → LgInputBase<TValue> → LgAriaComponentBase → LgComponentBase
  • Package NuGet : Lagoon.UI
Sélection multiple et saisie assistée

Pour lier une collection de valeurs, utilisez LgSelectMultiple (Référence API). Pour une saisie libre assistée de suggestions, utilisez LgSuggestBox.

Utilisation​

Démonstration​

Essayez ce composant dans le showcase Lagoon.

Options en markup​

Chaque option est un LgOptionListItem portant son texte et sa valeur.

ColorSelectPage.razor
<LgSelect Label="#Color" Placeholder="#ChooseColor" @bind-Value="_model.Color">
<Items>
@foreach (ColorItem item in _colors)
{
<LgOptionListItem Text="@item.Label" Value="@item.Value" />
}
</Items>
</LgSelect>
ColorSelectPage.razor.cs
public partial class ColorSelectPage : LgPage
{
// Options affichées : le couple libellé / valeur alimente les LgOptionListItem.
private readonly List<ColorItem> _colors = new()
{
new ColorItem("Bleu", "blue"),
new ColorItem("Vert", "green"),
new ColorItem("Rouge", "red")
};

private readonly ColorVm _model = new();

private sealed record ColorItem(string Label, string Value);

private sealed class ColorVm
{
public string Color { get; set; }
}
}

Alimentation par une source de données​

DataSourceItems alimente la liste depuis une collection ; DataSource (IListDataSource) prend en charge les scénarios avancés (texte / valeur séparés, chargement à la demande) — voir la Référence API pour les types attendus.

CountrySelectPage.razor
<LgSelect Label="#Country"
DataSourceItems="_countries"
@bind-Value="_model.Country" />
CountrySelectPage.razor.cs
public partial class CountrySelectPage : LgPage
{
// Source de données directe : chaque élément est à la fois le texte et la valeur.
private readonly List<string> _countries = new() { "France", "Allemagne", "Espagne", "Italie" };

private readonly CountryVm _model = new();

private sealed class CountryVm
{
public string Country { get; set; }
}
}

Source distante et selects en cascade​

RemoteListDataSource<TItem, TValue> charge les options depuis une action de contrôleur [Queryable] (voir Attribut Queryable) : TItem est le type renvoyé par le serveur (un view model), TValue le type de la valeur liée, et les deux sélecteurs extraient la valeur et le texte de chaque élément. ControllerQueryArg transmet au contrôleur un argument métier, reçu dans un QueryArg<T>.

Pour un select qui dépend d'un autre (les sociétés du pays choisi), il suffit de modifier ControllerQueryArg de la source : le select recharge sa liste avec le nouvel argument.

FirmSelectPage.razor
<LgSelect Label="#Country"
DataSource="_countriesDataSource"
OnChange="OnCountryChanged"
@bind-Value="_model.CountryId" />
<LgSelect Label="#Firm"
DataSource="_firmsDataSource"
@bind-Value="_model.FirmId" />
FirmSelectPage.razor.cs
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 reçu par l'action GetFirmsByCountry dans un QueryArg<int?>.
_firmsDataSource = new RemoteListDataSource<VmCountryFirm, Guid?>(
"api/Firms/GetFirmsByCountry", x => x.Id, x => x.FirmName)
{
ControllerQueryArg = _model.CountryId
};
}

private Task OnCountryChanged()
{
// La société sélectionnée appartient au pays précédent : on l'efface.
_model.FirmId = null;
// Changer l'argument suffit à recharger la liste des sociétés.
_firmsDataSource.ControllerQueryArg = _model.CountryId;
return Task.CompletedTask;
}

private sealed class FirmVm
{
public int? CountryId { get; set; }

public Guid? FirmId { get; set; }
}
}

Quand ControllerQueryArg change (une affectation de la même valeur est ignorée), le select abandonne sa liste et la redemande au serveur :

  • tout de suite si la liste est ouverte, si un chargement est en cours (il est annulé puis relancé avec le nouvel argument : la réponse obsolète n'est jamais affichée) ou s'il reste le libellé d'une valeur sélectionnée à résoudre ;
  • sinon à la prochaine ouverture de la liste, sans requête inutile.
attention
Valeur sélectionnée et ResetDataSource()
  • La valeur sélectionnée n'est pas effacée quand l'argument change : si elle n'appartient plus à la nouvelle liste, remettez-la à null dans le gestionnaire qui change l'argument (comme OnCountryChanged ci-dessus).
  • N'appelez pas ResetDataSource() avant ou après avoir modifié ControllerQueryArg : le changement d'argument recharge déjà le select. Appelé juste avant, ResetDataSource() peut envoyer une requête avec l'ancien argument, aussitôt annulée. Réservez ResetDataSource() au rechargement sans changement d'argument (données modifiées côté serveur, par exemple).

Le même fonctionnement s'applique à LgSelectMultiple.

Recherche dans les options​

ShowSearchBox affiche la zone de recherche, MinSearchCharacter fixe le nombre de caractères avant filtrage et OnFilterChange notifie chaque recherche (utile pour recharger une source à la demande).

CitySelectPage.razor
<LgSelect Label="#City"
ShowSearchBox="true"
MinSearchCharacter="2"
OnFilterChange="OnFilterChangeAsync"
DataSourceItems="_cities"
@bind-Value="_model.City" />
CitySelectPage.razor.cs
public partial class CitySelectPage : LgPage
{
private List<string> _cities = new() { "Paris", "Lyon", "Marseille" };

private readonly CityVm _model = new();

// Déclenché à chaque recherche : point d'entrée pour recharger la source à la demande.
private async Task OnFilterChangeAsync(FilterChangeEventArgs args)
{
await Task.Delay(100);
ShowInformation("#SearchDone");
}

private sealed class CityVm
{
public string City { get; set; }
}
}

Annuler un changement de sélection​

OnChangingAsync est appelé avant l'affectation et permet d'annuler le changement (args.Cancel) ; OnChange (hérité) est appelé après.

StatusSelectPage.razor
<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>
StatusSelectPage.razor.cs
public partial class StatusSelectPage : LgPage
{
private readonly StatusVm _model = new();

// Appelé avant le changement : interdit l'archivage direct depuis le brouillon.
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";
}
}

Propriétés​

Toutes les propriétés [Parameter] du composant, y compris celles héritées.

NomTypeDéfautDéclaré dansDescription
OnChangingAsyncFunc<ChangingEventArgs<TValue>, Task>nullLgSelectCallback appelé avant le changement de valeur ; le changement peut y être annulé.
DataSourceIListDataSource<TValue>nullLgSelectBaseSource de données de la liste (texte / valeur séparés, chargement à la demande).
DataSourceItemsIEnumerable<TValue>nullLgSelectBaseÉléments de la liste fournis directement.
DropDownMaxHeightint0LgSelectBaseHauteur maximale de la liste déroulante, en pixels. Si 0 ou moins, la configuration de l'application s'applique.
InputMaskstringnullLgSelectBaseMasque de saisie appliqué à la zone de recherche.
InputMaskKindInputMaskKindNoneLgSelectBaseType de masque de saisie de la zone de recherche.
InputMaskPlaceholderstringnullLgSelectBaseCaractère remplissant les positions vides du masque de saisie (par exemple # avec le masque 99-99-99-99-99 affiche ##-##-##-##-##). À ne pas confondre avec Placeholder. Sans valeur, le caractère par défaut du masque (_) est conservé. S'applique à la zone de recherche du menu déroulant.
ItemsRenderFragmentnullLgSelectBaseOptions déclarées en markup (LgOptionListItem).
MinSearchCharacterint0LgSelectBaseNombre minimal de caractères avant filtrage (et avant OnFilterChange en chargement à la demande).
OnFilterChangeEventCallback<FilterChangeEventArgs>—LgSelectBaseCallback déclenché quand l'utilisateur fait une recherche.
PlaceholderstringnullLgSelectBaseTexte affiché quand aucune valeur n'est sélectionnée. Distinct de InputMaskPlaceholder.
SearchBoxCssClassstringnullLgSelectBaseClasses CSS additionnelles de la zone de recherche.
ShowSearchBoxbool?nullLgSelectBaseAffiche la zone de recherche. Si null, la configuration de l'application s'applique.
SuffixSearchBoxstringnullLgSelectBaseSuffixe de la zone de recherche.
SuffixTypeSearchBoxInputLabelTypeIconNameLgSelectBaseNature du suffixe de la zone de recherche.
PrefixstringnullLgInputRenderBasePréfixe affiché dans le champ.
PrefixTypeInputLabelTypeTextLgInputRenderBaseNature du préfixe.
SuffixstringnullLgInputRenderBaseSuffixe affiché dans le champ.
SuffixTypeInputLabelTypeTextLgInputRenderBaseNature du suffixe.
AdditionalAttributesIReadOnlyDictionary<string, object>nullLgInputBaseAttributs HTML additionnels appliqués à l'élément rendu.
AutoFocusboolfalseLgInputBaseDonne le focus au champ lors du premier rendu.
ConfirmationMessagestringnullLgInputBaseMessage de confirmation affiché avant d'appliquer un changement de sélection.
ContainerIInputContainer<TValue>nullLgInputBaseUsage interne : rattache une cellule de GridView au champ.
CssClassstringnullLgInputBaseClasses CSS additionnelles.
DisabledboolfalseLgInputBaseDésactive le champ.
DisplayNamestringnullLgInputBaseNom du champ utilisé dans les messages d'erreur.
HideValidationMessageboolfalseLgInputBaseMasque le message de validation sous le champ.
LabelstringnullLgInputBaseLibellé du champ.
LabelContentRenderFragmentnullLgInputBaseContenu personnalisé de la zone de libellé.
OnChangeEventCallback<ChangeEventArgs>—LgInputBaseCallback appelé après le changement de sélection.
OnResetEventCallback<ChangeEventArgs>—LgInputBaseCallback appelé quand la sélection est effacée par le bouton d'effacement.
PolicyEditstringnullLgInputBasePolicy requise pour modifier le champ.
PolicyVisiblestringnullLgInputBasePolicy requise pour afficher le champ.
ReadOnlyboolfalseLgInputBaseAffiche la sélection en lecture seule.
Requiredbool?nullLgInputBaseChamp obligatoire. Si null, déduit de l'attribut [Required] de la propriété liée. Un champ obligatoire n'affiche pas le bouton d'effacement.
ResetButtonbool?nullLgInputBaseAffiche le bouton d'effacement de la sélection. Si null, la configuration de comportement de l'application s'applique.
ResetTextstringnullLgInputBaseTexte du bouton d'effacement.
ResetTextAriaLabelstringnullLgInputBaseLibellé accessible (aria-label) du bouton d'effacement.
TooltipstringnullLgInputBaseBulle d'aide.
TooltipIsHtmlboolfalseLgInputBaseIndique si le contenu du Tooltip est au format HTML (sinon texte brut).
ValueTValue—LgInputBaseValeur sélectionnée (@bind-Value).
ValueChangedEventCallback<TValue>—LgInputBaseCallback de mise à jour de la valeur liée.
ValueExpressionExpression<Func<TValue>>—LgInputBaseExpression identifiant la propriété liée.
AriaLabelstringnullLgAriaComponentBaseValeur de l'attribut aria-label.
AriaLabelledBystringnullLgAriaComponentBaseValeur de l'attribut aria-labelledby.
Paramètres en cascade

LgSelect consomme aussi des paramètres fournis automatiquement par des composants ancêtres (vous n'avez pas à les définir) : ParentAuthorizeView (LgAuthorizeView) et le contexte d'édition d'un LgEditForm parent.

Événements​

ÉvénementTypeDescription
OnChangingAsyncFunc<ChangingEventArgs<TValue>, Task>Avant le changement de sélection ; args.Cancel = true l'annule.
OnChangeEventCallback<ChangeEventArgs>Après le changement de sélection.
OnFilterChangeEventCallback<FilterChangeEventArgs>Quand l'utilisateur fait une recherche dans la liste.
OnResetEventCallback<ChangeEventArgs>Quand la sélection est effacée par le bouton d'effacement.

Énumérations associées​

Les énumérations utilisées sont documentées sur les composants de base : InputMaskKind sur LgTextBox et InputLabelType sur LgDateBox.

Bonnes pratiques / accessibilité​

  • Activez ShowSearchBox dès que la liste dépasse une dizaine d'options.
  • Utilisez DataSource (plutôt que DataSourceItems) quand le texte affiché diffère de la valeur stockée ou que la liste se charge à la demande.
  • Pour peu d'options toujours visibles, préférez LgRadioGroup.
Référence complète

Tous les paramètres (hérités compris) : Référence API — LgSelect. Pour la sélection multiple, voir LgSelectMultiple. Pour une saisie libre assistée de suggestions, voir LgSuggestBox.

Composants liés​