Reputation: 70
I am trying to make a dynamic form system and I want to be able to bind an InputCheckbox to a database field that's a string rather than a bool...
<EditForm Model="@theEntryResults" OnValidSubmit="@SaveEntries">
<div class="row">
<div class="col-6">
@foreach (var entry in theEntryResults)
{
<div class="form-group m-2">
<label>
@entry.Field.FieldName:
@switch (entry.Field.FieldTypeID)
{
case 0:
<InputText @bind-Value="@entry.Value" class="form-control"></InputText>
break;
case 1:
<InputSelect @bind-Value="@entry.Value" class="form-select">
<option value=""></option>
@foreach (var option in entry.Field.Choices)
{
<option value="@option.Value">@option.Name</option>
}
</InputSelect>
break;
case 2:
<InputCheckbox @bind-Value="@MyValue" class="form-check-inline" style="width: 50px; height: 50px;"></InputCheckbox>
break;
}
</label>
</div>
}
</div>
</div>
<button class="btn btn-success" type="submit">Save</button>
</EditForm>
is what I am trying but entry.Value is a string and so this is giving me "Cannot convert string to bool"
Any ideas?
Thanks!
Upvotes: 0
Views: 1608
Reputation: 3710
An example to bind string to an InputCheckbox
would be by using a component
where the string can be converted to boolean and bind to InputCheckBox
and vice versa.
Component:
@* MyInputCheckBox.razor *@
<InputCheckbox @bind-Value="isCheck"
class="form-check-inline"
style="width: 50px; height: 50px;"/>
@code {
[Parameter]
public string CheckValueStr { get; set; }
[Parameter]
public EventCallback<string> CheckValueStrChanged { get; set; }
private bool _isCheck;
public bool isCheck
{
get { return _isCheck; }
set {
_isCheck = value;
CheckValueStrChanged.InvokeAsync(value.ToString());}
}
protected override void OnInitialized()
{
isCheck = bool.Parse(CheckValueStr);
}
}
Page:
@page "/"
@using BlazorApp2.Components
<EditForm Model="sample">
<MyInputCheckBox @bind-CheckValueStr="@sample.CheckValue" />
</EditForm>
<br/>
@sample.CheckValue
@code {
private Sample sample = new Sample();
public class Sample
{
public string CheckValue = "false";
}
}
Output:
Upvotes: 0
Reputation: 9162
Bind it to a bool in your code section of the component and then translate in the getters and setters of that.
<InputCheckbox @bind-Value=@MyValue />
@code {
bool MyValue
{
get => Convert.ToBoolean(entry.Value);
set => entry.Value = value.ToString();
}
}
As you are using a for each loop, my recommendation would be to use a child-component for each entry (e.g. EntryViewComponent), so that each child-component is focused on working with an individual entry. In this way, the above suggestion would still apply.
@foreach (var entry in theEntryResults)
{
<EntryViewComponent Entry=@entry />
}
EntryViewComponent
<markup that was previously in the for-each loop>
@code {
[Parameter] public EntryClass Entry { get; set; }
// similar code to first suggestion above
}
If you wish to continue using mark-up inside the for each loop instead of a component, the following may work:
<InputCheckbox Value=@(Convert.ToBoolean(entry.Value))
ValueChanged=@((v) => entry.Value = v.ToString()) />
In this code, instead of auto-binding, you are using different code for the setting of the value of the checkbox and the handling of a value change from the checkbox.
Upvotes: 1