Reputation: 588
I am dynamically filling the values of a dropdown list based of the content of a list. When a item in the dropdown is selected, an option to remove this item is shown. When the item is removed, it is first removed from the list and then the dropdown list is rebuilt, this is where I run in to problems.
Instead of returning the dropdown to its default value when it is rebuilt the value just below the removed one is shown as selected (this happens without the @onchange
value being triggered).
How can I make the dropdown list return to its default value when it is being rebuilt?
Here is some Razor code:
<select class="form-control" @onchange="selectedValue">
<option value="">select one</option>
@foreach (var mod in values)
{
<option value="@mod.Id">@mod.Name</option>
}
</select>
The class named Items
that is populating the list:
public class Items
{
public string Name { get; set; }
public int Id { get; set; }
public Items(string name, int id)
{
Name = name;
Id = id;
}
}
The list itself (before it is populated):
public List<Items> itm = new List<Items>();
The function that's called onchange
:
public string SelectedValue = "";
public void selectedValue(ChangeEventArgs selectEvent)
{
SelectedValue = selectEvent.Value.ToString();
}
So to sum it up, this is what's happening:
Items
@foreach
loop (see Razor code).selectedValue()
function and changes the value and the SelectedValue
stringonchange
being run. This is the problemSelectedValue
string.This can probably be solved by setting the <select>
element to its default option/value, but i can't figure out how to do this.
How can I change the selected value to be the default option (in my case the "select one" option with value "") of my dropdown list?
Upvotes: 8
Views: 25300
Reputation: 2663
I was having a similar issue. I solved it by putting an if
statement in the loop that generates the option
elements and from there conditionally add the selected
attribute, here is a generic example:
<select @onchange="listChanged">
@foreach (var item in PageModel.Lists)
{
if(item.Id == currListId)
{
<option value="@item.Id" selected>@item.Name</option>
}
else
{
<option value="@item.Id">@item.Name</option>
}
}
</select>
Upvotes: 10
Reputation: 39
A similar problem confronted me in a .NET MAUI Blazor project. In the project I'm working on a view model manages most of the form behavior. In addition, CommunityToolkit.Mvvm is used to manage the property changed management. So this answer will base itself on that configuration adjusted for using bindings. It also follows answer given by @MikeT.
The assumption is that another element is effecting the selection decision. In my case if there is only one element in values to choose from, that element would become selected automatically. Otherwise, the user makes a selection.
<select class="form-control" @Bind="vm.selectedValueId"
disabled="@(vm.IsValuesDataLoaded == false)">
<option value="">select one</option>
@foreach (var mod in values)
{
@if(@mod.Id == @vm.selectedValueId)
{
<option value="@mod.Id" selected>@mod.Name</option>
}
else
{
<option value="@mod.Id">@mod.Name</option>
}
}
</select>
@code{
ValueViewModel vm; //instantiated inside OnInitialized
// more ...
}
As the view model is handling construction of the element list in values, all of the activity takes place there. So this section of view model code would be --
partial void OnSomeOtherPreliminaryPropertyChanged(string? value)
{
// code for processing this event
// condition test could also be for an entry previously selected
if(values.Count == 1)
{
SelectedValueId = whatever_Value_Should_Be_Default_For_Selection;
OnModuleIdChanged(selectedValueId);
}
IsValuesDataLoaded = true;
}
[ObservableProperty]
private int selectedValueId;
[ObservableProperty]
private string selectedValue;
//OnSelected... is called when selectedValueId changes. In this case
// the code is changing the selection
partial void OnSelectedValueIdChanged(int? value)
{
SelectedValue = Values[value].Name
}
public bool IsValuesDataLoaded //controls the enabled state of the select element
{
get;
private set;
} = false;
Upvotes: 1
Reputation: 45626
How can I change the selected value to be the default option (in my case the "select one" option with value "") of my dropdown list?
I'm afraid you can do it only with JSInterop as follows:
Generally speaking, the selectedIndex property on the select element is set to 0 after you select an option in the select element. This is done in the selectedValue method...
This is a complete working code snippet. Run it and test it...
@page "/"
<select @ref="myselect" id="myselect" class="form-control"
@onchange="selectedValue">
<option selected value="-1">select one</option>
@foreach (var item in items)
{
<option value="@item.ID">@item.Name</option>
}
</select>
<p>@SelectedValue</p>
@code {
[Inject] IJSRuntime JSRuntime { get; set; }
private ElementReference myselect;
List<Item> items = Enumerable.Range(1, 10).Select(i => new Item {
Name = $"Name {i.ToString()}", ID = i }).ToList();
public string SelectedValue = "";
public void selectedValue(ChangeEventArgs args)
{
SelectedValue = args.Value.ToString();
var item = items.Single(item => item.ID == Convert.ToInt32(SelectedValue));
items.Remove(item);
JSRuntime.InvokeVoidAsync("exampleJsFunctions.selectElement", myselect);
}
public class Item
{
public string Name { get; set; }
public int ID { get; set; }
}
}
Put the following JS code in the _Host.cshtml file:
<script src="_framework/blazor.server.js"></script>
<script>
window.exampleJsFunctions =
{
selectElement: function (element) {
element.selectedIndex = 0;
}
};
</script>
Upvotes: 5