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.
Yes, radio buttons aren't one of the supported input elements yet. This is a good thing to add to the backlog.
@SteveSandersonMS
It appears that the issue for the input type of radio is the generated code for the GetValue (100) against 'value'
builder5.OpenElement(97, "input");
builder5.AddAttribute(98, "type", "radio");
builder5.AddAttribute(99, "name", "vacation");
builder5.AddAttribute(100, "value", Microsoft.AspNetCore.Blazor.Components.BindMethods.GetValue(northwestVacation));
builder5.AddAttribute(101, "onchange", Microsoft.AspNetCore.Blazor.Components.BindMethods.SetValueHandler(__value => northwestVacation = __value, northwestVacation));
as opposed to a checkbox with the same binding that generates the GetValue (117) against 'checked'
builder5.OpenElement(115, "input");
builder5.AddAttribute(116, "type", "checkbox");
builder5.AddAttribute(117, "checked", Microsoft.AspNetCore.Blazor.Components.BindMethods.GetValue(northwestVacation));
builder5.AddAttribute(118, "onchange", Microsoft.AspNetCore.Blazor.Components.BindMethods.SetValueHandler(__value => northwestVacation = __value, northwestVacation));
I gave a shot at understanding the Blazor BindTagHelperDescriptorProvider()
where I believe this code is being generated I think by the GetElementBindData()
.
As far as I can tell all that is needed for radio support is the addition of one line to BindAttributes.cs of
[BindInputElement("radio", null, "checked", "onchange")]
to get the appropriate element of a radio button to get the value of the binding.
@SteveSandersonMS
Adding the [BindInputElement(...)]
to BindAttributes.cs does indeed make the code adding the attributes the same for a checkbox or a radio button. However, that isn't enough. So I have some more spelunking of the Blazor project to do (And I was hoping for the simplest one line PR ever )
@SteveSandersonMS
The exploration continues. I added code to EventForDotNet.ts
in FromDOMEvent()
of
case 'change': {
const targetIsCheckbox = isCheckbox(element);
const targetIsRadio = isRadio(element);
const newValue = (targetIsCheckbox || targetIsRadio) ? !!element['checked'] : element['value'];
return new EventForDotNet<UIChangeEventArgs>('change', { type: event.type, value: newValue });
}
function isRadio(element: Element | null) {
return element && element.tagName === 'INPUT' && element.getAttribute('type') === 'radio';
}
I see the first assignment of the radio button in the property but not subsequent changes. I guess this means I need to figure out the caller of FromDOMEvent()
Hello, what the current situation on this subject
I was using this kind of code until now, was worked in preview 3/4, but today i see it not work on preview 5, the checked is not render correctly, but the on change still working
<label class="form-check-label">
<input class="form-check-input" type="radio" name="rbSelectChildren" checked="@(Model.ShowAllDossiers == true)" onchange="@(() => Model.ShowAllDossiers = true)" />
Tous les dossiers
</label>
<label class="form-check-label">
<input class="form-check-input" type="radio" name="rbSelectChildren" checked="@(Model.ShowAllDossiers == false)" onchange="@(() => Model.ShowAllDossiers = false)" />
Uniquement les
</label>
Hello, same question to @SteveSandersonMS ...
Do you advance to the issue ?
Thanks
Has this been figured out yet? Preview 9 (and therefore RTM) is eminent.
Radio buttons are not hard to work with in Blazor - I have a gist and Blazor Fiddle that demonstrates this here : https://gist.github.com/SQL-MisterMagoo/bc5713fb26bf84bf810d48d1f45c361a
Essentially a similar implementation but with an integer backing store:
<tr>
<th>
Saturday display:
</th>
<td align="left">
<input type="radio" name="group" checked="@(pGroupCode == 0)" @onchange="@(() => pGroupCode = 0)" /> Group with Friday<br />
<input type="radio" name="group" checked="@(pGroupCode == 1)" @onchange="@(() => pGroupCode = 1)" /> Group with Monday<br />
<input type="radio" name="group" checked="@(pGroupCode == 2)" @onchange="@(() => pGroupCode = 2)" /> Do not show
</td>
</tr>
and the code:
protected int pGroupCode { get; set; }
In case anyone is interested, here is it for F# and Bolero (which implements a Model-View-Update programming model on top of Blazor): https://github.com/fsbolero/Bolero/issues/75
Solution with 2 components (RadioGroup & Radio): https://blazorfiddle.com/s/zwogor6l
<RadioGroup GroupName="osType" @bind-Value="OsType">
<ul>
<li><Radio Value="Windows" /> win</li>
<li><Radio Value="Linux" /> linux</li>
<li><Radio Value="Mac" /> mac</li>
<li><Radio Value="Android" Disabled="true" /> android </li>
</ul>
</RadioGroup>
selected: @OsType
@code {
public string OsType {get; set;}
}
@SteveSandersonMS and I have chatted about this. We think that the current best solution for this is to do it manually instead of using bind, as there's more complexity involved and would likely require compiler changes.
```razor
@foreach (var choice in new[] { Choices.Red, Choices.Green, Choices.Blue })
{
}
You chose: @currentChoice
@code {
enum Choices { Red, Green, Blue };
Choices currentChoice = Choices.Red;
}
```
That's exactly how I have my radio buttons implemented; It certainly works but isn't very 'pretty'. I'd still like to see bind working sometime in the future but it obviously isn't a showstopper.
@SteveSandersonMS and I have chatted about this. We think that the current best solution for this is to do it manually instead of using bind, as there's more complexity involved and would likely require compiler changes.
@foreach (var choice in new[] { Choices.Red, Choices.Green, Choices.Blue }) { <label> <input name="yourColor" type="radio" value="@choice" checked="@(currentChoice == choice)" @onchange="@(() => { currentChoice = choice; })" /> @choice.ToString() </label> } <p>You chose: @currentChoice</p> @code { enum Choices { Red, Green, Blue }; Choices currentChoice = Choices.Red; }
@javiercn Thanks for posting this workaround - it would be nice if an area in the MSDN documentation could be created for things like this so we don't have to scour GitHub.
These solutions are still problematic if you are depending on the EditContext
notifying you of a change through the OnFieldChangedEvent
as it does not get fired.
We don't have an InputRadio component itself that works with forms.
This is something that could be built, but I suggest filing a separate issue to track it elsewhere instead of here.
Any news on this yet? I can't get Blazor radio buttons to work with enums and the docs example given does not work? https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-3.1
@SteveHindmarsh while binding directly may not work yet, writing a component that generates all the radio buttons from an enum isn't that hard.
Yes the Blazor paradigm makes things blisteringly simple once you start getting familiar however, if I hadn't wasted time with the incorrect documentation I may have now had exactly that. Anyhow it's allowed me to get familiar with EditContext.OnFieldChanged and the EditContext.NotifyFieldChanged event which has allowed me to program a solution. Blazor rocks!
Most helpful comment
@SteveSandersonMS and I have chatted about this. We think that the current best solution for this is to do it manually instead of using bind, as there's more complexity involved and would likely require compiler changes.
```razor
@foreach (var choice in new[] { Choices.Red, Choices.Green, Choices.Blue })
{
}
You chose: @currentChoice
@code {
enum Choices { Red, Green, Blue };
Choices currentChoice = Choices.Red;
}
```