Hi Everyone,
I am trying to include a component in my TelerikForm which will contain a <FormGroup>, <FormItems> and all the bits for a mailing address. This has been giving me some grief and I would love some help. Here's what I have:
Here's the outside component:
@page "/agencies/new"
@using kpow.interfaces.Services.Agencies
@using kpow.Ui.Components
@inject IAgencies AgencyService
<TelerikForm EditContext="formContext">
<FormValidation>
<DataAnnotationsValidator></DataAnnotationsValidator>
<TelerikValidationSummary />
</FormValidation>
<FormItems>
<FormItem Field="@nameof(Agency.Name)" LabelText="Name" />
<FormItem Field="@nameof(Agency.AgencyType)" LabelText="Agency Type" />
<AddressSubForm
Address="@Agency.Address"
SetAddress="address => Agency.Address = address"/>
</FormItems>
</TelerikForm>
@code {
private Agency Agency { get; } = new() { Address = new Address() };
EditContext formContext { get; set; }
protected override void OnInitialized()
{
formContext = new EditContext(Agency);
base.OnInitialized();
}
}
Here's the AddressSubForm Component:
@inject interfaces.Services.Ports.ICountries CountryService
<FormGroup LabelText="Address">
<FormItem Field="@nameof(Address.ToLine)" LabelText="ToLine" ></FormItem>
<FormItem Field="@nameof(Address.Street1)" LabelText="Street"></FormItem>
<FormItem Field="@nameof(Address.Street2)" LabelText="Street 2"></FormItem>
<FormItem Field="@nameof(Address.City)" LabelText="City"></FormItem>
<FormItem Field="@nameof(Address.PostalCode)" LabelText="Postal Code"></FormItem>
@if (ShowRegions == true)
{
<FormItem Field="@nameof(RegionId)" LabelText="Region">
<Template>
<TelerikDropDownList Data="@regions"
TextField="Name"
ValueField="Id"
@bind-Value="RegionId">
</TelerikDropDownList>
</Template>
</FormItem>
}
<FormItem Field="@nameof(CountryId)" LabelText="Country">
<Template>
<TelerikDropDownList Id="cbCountries"
TextField="Name"
ValueField="Id"
Data="@countries"
OnChange="CountryChanged"
@bind-Value="CountryId">
</TelerikDropDownList>
</Template>
</FormItem>
</FormGroup>
@code {
[Parameter] public Address Address { get; set; } = new Address();
[Parameter] public Func<Address, Address>? SetAddress { get; set; }
private IEnumerable<Country>? countries { get; set; }
private IEnumerable<Region>? regions { get; set; }
private bool ShowRegions { get; set; } = false;
private string ToLine { get; set; } = string.Empty;
private string Street1 { get; set; } = string.Empty;
private string? Street2 { get; set; } = string.Empty;
private string City { get; set; } = string.Empty;
private int? RegionId { get; set; } = null;
private string PostalCode { get; set; } = string.Empty;
private int? CountryId { get; set; } = null;
{
ToLine = Address.ToLine;
Street1 = Address.Street1;
Street2 = Address.Street2;
City = Address.City;
RegionId = Address.RegionId;
PostalCode = Address.PostalCode;
CountryId = Address.CountryId;
countries = await CountryService.GetAll();
}
private async Task CountryChanged(object value)
{
CountryId = (int)value; // Ensure CountryId is updated
Address = SetAddress(Address with { CountryId = (int)value, RegionId = null });
switch (CountryId)
{
case 185: //usa
case 32: //canada
{
regions = await CountryService.GetRegions(CountryId.Value);
ShowRegions = true;
break;
}
default:
{
ShowRegions = false;
break;
}
}
}
private void RegionChanged(object value)
{
Address = SetAddress(Address with { RegionId = (int)value });
}
}
When this runs, I can see the rendered labels in the right place for the Address, but the countries drop down is not filled even though the data is present in the OnInitializedAsync when it calls await CountryService.GetAll(); Also, none of the form fields in Address render - only the label. There is an error in console per field in the Address component that is not using a template:
Unhandled exception rendering component: Value cannot be null. (Parameter 'For')
System.ArgumentNullException: Value cannot be null. (Parameter 'For')
at Telerik.Blazor.Components.Common.BaseComponent.ThrowIfParameterIsNull(Object argumentValue, String argumentName)
at Telerik.Blazor.Components.Validation.ValidationMessageBase`1[[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnParametersSet()
at Microsoft.AspNetCore.Components.ComponentBase.CallOnParametersSetAsync()
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
I'm looking forward to hearing your ideas! Thanks!
-scott