About

P11SelectMultiple Component

The P11SelectMultiple component provides a multi-selection dropdown list, wrapping the native HTML <select multiple> element. It enables users to select multiple options from a predefined list, integrated with Bootstrap's .form-select class for consistent styling and offering flexible data binding and accessibility features.
Note: Similar to P11Select, options can be populated via an Items collection with expressions/fields, or manually through ChildContent. Ensure your binding target (@bind-Value) for this component is an ICollection<TValue> (e.g., List<string> or HashSet<int>) to correctly handle multiple selections.


P11SelectMultiple Component Examples

These examples demonstrate various configurations and functionalities of the P11SelectMultiple component, showcasing its flexibility for different use cases.

1. Standard Usage with List of Objects (Multiple Selection)

Selecting multiple names from a list of <code>Person</code> objects.

Selected Person IDs: Nothing selected

Implementation


<label for="multiPersonSelect" class="form-label">Wähle Personen (Mehrfachauswahl):</label>
<P11SelectMultiple TItem="Person" TValue="int"
                   Id="multiPersonSelect"
                   @bind-Value="selectedPersonIds"
                   Items="people2"
                   ItemValueExpression="p => p.Id"
                   ItemTextExpression="p => p.Name"
                   PlaceholderText="-- Keine Auswahl --"
                   OnChanged="@OnMultiplePersonsChanged"
                   CssClass="form-select-lg"
                   AriaLabel="Mehrere Personen auswählen Dropdown">
</P11SelectMultiple>
<p class="mt-2">
    Ausgewählte Personen IDs:
    <strong>
        @(selectedPersonIds != null && selectedPersonIds.Any()
                        ? string.Join(", ", selectedPersonIds)
                        : "Nichts ausgewählt")
    </strong>
</p>
@if (!string.IsNullOrEmpty(multiPersonChangedMessage))
{
    <p class="text-info">@multiPersonChangedMessage</p>
}

private ICollection<int> selectedPersonIds = new List<int>(); // List<int> for multiple selection
private string? multiPersonChangedMessage;

private List<Person> people2 = new List<Person>
{
    new Person { Id = 1, Name = "Alice", City = "New York" },
    new Person { Id = 2, Name = "Bob", City = "London" },
    new Person { Id = 3, Name = "Charlie", City = "Paris" },
    new Person { Id = 4, Name = "Diana", City = "Berlin" }
};

private void OnMultiplePersonsChanged(ICollection<int> newPersonIds)
{
    multiPersonChangedMessage = $"Personen geändert zu: {string.Join(", ", newPersonIds ?? new List<int>())}";
    Console.WriteLine(multiPersonChangedMessage);
}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public string City { get; set; } = string.Empty;
}


2. Usage with Enum (Multiple Selection)

Selecting multiple priorities from an <code>enum</code>.

Selected Priorities: Nothing selected

Implementation


<label for="multiPrioritySelect" class="form-label">Wähle Prioritäten (Mehrfachauswahl):</label>
<P11SelectMultiple TItem="Priority" TValue="Priority"
                   Id="multiPrioritySelect"
                   @bind-Value="selectedPriorities"
                   Items="@Enum.GetValues<Priority>()"
                   ItemValueExpression="p => p"
                   ItemTextExpression="p => p.ToString()"
                   PlaceholderText="-- Wähle Prioritäten --"
                   AriaLabel="Mehrere Prioritäten auswählen Dropdown">
</P11SelectMultiple>
<p class="mt-2">
    Ausgewählte Prioritäten:
    <strong>
        @(selectedPriorities != null && selectedPriorities.Any()
                        ? string.Join(", ", selectedPriorities)
                        : "Nichts ausgewählt")
    </strong>
</p>

private ICollection<Priority> selectedPriorities = new List<Priority>(); // List<Priority> for multiple enum selection

public enum Priority
{
    Low,
    Medium,
    High,
    Critical
}


3. Manual Options (ChildContent) (Multiple Selection)

Direct rendering of <code>&lt;option&gt;</code> tags within the component for multiple selection.

Selected Cities: MUN

Implementation


<label for="multiCitySelect" class="form-label">Wähle Städte manuell (Mehrfachauswahl):</label>
<P11SelectMultiple TItem="string" TValue="string"
                   Id="multiCitySelect"
                   @bind-Value="selectedCities"
                   PlaceholderText="Wähle Städte manuell"
                   AriaLabel="Mehrere Städte auswählen Dropdown">
    <option value="BER">Berlin</option>
    <option value="MUN">München</option>
    <option value="HAM">Hamburg</option>
    <option value="COL">Köln</option>
    <option value="FRA">Frankfurt</option>
</P11SelectMultiple>
<p class="mt-2">
    Ausgewählte Städte:
    <strong>
        @(selectedCities != null && selectedCities.Any()
                        ? string.Join(", ", selectedCities)
                        : "Nichts ausgewählt")
    </strong>
</p>

private ICollection<string> selectedCities = new List<string> { "MUN" }; // Pre-selected for manual example


4. Disabled Select (Multiple Selection)

A multi-selection field that is not interactive.

Disabled Selection: 1, 3

Implementation


<label for="disabledMultiSelect" class="form-label">Deaktivierte Mehrfachauswahl:</label>
<P11SelectMultiple TItem="Person" TValue="int"
                   Id="disabledMultiSelect"
                   @bind-Value="disabledSelectedPersonIds"
                   Items="people2"
                   ItemValueExpression="p => p.Id"
                   ItemTextExpression="p => p.Name"
                   IsDisabled="true"
                   PlaceholderText="Auswahl deaktiviert"
                   AriaLabel="Deaktiviertes Mehrfachauswahl Dropdown">
</P11SelectMultiple>
<p class="mt-2">
    Deaktivierte Auswahl:
    <strong>
        @(disabledSelectedPersonIds != null && disabledSelectedPersonIds.Any()
                        ? string.Join(", ", disabledSelectedPersonIds)
                        : "Nichts ausgewählt")
    </strong>
</p>

private ICollection<int> disabledSelectedPersonIds = new List<int> { 1, 3 }; // Pre-selected for disabled example


5. Validation in EditForm (Multiple Selection)

Demonstrates integration with Blazor's <code>EditForm</code> and validation mechanisms for multiple selection.

Validation Status: Warten auf Absenden...

Implementation


<EditForm Model="validationModelMultiple" OnValidSubmit="HandleValidSubmit3" OnInvalidSubmit="HandleInvalidSubmit3">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <div class="mb-3">
        <label for="requiredMultiPersonSelect" class="form-label">Pflichtfeld Personen (Mehrfachauswahl):</label>
        <P11SelectMultiple TItem="Person" TValue="int"
                           Id="requiredMultiPersonSelect"
                           @bind-Value="validationModelMultiple.SelectedRequiredPersonIds"
                           Items="people2"
                           ItemValueExpression="p => p.Id"
                           ItemTextExpression="p => p.Name"
                           PlaceholderText="-- Bitte wählen --"
                           AriaLabel="Pflichtfeld Personen Dropdown">
        </P11SelectMultiple>
        <ValidationMessage For="@(() => validationModelMultiple.SelectedRequiredPersonIds)" />
    </div>

    <div class="mb-3">
        <label for="requiredMultiPrioritySelect" class="form-label">Pflichtfeld Prioritäten (Mehrfachauswahl):</label>
        <P11SelectMultiple TItem="Priority" TValue="Priority"
                           Id="requiredMultiPrioritySelect"
                           @bind-Value="validationModelMultiple.SelectedRequiredPriorities"
                           Items="@Enum.GetValues<Priority>()"
                           ItemValueExpression="p => p"
                           ItemTextExpression="p => p.ToString()"
                           PlaceholderText="-- Bitte wählen --"
                           AriaLabel="Pflichtfeld Prioritäten Dropdown">
        </P11SelectMultiple>
        <ValidationMessage For="@(() => validationModelMultiple.SelectedRequiredPriorities)" />
    </div>

    <button type="submit" class="btn btn-primary">Formular absenden</button>
    <p class="mt-2">Validierungsstatus: <strong>@validationStatus3</strong></p>
</EditForm>

private ValidationTestModelMultiple validationModelMultiple = new ValidationTestModelMultiple();
private string validationStatus3 = "Warten auf Absenden...";

private void HandleValidSubmit3()
{
    validationStatus3 = "Formular ist GÜLTIG!";
    Console.WriteLine($"Validierung erfolgreich. Personen: {string.Join(", ", validationModelMultiple.SelectedRequiredPersonIds ?? new List<int>())}, Prioritäten: {string.Join(", ", validationModelMultiple.SelectedRequiredPriorities ?? new List<Priority>())}");
}

private void HandleInvalidSubmit3()
{
    validationStatus3 = "Formular ist UNGÜLTIG!";
    Console.WriteLine("Validierung fehlgeschlagen.");
}

public class ValidationTestModelMultiple
{
    [Required(ErrorMessage = "Bitte wählen Sie mindestens eine Person aus.")]
    // For collections, Required checks if the collection is null.
    // To check if it's empty, you might need a custom validation attribute or check in OnValidSubmit.
    // However, a simple Required will catch a null collection.
    public ICollection<int>? SelectedRequiredPersonIds { get; set; } = new List<int>();

    [Required(ErrorMessage = "Bitte wählen Sie mindestens eine Priorität aus.")]
    public ICollection<Priority>? SelectedRequiredPriorities { get; set; } = new List<Priority>();
}


6. OnChanged Event Example

This example demonstrates how to use the <code>OnChanged</code> event to react to changes in the selected values. The current selections are displayed immediately after a change.

Selected Languages (via OnChanged): None

Implementation


<label for="programmingLanguageSelect" class="form-label">Wähle Programmiersprachen:</label>
<P11SelectMultiple TItem="string" TValue="string"
                   Id="programmingLanguageSelect"
                   @bind-Value="selectedProgrammingLanguages"
                   OnChanged="@OnProgrammingLanguagesChanged"
                   Items="programmingLanguageOptions"
                   ItemValueExpression="lang => lang"
                   ItemTextExpression="lang => lang"
                   PlaceholderText="-- Wähle Sprachen --"
                   AriaLabel="Programmiersprachen auswählen Dropdown">
</P11SelectMultiple>
<p class="mt-2">
    Ausgewählte Sprachen (via OnChanged):
    <strong>
        @(selectedProgrammingLanguages != null && selectedProgrammingLanguages.Any()
                        ? string.Join(", ", selectedProgrammingLanguages)
                        : "None")
    </strong>
</p>
@if (!string.IsNullOrEmpty(programmingLanguagesChangedMessage))
{
    <p class="text-info">@programmingLanguagesChangedMessage</p>
}

private ICollection<string> selectedProgrammingLanguages = new List<string>();
private string? programmingLanguagesChangedMessage;

private List<string> programmingLanguageOptions = new() { "C#", "JavaScript", "Python", "Java", "TypeScript", "Go" };

private void OnProgrammingLanguagesChanged(ICollection<string> newValues)
{
    // selectedProgrammingLanguages wird bereits durch @bind-Value aktualisiert.
    // Wir nutzen newValues hier, um die Event-Payload zu demonstrieren.
    programmingLanguagesChangedMessage = $"Sprachen geändert zu: {string.Join(", ", newValues ?? new List<string>())} um {DateTime.Now:HH:mm:ss}";
    Console.WriteLine($"Programming languages changed to: {string.Join(", ", newValues ?? new List<string>())}");
}


Component API

Parameter Type Default Description
Items IEnumerable<TItem>? null Gets or sets the collection of items to display in the select dropdown.
ItemValueExpression Expression<Func<TItem, TValue>>? null Gets or sets an expression that specifies which property of TItem should be used as the value for each option. This is the preferred way over ItemValueField for type safety and AOT/trimming compatibility.
ItemTextExpression Expression<Func<TItem, string>>? null Gets or sets an expression that specifies which property of TItem should be used as the display text for each option. This is the preferred way over ItemTextField for type safety and AOT/trimming compatibility.
ItemValueField string? null Gets or sets the name of the property in TItem to use as the value for each option. Use ItemValueExpression for better type safety and AOT/trimming compatibility.
ItemTextField string? null Gets or sets the name of the property in TItem to use as the display text for each option. Use ItemTextExpression for better type safety and AOT/trimming compatibility.
Id string? null Gets or sets the HTML 'id' attribute for the select element. Recommended for accessibility, especially when used with a <label>.
Name string? null Gets or sets the HTML 'name' attribute for the select element.
CssClass string? null Gets or sets additional CSS classes to apply to the select element.
IsDisabled bool false Gets or sets a value indicating whether the select element should be disabled.
AriaLabel string? null Gets or sets the ARIA label for accessibility. Provides a descriptive label for screen readers. Important if no visual label is associated via 'id' or 'for'.
Title string? null Gets or sets the HTML 'title' attribute for the select element. Provides a tooltip on hover and can act as a fallback accessible name.
PlaceholderText string? null Gets or sets the text for a default placeholder option.
PlaceholderValue string string.Empty Gets or sets the value for the default placeholder option.
PlaceholderIsDisabled bool true Gets or sets a value indicating whether the placeholder option should be disabled (not selectable).
NoOptionsText string \"No options available\" Gets or sets the text to display when no options are available (and no placeholder or ChildContent is provided).
ChildContent RenderFragment? null Gets or sets the content to render inside the <select> element, typically used to define custom <option> elements manually.
SkipValidation bool false Gets or sets a value indicating whether to skip the internal configuration validation checks.
Events
OnChanged EventCallback<ICollection<TValue>> - An EventCallback that is invoked when the selected values of the component change. The callback receives the new collection of values as its argument. This complements the @bind-Value parameter.




An unhandled error has occurred. Reload 🗙