Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

Choosing and configuring the most appropriate Blazor Fluent UI Drop-Down

$
0
0

I'm fairly new to Blazor and the new Fluent UI. I'm trying to create set of hierarchical drop-downs (the values in one list based on the user selection in another) based on the values from an API, but can't seem to get the placeholder text to behave as I'd like.

Using the following Blazor code, I've mocked up an example of my problem. It uses the FluentCombobox because it has a convenient Placeholder property. The problem is that, when the sub-list changes, the value chosen previously is persisted.

Repro steps:

  1. After the page loads, choose Make: 'Audi'.
  2. Then choose Model: 'A4'.
  3. Then go back to Make and choose 'BMW'.
  4. Problem: the value in Model still reflects 'A4', despite 'A4' not being a valid option. I'd like it to show the Placeholder text instead of persisting the previously selected value.

Blazor page

@page "/Vehicles"@rendermode InteractiveServer<h3>Vehicles</h3><FluentCombobox Label="Make:" Placeholder="Select a make..." Items="@Makes" ValueChanged="MakeValueChanged" Disabled="@MakesEmpty" Autocomplete="ComboboxAutocomplete.List" Height="300px" /><br/><FluentCombobox Label="Model:" Placeholder="Select a model..." Items="@Models" ValueChanged="ModelValueChanged" Disabled="@ModelsEmpty" Autocomplete="ComboboxAutocomplete.List" Height="300px" /><br /><FluentButton @onclick="OnSearchClick" Disabled="@SearchDisabled">Search</FluentButton>@code {    public string Make { get; set; } = string.Empty;    public string Model { get; set; } = string.Empty;    private IEnumerable<string> Makes { get; set; } = [];    private IEnumerable<string> Models { get; set; } = [];    private IDictionary<string, IEnumerable<string>> MakesModels { get; set; } = new Dictionary<string, IEnumerable<string>>    {        {"Audi", new string[] { "A4", "A6", "A8" } },        {"BMW", new string[] { "3 Series", "4 Series", "6 Series" } },        {"Volvo", new string[] { "C30", "C40", "C70" } },    };    private bool MakesEmpty { get { return this.Makes.Count() == 0; } }    private bool ModelsEmpty { get { return this.Models.Count() == 0; } }    private bool SearchDisabled { get { return this.Model.Length == 0; } }    private void LoadMakes()    {        // ... do stuff...        this.Makes = this.MakesModels.Keys;    }    private void LoadModels(string make)    {        this.Models = [];        this.Model = string.Empty;        // ... do stuff...        this.Models = this.MakesModels[make];    }    private void MakeValueChanged(string make)    {        this.Make = make;        this.LoadModels(this.Make);    }    private void ModelValueChanged(string model)    {        this.Model = model;    }    private void OnSearchClick()    {        Console.WriteLine($"Searching for make '{this.Make}' and model '{this.Model}'");    }    protected override void OnInitialized()    {        this.LoadMakes();    }}

Here is an (simplistic) example of an implementation of the drop-down component that works as I expected, but not using Fluent UI:

<div><label>@Label<select id="@Id" @bind="Value" @bind:after="OnValueChanged">            @{                int i = 0;                foreach (var item in Items)                {                    if (0 == i++)                    {<option value="" selected disabled>@PlaceholderText</option>                    }<option value="@item.Value">@item.Label</option>                }            }</select></label></div>

As you can see, the Placeholder value is re-written when the items list changes.

I've explored using the Fluent Listbox component and the FluentSelect component instead, but these don't seem to have a Placeholder attribute, and always chooses the value matching the position of the previously selected value (which is odd behaviour in my view). I want to avoid that and force the user to have to choose a value, or no value at all if that's a valid option. I suppose that I could use the Listbox and add a blank entry at the beginning. Is there no better way?

See also:

Thanks,

Kaine


Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>