-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
If you create a InputSelect control that is bound (via @bind-Value) to a bool?, it does not work in the same way as InputSelect bound to other nullable types (say int or Enum), and it never displays the null value correctly, but always shows the "false" value.
Expected Behavior
When a Nullable is bound to an InputSelect, the option with value="" should be bound to the null value. This is how other nullable types work with InputSelect, and also is the most useful.
If the model has null, then the option with value="" should be displayed when the form initially shows.
If the select is manually set to the option with value="", then that value should continue to be displayed.
Steps To Reproduce
@page "/"
<EditForm Model="Model" OnValidSubmit="Submit">
<p>
<label>What is your favorite color?</label>
<InputSelect @bind-Value="Model.FavoriteColor">
<option value="">Select a Color</option>
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</InputSelect>
</p>
<p>
<label>How many legs do you have?</label>
<InputSelect @bind-Value="Model.NumberOfLegs">
<option value="">Select a Number</option>
<option value="1">1</option>
<option value="2">2</option>
</InputSelect>
</p>
<p>
<label>Are you awesome?</label>
<InputSelect @bind-Value="Model.Awesome">
<option value="">Select Yes or No</option>
<option value="true">Yes</option>
<option value="false">No</option>
</InputSelect>
</p>
<button>Submit</button>
</EditForm>
@code {
enum Color { Red, Green, Blue };
class InputModel
{
public Color? FavoriteColor { get; set; } = null;
public int? NumberOfLegs { get; set; } = null;
public bool? Awesome { get; set; } = null;
}
InputModel Model = new InputModel();
void Submit()
{
Console.WriteLine($"Color: {Model.FavoriteColor} Legs: {Model.NumberOfLegs} Awesome: {Model.Awesome}");
}
}
When this form is initially shown, the Favorite Color and Number of Legs selects show the "Select..." option, but the Awesome select shows "No". In addition, any attempt to set the "Awesome" select to "Select Yes or No" has it change immediate back to No.
Exceptions (if any)
No response
.NET Version
8.0.200
Anything else?
I think the fix is to change the src/Components/Web/src/Forms/InputSelect.cs implementation of FormatValueAsString to something like:
protected override string? FormatValueAsString(TValue? value)
{
if (typeof(TValue) == typeof(bool)) {
return (bool)(object)value! ? "true" : "false";
}
else if (typeof(TValue) == typeof(bool?)) {
if (value == null)
return null;
else
return (bool)(object)value ? "true" : "false";
}
return base.FormatValueAsString(value);
}
Luckily this method is protected, so I can fix this in the meantime by creating my own component:
public class BetterInputSelect<TValue>: InputSelect<TValue>
{
protected override string? FormatValueAsString(TValue? value)
{
if (typeof(TValue) == typeof(bool)) {
return (bool)(object)value! ? "true" : "false";
}
else if (typeof(TValue) == typeof(bool?)) {
if (value == null)
return null;
else
return (bool)(object)value ? "true" : "false";
}
return base.FormatValueAsString(value);
}
}
But I think the actual InputSelect.cs should be fixed.