Reputation: 729
I have two select boxes in my Blazor page. I select the department on Select Box-1 and the department related Machine Group on Select Box-2 (List of Select Box-2 will be loaded acc. to selection on Select-Box-1). In general it is working. But I have following problem: If I select Department (MFT) in SB-1 and select the 3. selection of Machine Group in SB-2 and then change the selection in SB-1 to another department: The correct list belonging to the new department is listed in SB-2, but I see directly the 3. selection of the SB-2's nwe selection list. Normaly I would expect that SB-2 should be reset to a default value (-- Select Machine Group--) How can I do that? In other words: How can I set the selection of a selection box with code to a default or predefined selection?
@page "/connect"
@using System.IO
<select class="Dep" @onchange="func_dep">
<option value="">-- Select Department --</option>
@foreach (var dept in templates_dep)
{
<option value=@dept>@dept</option>
}
</select>
<select class="MG" @onchange="func_MG">
<option value="">-- Select Machine Group --</option>
@foreach (var mgt in templates_MG)
{
<option value=@mgt>@mgt</option>
}
</select>
@code{
List<string> templates_dep = new List<string>() { "",""};
protected override async Task OnInitializedAsync()
{
templates_dep.Clear();
read_dep();
}
public void read_dep()
{
var dep_file = File.ReadAllLines("files\\mae\\dep.csv");
foreach (var s in dep_file)
templates_dep.Add(s);
}
}
@functions {
string selectedString_dep{get; set; }
List<string> templates_MG = new List<string>() { "", "", "", "", "" };
string selectedString_MG {get; set; }
async void func_dep(ChangeEventArgs e)
{
templates_MG.Clear();
var path_mg ="files\\mae\\"+selectedString_dep+"_MG.csv";
var logFile = File.ReadAllLines(path_mg);
foreach (var s in logFile) templates_MG.Add(s);
}
}
Upvotes: 3
Views: 2913
Reputation: 119
I found it easiest to use IJSRuntime and call a pure javascript function to reset it.
For example:
Here is the javascript function:
function resetSelectElement(id) {
var selectElement = document.getElementById(id);
selectElement.selectedIndex = 0; // first option is selected, or
// -1 for no option selected
}
Here is how the javascript function is called from the razor page:
//contruct
@inject IJSRuntime jsRuntime
//call inside a method
await jsRuntime.InvokeVoidAsync("resetSelectElement", "mySelectId");
Upvotes: 1
Reputation: 14533
You can do it with two way binding and C# property setters :
<select @bind=@SelectedOptionA>
<option value="">-- Select Department --</option>
@foreach (var option in A_Options)
{
<option value="@option">@option</option>
}
</select>
<select @bind=@selectedOptionB>
<option value="">-- Select Machine Group--</option>
@foreach (var option in B_Options)
{
<option value="@option">@option</option>
}
</select>
@code {
string selectedOptionA = "";
string selectedOptionB = "";
IEnumerable<string> A_Options = Enumerable.Range(start: 1, count: 10).Select(i => $"AOption-{i}");
IEnumerable<string> B_Options = Enumerable.Empty<string>();
public string SelectedOptionA
{
get => selectedOptionA;
set
{
if (selectedOptionA != value)
{
selectedOptionA = value;
if (value == "")
{
selectedOptionB = "";
B_Options = Enumerable.Empty<string>();
}
else
{
GetBOptions(value);
// Set Default Value
selectedOptionB = GetDefaultOption();
}
}
}
}
private void GetBOptions(string value)
{
// Query real data here
B_Options = Enumerable.Range(start: 1, count: 10)
.Select(i => $"{value}/BOption-{i}")
.ToList();
}
private string GetDefaultOption()
=> B_Options.Skip(random.Next(minValue: 0, maxValue: 9)).First();
Random random = new Random();
}
Upvotes: 5
Reputation: 30016
Here's a demo system for a "Cascading Select" that I put together to answer a similar question on another site.
The demo page:
@page "/Test"
@page "/"
<PageTitle>Index</PageTitle>
<h6>Select Test</h6>
<div class="m-2 p-2 row">
<div class="col-2">
Continent:
</div>
<div class="col-6">
<select class="form-select form-select-sm" value="@model.Continent" @onchange=this.ContinentChange>
<option value="">-- Select A Continent --</option>
@foreach (var continent in Data.Continents)
{
<option value="@continent.Name">@continent.Name</option>
}
</select>
</div>
</div>
<div class="m-2 p-2 row">
<div class="col-2">
Country:
</div>
<div class="col-6">
<select disabled="@this.countryDisabled" class="form-select form-select-sm" value="@model.Country" @onchange=this.CountryChange>
<option value="">-- Select A Country --</option>
@foreach (var item in filteredCountries)
{
<option value="@item.Name">@item.Name</option>
}
</select>
</div>
</div>
<div class="m-2 p-2 bg-light">
<div>
Continent = @model.Continent
</div>
<div>
Country = @model.Country
</div>
</div>
@code {
private CountryData Data = CountryData.Instance();
private Model model = new Model();
private List<Country> filteredCountries = new List<Country>();
private bool countryDisabled => string.IsNullOrWhiteSpace(this.model.Continent);
private void ContinentChange(ChangeEventArgs e)
{
string continent = e.Value?.ToString() ?? string.Empty;
if (!model.Continent.Equals(continent, StringComparison.CurrentCultureIgnoreCase))
{
filteredCountries.Clear();
filteredCountries.AddRange(Data.Countries.Where(item => item.Continent == continent));
model.Country = string.Empty;
model.Continent = continent;
}
}
private void CountryChange(ChangeEventArgs e)
{
string country = e.Value?.ToString() ?? string.Empty;
if (!model.Country.Equals(country, StringComparison.CurrentCultureIgnoreCase))
model.Country = country;
}
public class Model
{
public string Country { get; set; } = string.Empty;
public string Continent { get; set; } = string.Empty;
}
}
And the data set it uses.
namespace BlazorApp3.Data;
public class Continent
{
public string Name { get; set; } = String.Empty;
}
public class Country
{
public string Continent { get; set; } = string.Empty;
public string Name { get; set; } = String.Empty;
}
public class CountryData
{
public IEnumerable<Country> Countries { get; private set; } = Enumerable.Empty<Country>();
public IEnumerable<Continent> Continents { get; private set; } = Enumerable.Empty<Continent>();
private CountryData()
=> this.GetData();
public void GetData()
{
var continents = new List<Continent>();
var continent = new Continent { Name = "Europe" };
continents.Add(continent);
var countries = new List<Country>
{
new Country { Name = "France", Continent = continent.Name },
new Country { Name = "Portugal", Continent = continent.Name },
new Country { Name = "England", Continent = continent.Name },
};
continent = new Continent { Name = "Africa" };
continents.Add(continent);
countries.Add(new Country { Name = "Senegal", Continent = continent.Name });
countries.Add(new Country { Name = "Egypt", Continent = continent.Name });
countries.Add(new Country { Name = "Kenya", Continent = continent.Name });
continent = new Continent {Name = "South America" };
continents.Add(continent);
countries.Add(new Country { Name = "Brazil", Continent = continent.Name });
countries.Add(new Country { Name = "Chile", Continent = continent.Name });
countries.Add(new Country { Name = "Peru", Continent = continent.Name });
this.Continents = continents;
this.Countries = countries;
}
public static CountryData? _instance;
public static CountryData Instance()
{
if (_instance is null)
_instance = new CountryData();
return _instance;
}
}
Upvotes: 1