1

I have an enum and a variable of the enum type as follows:

private enum Cities {Berlin, Madrid, Paris, Vienna}
private Cities City;

In the html I have a InputSelect component as follows:

<InputSelect @bind-Value="City">
@foreach(var city in Enum.GetValues(typeof(Cities)))
{
    <option value="@city">@city</option>
}
<br />
@City

This is working fine, and each time I select another city the variable city is updated.

enter image description here

The issue I have is that I need to execute some tasks when a new city is selected. So I need to attach a function to the InputSelect. I cannot add ValueChanged because of the binding. I tried also the following:

<InputSelect ValueChanged="(e)=>TestFunction(e)">
@foreach(var city in Enum.GetValues(typeof(Cities)))
{
    <option value="@city">@city</option>
}
</InputSelect>

But it gives an error. enter image description here

I don't know what to do to make it work. Maybe someone has an idea.

Bert
  • 87
  • 1
  • 6

2 Answers2

1

You don't need to use the Blazor input components unless you are using the built-in validation that comes with EditForm. I use vanilla HTML 99% of the time.

If you want to handle any kind of html input change yourself (not just select), you can provide an onchange method, and handle the arguments yourself. You can see the expected signature by hovering over @onchange after you type it.

<select @onchange=HandleCitySelection>
    <option selected disabled>Select a city. . . </option>
    @foreach (var city in Enum.GetValues(typeof(Cities)))
    {
        <option value="@city">@city</option>
    }
</select>
@if(City is not null)
{
    <div>You selected "@City."</div>
}

@code {
    private enum Cities { Berlin, Madrid, Paris, Vienna }
    private Cities? City;

    async Task HandleCitySelection(ChangeEventArgs e)
    {
        City = (Cities)Enum.Parse(typeof(Cities), e.Value.ToString());
        // Do stuff
    }
}
Bennyboy1973
  • 3,413
  • 2
  • 11
  • 16
1

While @BennyBoy1973 is correct, you can make this work easily with InputSelect.

  1. In the first select I've hooked up the binding get to the field and the set to a handler.

  2. In the second select I've set up the binding manually.

You can run whatever code you like in the handler.

Here's a demo page:

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<div class="bg-dark text-white p-2 m-2">
    <pre>City: @City</pre>
    <pre>TimeStamp: @_timeStamp</pre>
</div>

<InputSelect class="form-select mb-3" @bind-Value:get=this.City @bind-Value:set=this.OnUpdate>
    @foreach (var city in Enum.GetValues(typeof(Cities)))
    {
        <option value="@city">@city</option>
    }
</InputSelect>

<InputSelect TValue=Cities class="form-select mb-3" Value=this.City ValueChanged="OnUpdate" ValueExpression="() => City" >
    @foreach (var city in Enum.GetValues(typeof(Cities)))
    {
        <option value="@city">@city</option>
    }
</InputSelect>

@code {
    private enum Cities { Berlin, Madrid, Paris, Vienna }
    private Cities City;
    private string _timeStamp = string.Empty;

    private void OnUpdate(Cities city)
    {
        City = city;
        _timeStamp = DateTime.Now.ToLongTimeString();
    }
}
MrC aka Shaun Curtis
  • 19,075
  • 3
  • 13
  • 31
  • Thank you very munch. Indeed both solutions are working fine. The solution from Bennyboy1973 is also working fine but I can only check one answer as correct. – Bert Apr 13 '23 at 11:46
  • NP. Main outcome is problem solved and new knowledge acquired. I don't answer questions for the points! – MrC aka Shaun Curtis Apr 13 '23 at 17:34
  • @Bert, I always look for Shaun's answers, as I also learn a lot from him. Today, I learned about the
     tag, which didn't exist in my world yesterday :)
    – Bennyboy1973 Apr 14 '23 at 11:49