Hello,
I'm working on a .NET8 Blazor webapp with some InteractiveAutoRenderMode. I'm trying to figure out how to code the HTML/Razor in a Blazor component to be able to display a pair of inputs and then bind a collection of a complex type.
I also want the possibility for the user to add more instances to the collection within the UI/component by being able to add more inputs (through a button click) before submitting the form.
I am not sure how to capture the properties inside the complex type collection for the FieldIdentifier instance usually helping with binding and validation? And then how would that work within a loop for the user to be able to add more instances to the collection?
FieldIdentifier.Create(() => NewProductOfferModel!.LimitedAvailabilities[0].LimitedAvailabilityStartTime)
The HTML for the pair of inputs looks like this:
ManageProductOffer.razor :
<div class="input-group">
<label for="@($"""idAvailabilityStartInput""")">
<input type="datetime-local" id="@($"""idAvailabilityStartInput""")" name="fAvailabilityStart"
step="any" min="@(TimeProvider.GetLocalNow().LocalDateTime.ToString(SortableDateTimePatternFormat))"
class="@(ApplyStyleForValidationState(FieldIdentifier.Create(() => NewProductOfferModel!.LimitedAvailabilities)))"
value="@(NewProductOfferModel!.LimitedAvailabilities[0].LimitedAvailabilityStartTime.ToString(SortableDateTimePatternFormat))"
@onchange=@(changeEventArgs => TryBindAndValidateField(
changeEventArgs: changeEventArgs,
fieldIdentifier: FieldIdentifier.Create(() => NewProductOfferModel!.LimitedAvailabilities[0].LimitedAvailabilityStartTime),
validationDelegate: () => LimitedAvailability.ValidateLimitedAvailability(NewProductOfferModel!.LimitedAvailabilities[0]))) />
</label>
<label for="@($"""idAvailabilityEndInput""")">
<input type="datetime-local" id="@($"""idAvailabilityEndInput""")" name="fAvailabilityEnd"
step="any" min="@(TimeProvider.GetLocalNow().LocalDateTime.ToString(SortableDateTimePatternFormat))"
class="@(ApplyStyleForValidationState(FieldIdentifier.Create(() => NewProductOfferModel!.LimitedAvailabilities)))"
value="@(NewProductOfferModel!.LimitedAvailabilities[0].LimitedAvailabilityEndTime.ToString(SortableDateTimePatternFormat))"
@onchange=@(changeEventArgs => TryBindAndValidateField(
changeEventArgs: changeEventArgs,
fieldIdentifier: FieldIdentifier.Create(() => NewProductOfferModel!.LimitedAvailabilities[0].LimitedAvailabilityEndTime),
validationDelegate: () => LimitedAvailability.ValidateLimitedAvailability(NewProductOfferModel!.LimitedAvailabilities[0]))) />
</label>
<small class="">
<ValidationMessage For="@(() => NewProductOfferModel!.LimitedAvailabilities[0])" />
</small>
</div>
And the code for the model with the complex type collection looks like this:
ProductOfferModel.cs :
public sealed record class ProductOfferModel
{
public Guid ID { get; init; } = Guid.NewGuid();
public String ProductOfferDescription { get; set; } = String.Empty;
public Guid ProductID { get; set; } = Guid.Empty;
public String ProductDescription { get; set; } = String.Empty;
public List<LimitedAvailability> LimitedAvailabilities { get; set; } = [new LimitedAvailability()];
}
public sealed record class LimitedAvailability
{
public Guid ID { get; init; } = Guid.NewGuid();
public DateTime LimitedAvailabilityStartTime { get; set; } = DateTime.MinValue;
public DateTime LimitedAvailabilityEndTime { get; set; } = DateTime.MinValue;
internal static Boolean ValidateLimitedAvailability( LimitedAvailability limitedAvailability )
{
ArgumentNullException.ThrowIfNull(limitedAvailability);
return limitedAvailability.LimitedAvailabilityStartTime < limitedAvailability.LimitedAvailabilityEndTime ?
true
: false;
}
}
The (microsoft documentation) mentions supporting complex type and be able to nest and bind, however it does not seems to mention how to capture the FieldIdentifier accessor for a property inside complex type to customize @onchange or @oninput behavior for example.
Anyone has been solving something similar with using collections of complex types and letting the user add more inputs to the form before submit?