2

I need to construct a <select> list with an optional selected item. Currently I'm having to write out two versions depending on whether the selected property of my dictionary item is true.

<InputSelect>
    @foreach (var kvp in ListOfValues)
    {
    if (kvp.Key == SelectedValue)
      {
        <option selected value="@kvp.Key">@kvp.Value</option>
      }
      else
      {
        <option value="@kvp.Key">@kvp.Value</option>
      }
    }
</InputSelect>

However I was hoping to shortcut this process because if additional attributes are required (such as disabled or class it becomes ridiculously complex. Looking around for tutorials I assumed this might work, but it doesn't...

<InputSelect>
    @foreach (var kvp in ListOfValues)
    {
        <option @(kvp.Key == SelectedValue ? "selected" : "") value="@kvp.Key">
            @kvp.Value
        </option>
    }
</InputSelect>

Is there a way to add strings into HTML elements when there isn't a property=value combination?

Further clarity

I can successfully skip if the conditional check and just use <InputSelect @bind-Value="@SelectedValue">, but this question also relates to aspects such as disabled which don't generally render with =value.

EvilDr
  • 8,943
  • 14
  • 73
  • 133
  • Just an idea, you can build markup: https://stackoverflow.com/questions/50604366/is-there-an-equivalent-to-html-raw-in-blazor Hastily prepared example: https://blazorrepl.telerik.com/GnuVlcmE5452qnAH57 – maciek Jul 12 '23 at 20:55
  • 2
    @maciek In this case, there's a much easier method. html valueless keywords like `selected` and `disabled` can be optionally rendered in Blazor using boolean logic: `selected="@(SomeBooleanExpression)"` Blazor knows what to do with that. – Bennyboy1973 Jul 13 '23 at 04:53
  • Thank you. @Bennyboy1973 do you know if there's documentation around this aspect? It's curious that Blazor renders a shortened version (without true/false strings appended to the markup). While I guess its completely HTML5 standards-compliant, it does seems a little unintuitive IMHO. – EvilDr Jul 13 '23 at 07:39

1 Answers1

2

If you wanna render selected attribute via

@(kvp.Key == SelectedValue ? "selected" : "")

It will report an error:

Failed to execute 'setAttribute' on 'Element': '@(kvp.Key' is not a valid attribute name.

HTML element attributes are conditionally rendered based on the .NET value. If the value is false or null, the attribute isn't rendered. If the value is true, the attribute is rendered minimized. So if you wanna shortcut the first process, You can use this method to render the selected attribute by condition.

@foreach (var kvp in ListOfValues)
        {
            <option value="@kvp.Key" selected="@(kvp.Key==SelectedValue)">
                @kvp.Value
            </option>
        }
Xinran Shen
  • 8,416
  • 2
  • 3
  • 12
  • Thank you, that's fixed it. Do you know if there's a reason the dev's chose the approach to render the attribute minimised if `true`? I can find the source code for `` but not the render code for the actual list item options. I'd be interested to read up on their approach. – EvilDr Jul 13 '23 at 07:34
  • 1
    Sorry, I don't know about it. I think you can post an issue about it in Blazor github, Maybe the Blazor developer will response you. – Xinran Shen Jul 13 '23 at 07:38