DEV Community

jsakamoto
jsakamoto

Posted on • Updated on

[Workaround] How to two-way data binding of radio button input with Blazor SPA (v.0.5.x)?

Introduction: What's "Blazor"?

"Blazor" is a Single Page Web Application (a.k.a "SPA") framework.

Blazor allows you to running C# code and .NET Standard 2.0 native assembly (.dll) on top of a modern web browser, without any .NET server processes.

If you are new to Blazor, I recommend watching this YouTube video.

NDC Oslo 2017 - "Web Apps can’t really do that, can they? - Steve Sanderson"

The video was about prototype of Blazor, and the current version when I wrote this post was v.0.5.1, which had some breaking changes. But that video is useful to understanding the concept and pros/cons of "Blazor".

Two-way data binding of Blazor

Blazor is a SPA framework, so you can two-way bind a data to input or select/option elements easily, like this:

@functions {
    int EditionCode = 1;
}

<select bind="@EditionCode">
  <option value="1">Home</option>
  <option value="2">Pro</option>
  <option value="3">Enterprise</option>
</select>
Enter fullscreen mode Exit fullscreen mode

Blazor provides those two-way data binding mechanism by "bind=..." syntax.

"bind" syntax doesn't work for radio button inputs!

However, as an exception, you can't two-way data bind to radio button input elements by "bind=..." syntax, at this time (Blazor v.0.5.x).

The following sample code doesn't work.

@functions {
    int EditionCode = 1;
}

<label>
  <input type="radio" name="edition" value="1" bind="@EditionCode"/> Home
</label>
<label>
  <input type="radio" name="edition" value="2" bind="@EditionCode"/> Pro
</label>
<label>
  <input type="radio" name="edition" value="3" bind="@EditionCode"/> Enterprise
</label>
Enter fullscreen mode Exit fullscreen mode

I can expect that above code will work fine in the near future, but Blazor v.0.5.x does not allow that code yet.

What can we do?

Workaround for this problem

Don't worry. There is workaround.

Two-way data binding of radio button input elements can be done as follows:

@functions {
    int EditionCode = 1;
}

<label>
  <input type="radio" name="edition" checked="@(EditionCode == 1)" onchange="@(() => EditionCode = 1)"/> Home
</label>
<label>
  <input type="radio" name="edition" checked="@(EditionCode == 2)" onchange="@(() => EditionCode = 2)"/> Pro
</label>
<label>
  <input type="radio" name="edition" checked="@(EditionCode == 3)" onchange="@(() => EditionCode = 3)"/> Enterprise
</label>
Enter fullscreen mode Exit fullscreen mode

The code checked="@(EditionCode == ...)" works as "from data to DOM" one-way binding.

The other way, the code onchage="@(() => EditionCode = ...)" works as "from DOM to data" one-way binding.

You can implement two-way binding to radio button inputs by combine these two codes.

Of course, you can also build radio button inputs dynamically, like this:

@functions {
    int EditionCode = 1;

    // "Edition" class has "int Code" and "string Text" properties.
    Edition[] Editions = new [] {
      new Edition { Code = 1, Text = "Home" },
      new Edition { Code = 2, Text = "Pro" },
      new Edition { Code = 3, Text = "Enterprise" },
    };
}

@foreach (var edition in this.Editions)
{
<label>
  <input type="radio" 
         name="edition"
         checked="@(EditionCode == edition.Code)"
         onchange="@(() => EditionCode = edition.Code)"/>
         @edition.Text
</label>
}
Enter fullscreen mode Exit fullscreen mode

This workaround is not cool and smart, but it works fine anyway.

The future release of Blazor will be supported "bind" syntx for radio button inputs, I think.

See also:

Bind does not yet handle radio buttons #5579

I have the the following in my cshtml

    <td>
        <input type="radio" name="vacation" bind="@northwestVacation" /> Northwest @northwestVacation<br>
        <input type="radio" name="vacation" bind="@sinaiVacation" /> Sinai @sinaiVacation
    </td>

with corresponding properties northwestVacation and sinaiVacation in my code. During a debug session I see the get called numerous times for each but even with a true value the corresponding radio button is not in the selected state. And, as I select either button I never see the set called on either property.

Let's look forward to the new release of Blazor!

Happy coding with Blazor :)

Top comments (2)

Collapse
 
markstega profile image
MarkStega

I believe that you need to add the 'name' attribute to the radio button group to get them to function as radio buttons (per the example of mine that you quoted from GitHub). Otherwise this is a very clean work-aound while waiting for binding to be implemented.

Collapse
 
j_sakamoto profile image
jsakamoto

I believe that you need to add the 'name' attribute to the radio button group

Oh, You are right! That is my mistake.

I fixed it just now.

Thanks a lot!