In my Blazor page, I have this simple code (ToggleButtonGroup is from here).
<div class="col-lg-6">
<label class="form-label form-field-label">Insert your value</label>
<ToggleButtonGroup Options="@GroupOptions.Options0To10"
@bind-Value="@_session.InteractiveNumber" />
<hr>
</div>
The model I use is defined like that
public class Session {
public int ActiveNumber { get; set; }
}
public Session _session = new();
The ToggleButtonGroup returns a string as a value but I want to store in the database and this is why the Session
is defined like that. How can I cast the value from a string
to int
? Can I use something like @(e => _session.ActiveNumber = e.ToString())
?
For reference see this answer for the previous question on this topic - Bootstrap radio button group
You need to make ToggleButtonGroup
generic. I've modified the code from the original answer:
@using System.Diagnostics.CodeAnalysis
@typeparam TValue
@inherits InputBase<TValue>
<div class="btn-group mt-1 me-2 mb-3" data-toggle="buttons">
@foreach (var item in this.Options)
{
<button type="button" class="@this.GetButtonCSS(item.Value)" @onclick="() => ValueHasChanged(item.Value)">
@item.Label
</button>
}
</div>
@code {
[Parameter, EditorRequired] public IEnumerable<SelectOption<TValue>> Options { get; set; } = Enumerable.Empty<SelectOption<TValue>>();
[Parameter] public string SelectedCss { get; set; } = "btn btn-primary";
[Parameter] public string UnSelectedCss { get; set; } = "btn btn-outline-primary";
// We must implement as it's abstract in InputBase.
// But not used as we bypass the string conversion logic by setting CurrentValue directly
protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TValue result, [NotNullWhen(false)] out string? validationErrorMessage)
{
result = this.CurrentValue!;
validationErrorMessage = null;
return true;
}
private string GetButtonCSS(TValue value)
{
return value?.Equals(this.Value) ?? false
? this.SelectedCss
: this.UnSelectedCss;
}
private void ValueHasChanged(TValue value)
{
// Bypass all the string conversion stuff as we have the value
// Set CurrentValue directly instead of CurrentValueAsString and using the built in string to TValue conversion logic
this.CurrentValue = value;
}
}
public readonly record struct SelectOption<TValue>(TValue Value, string Label);
And Demo page:
@page "/"
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<EditForm Model="_model">
<ToggleButtonGroup Options="_options" @bind-Value="_model.Value1" />
<ToggleButtonGroup Options="_intOptions" @bind-Value="_model.Value2" />
<ToggleButtonGroup Options="_boolOptions" @bind-Value="_model.Value3" />
</EditForm>
<div class="bg-dark text-white m-2 p-2">
<pre>Value1: @_model.Value1</pre>
<pre>Value2: @_model.Value2</pre>
<pre>Value3: @_model.Value3</pre>
</div>
@code {
private List<SelectOption<string>> _options = new() {
new("Yes", "Yes"),
new("No", "No"),
new("Sometimes", "Sometimes")
};
private List<SelectOption<int>> _intOptions = new() {
new(1, "Yes"),
new(0, "No"),
new(-1, "Sometimes")
};
private List<SelectOption<bool>> _boolOptions = new() {
new(true, "On"),
new(false, "Off")
};
private Model _model = new();
public class Model
{
public string Value1 { get; set; } = "N";
public int Value2 { get; set; }
public bool Value3 { get; set; }
}
}