I have an order page in my blazor app that accepts details of an order, with a table where order lines are added. I have a function called "CalculateTotals()" which needs to be called every time a field is changed, like quantity or unit price, to update the totals in the UI, before the user submits the order form.
It seems that all of the functionality works fine for any controls other than <select>. In each order line there is also a collection of "taxes". This is presented by looping through the tax lines, per order line and showing a dropdown where the user selects a tax code. When the selection is made, it seems that @onchange is triggered, as I can see the value change in the json output of the model, but the CalculateTotals function is never called, so the onfieldchanged event in my code isn't being triggered. It seems that it is doing this for any <select> that I use, regardless of where it is in the editform. I use instead of <InputSelect> as my dropdown values are Guids. Anyone have an idea why the onFieldChange event wouldn't be triggered as a model field change? Below is a snippit of my code.
<EditForm EditContext="@formContext">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="row">
<div class="col-12">
<div class="card">
<div class="row">
<div class="col-12">
<div class="table-responsive">
<table class="table mt-4" ondragover="event.preventDefault();">
<thead>
<tr>
<th>#</th>
<th>Description</th>
<th>Quantity</th>
<th>Unit Cost</th>
<th>Taxes</th>
<th class="text-right">Total</th>
</tr>
</thead>
<tbody>
@if (order.OrderLines != null)
{
foreach (var line in order.OrderLines.OrderBy(x => x.LineNumber))
{
<tr >
<div id="dragdiv" class="dragula-handle" draggable="true" @ondrop="@(()=> Drop(line))" @ondrag="@(()=> StartDrag(line))" @key="line.Id"></div>
<td>
<InputText id="item-desc" @bind-Value="line.Description" class="form-control form-control-sm" disabled="@FormDisabled" placeholder="Description" />
</td>
<td>
<InputNumber id="item-qty" @bind-Value="line.Quantity" class="form-control form-control-sm" disabled="@FormDisabled" placeholder="Qty" />
</td>
<td>
<InputNumber id="item-unit-cost" @bind-Value="@line.AmountPerUnit" class="form-control form-control-sm" disabled="@FormDisabled" placeholder="Unit Cost" />
<ValidationMessage For="@(() => line.AmountPerUnit)" />
</td>
<td>
@if (line.Taxes != null)
{
foreach (var tax in line.Taxes)
{
<select id="[email protected]" @bind="tax.TaxCodeId" class="form-control">
@if (taxCodes != null)
{
foreach (var taxcode in taxCodes)
{
<option value="@taxcode.Id">@taxcode.Name</option>
}
}
</select>
}
}
</td>
</tr>
}
}
</tbody>
</table>
</div> <!-- end table-responsive-->
</div> <!-- end col -->
</div>
<!-- end row -->
</div> <!-- end card-body-->
</div> <!-- end card -->
</div> <!-- end col-->
</div>
</EditForm>
@code {
protected override async Task OnInitializedAsync()
{
await Load();
formContext = new EditContext(order);
formContext.OnFieldChanged += EditContext_OnFieldChanged;
await base.OnInitializedAsync();
}
private void EditContext_OnFieldChanged(object sender,FieldChangedEventArgs e)
{
Console.WriteLine(e.FieldIdentifier.FieldName);
if (formContext.Validate())
{
// You can validate the EditContext here, and do necessary
CalculateTotals();
}
}
}