I have a Telerik Grid and EditForm side-by-side on a page. The EditForm displays the selected object upon clicking a grid row. Below is an excerpt of my custom form component.
@typeparam TEntity where TEntity : class, IEntity, new()
<div>
<TelerikGrid
@ref="GridRef"
Pageable="true"
Sortable="true"
Resizable="true"
ShowColumnMenu="true"
Reorderable="true"
PageSize="50"
SelectionMode="@GridSelectionMode.Single"
SelectedItems="@_selectedItems"
SelectedItemsChanged="@((IEnumerable<TEntity> list) => OnGridSelectedItemsChanged(list))"
OnRowClick="@OnGridRowClick"
OnRead="GetGridData"
EnableLoaderContainer="true">
@* toolbar, columns, etc. *@
</TelerikGrid>
<EditForm EditContext="@_editContext" OnSubmit="OnSubmitAsync">
<TelerikDateTimePicker Placeholder=" "
Value="(DateTime?)PropertyValue"
ValueExpression="ValueExpression<DateTime?>()"
ValueChanged="(DateTime? val) => OnValueChanged(val)"
Readonly="true">
</TelerikDateTimePicker>
</EditForm>
</div>
@code {
private EditContext? _editContext;
private IEnumerable<TEntity> _selectedItems = Enumerable.Empty<TEntity>();
private TEntity? _selectedItem;
[CascadingParameter] public TEntity? Entity { get; set; }
protected override void OnInitialized()
{
_editContext = new(Entity);
_editContext.OnFieldChanged += OnFieldChanged!;
}
// Override the grid's built-in row selection by handling the SelectedItemsChanged event. Do not execute any logic in it to let the OnGridRowClick handle the selection.
// https://docs.telerik.com/blazor-ui/knowledge-base/grid-select-or-deselect-item-on-row-click
private void OnGridSelectedItemsChanged(IEnumerable<TEntity> selectedList)
{
}
private async Task OnGridRowClick(GridRowClickEventArgs args)
{
var currItem = args.Item as TEntity;
if (currItem?.Id == _selectedItem?.Id) return;
var discardChanges = await ConfirmDiscardFormChangesAsync();
if (!discardChanges) return;
_selectedItems = new[] { currItem };
_selectedItem = _selectedItems.First();
}
private async Task OnValueChanged(object? value)
{
// not getting fired when grid's selected item is changed, which is good
}
private void OnFieldChanged(object sender, FieldChangedEventArgs args)
{
// gets fired when grid's selected item is changed
// _editContext.IsModified() is true here
}
}
Whenever the form displays an item upon clicking a different row with DateTime field value different from the previously selected one, the EditContext's IsModified() becomes true. This is not the case when I replace the TelerikDateTimePicker with Blazor's InputDate component.
When user click on the input field of DatePicker, it either select date, or month, or year, but we want to select whole date input field like it highlights/selects whole content on Tab key.
Tried with the following code but still no luck.
<span @onfocusin="@FocusHandler">
<TelerikDatePicker @bind-Value="@SelectedDate"
Min="@Min"
Max="@Max"
Format="MM/dd/yyyy"
DebounceDelay="@DebounceDelay"
ShowWeekNumbers="true"
@ref="@DateRef">
<DatePickerFormatPlaceholder Day="day" Month="month" Year="year" />
</TelerikDatePicker>
</span>
@code {
private DateTime? SelectedDate { get; set; }
private DateTime Max = new DateTime(2050, 12, 31);
private DateTime Min = new DateTime(1950, 1, 1);
private int DebounceDelay { get; set; } = 200;
private TelerikDatePicker<DateTime?> DateRef { get; set; }
private async Task FocusHandler()
{
await DateRef.FocusAsync();
}
}
It gets selected on buttonclick though (code snippet below where it selects all content on button click) -
<TelerikButton OnClick="@FocusHandler">Focus Date</TelerikButton>
<TelerikDatePicker @bind-Value="@SelectedDate"
Min="@Min"
Max="@Max"
Format="MM/dd/yyyy"
DebounceDelay="@DebounceDelay"
ShowWeekNumbers="true"
@ref="@DateRef">
<DatePickerFormatPlaceholder Day="day" Month="month" Year="year" />
</TelerikDatePicker>
@code {
private DateTime? SelectedDate { get; set; }
private DateTime Max = new DateTime(2050, 12, 31);
private DateTime Min = new DateTime(1950, 1, 1);
private int DebounceDelay { get; set; } = 200;
private TelerikDatePicker<DateTime?> DateRef { get; set; }
private async Task FocusHandler()
{
await DateRef.FocusAsync();
}
}
Any help would be appreciated! TIA.
-Neelima
I am trying to perform the following in a Blazor app. Default value = DateTime.Now. When a user enters a MMddyy or MMddyyyy I want to automatically format the date to MM/dd/yyyy. But I'm having an issue where the control automatically formats back to the default date value. Below is my layout for the DatePicker. I've tried different variations based on the demos Telerik provides but no luck. Hope someone can help. Thanks!
<TelerikDatePicker Id="@CustomComponent.FieldLabel"
Hi,
Is there a way of having a timespan (or duration) component in Blazor at all, like the one mentioned here for Xamerin:
https://www.telerik.com/blogs/choose-time-duration-telerik-timespan-picker-xamarin
Apologies if I have missed it in the docs.
Regards,
Rawden.
Hey,
I'm using the TelerikDatePicker in a grid edited row and I want to stop changing values when I click the keyboard arrows. Is there any solution to stop this ?
Thanks.
Hi,
when using the DatePicker or DateTimePicker in my project i get the following error when focus is lost in Firefox:
Uncaught (in promise) Error: System.Collections.Generic.KeyNotFoundException: Arg_KeyNotFoundWithKey, inputElementValue at System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Text.Json.JsonElement, System.Text.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51]].get_Item(String ) at Telerik.Blazor.Components.Common.DateInputs.DateInput`1[[System.DateTime, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].DateInput_Focus(Dictionary`2 args) at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.InvokeSynchronously(JSRuntime , DotNetInvocationInfo& , IDotNetObjectReference , String ) at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(JSRuntime , DotNetInvocationInfo , String )
How to reproduce:
I use VS2022 .NET 7, Telerik Blazor 4.1.0
Just create a Blazor WASM Client project. Add the DatePicker. Publish with AOT and run in Firefox. Current culture is set to german.
Simply set the focus on the datepicker, then hit "Tab"-key to switch to another component. Then I get the above error.
When using Chrome, this does not happen. Also tested on different machines. Error occurs only in Firefox.
If you need more information please let me know.
Regards,
Thomas
I recall being told I would have access to source code once I buy a licence.
Now that I have a licence, how do I get access to the source so I can do a local build?
Hi,
I am working on a dynamic form generator which is capable of generating a form based on a Json formdefinition retrieved from the server. I had some hurdles, but so far things are progressing nicely. Here's a summary of how it works (or should work):
TelerikTextBox and TelerikRadioButtonGroup work like a charm (they both use string properties of the dynamically created model). However the TelerikNumericTextBox and TelerikDateTimePicker generate the following error (and show a red line in the razor file:
Error (active) CS0411 The type arguments for method 'TypeInference.CreateTelerikNumericTextBox_0<T>(RenderTreeBuilder, int, int, string, int, T, int, Expression<Func<T>>, int, int, int, T, int, string, int, EventCallback<object>, int, EventCallback<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Error (active) CS0411 The type arguments for method 'TypeInference.CreateTelerikDatePicker_1<T>(RenderTreeBuilder, int, int, string, int, T, int, Expression<Func<T>>, int, EventCallback<object>, int, EventCallback<T>, int, string)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
I assume it has something to do with the type of the propery, but I am not sure. Here's the full code of the dynamic form so far.
@namespace TrueLime.Blazor.TrueForms
@inherits TrueFormBase
<TelerikForm EditContext="@FormEditContext"
OnSubmit="@HandleSubmit">
<FormValidation>
<DataAnnotationsValidator></DataAnnotationsValidator>
</FormValidation>
<FormItems>
@foreach (var propertyInfo in GetFormFieldProperties())
{
<FormItem Field="@(propertyInfo.Name)">
<Template>
<div class="mb-1 row">
<label for="@(propertyInfo.Name)" class="k-label k-form-label col-sm-2">@propertyInfo.DisplayName()</label>
<div class="col-sm-8">
@switch (GetFormControlType(propertyInfo.Name))
{
case "textbox":
<TelerikTextBox Id="@(propertyInfo.Name)"
Value="@GetStringValue(propertyInfo.Name)"
ValueExpression="@(() => propertyInfo.Name)"
OnChange="OnChange"
ValueChanged="@(value => OnValueChanged(value, propertyInfo.Name))"
InputMode="text"
PlaceHolder="@propertyInfo.PlaceholderDescription()">
</TelerikTextBox>
break;
case "decimaltextbox":
<TelerikNumericTextBox Id="@(propertyInfo.Name)"
Value="@GetDecimalValue(propertyInfo.Name)"
ValueExpression="@(() => propertyInfo.Name)"
Decimals="2"
Step="0.01m"
Format="@CurrencyFormat"
OnChange="OnChange"
ValueChanged="@(value => OnValueChanged(value, propertyInfo.Name))">
</TelerikNumericTextBox>
break;
case "datepicker":
<TelerikDatePicker Id="@(propertyInfo.Name)"
Value="@GetDateTimeValue(propertyInfo.Name)"
ValueExpression="@(() => propertyInfo.Name)"
OnChange="OnChange"
ValueChanged="@((DateTime value) => OnValueChanged(value, propertyInfo.Name))"
Placeholder="@propertyInfo.PlaceholderDescription()"
>
</TelerikDatePicker>
break;
case "radiogroup":
<TelerikRadioGroup Id="@(propertyInfo.Name)"
Value="@GetStringValue(propertyInfo.Name)"
ValueExpression="@(() => propertyInfo.Name)"
OnChange="OnChange"
ValueChanged="@((string value) => OnValueChanged(value, propertyInfo.Name))"
Layout="@GetRadioGroupLayout(propertyInfo.Name)"
Data="@GetFormOptions(propertyInfo.Name)"
ValueField="@nameof(FormOption.Value)"
TextField="@nameof(FormOption.Text)">
</TelerikRadioGroup>
break;
}
</div>
<div class="col-sm-2">
<TrueFormValidationMessage For="@(new FieldIdentifier(FormModel, propertyInfo.Name))" />
</div>
</div>
</Template>
</FormItem>
}
</FormItems>
<FormButtons>
<TelerikButton ButtonType="ButtonType.Submit">@SubmitButtonLabel</TelerikButton>
</FormButtons>
</TelerikForm>
<br/>
@ScreenLog
Here's the OnValueChanged (which needs work, but the get the gist of it):
protected void OnValueChanged(object e, string propertyName) { var propertyInfo = FormInputModel.GetType().GetProperty(propertyName); if (propertyInfo == null) return; if (propertyInfo.PropertyType == typeof(int)) SetFormValue(propertyInfo.Name, Convert.ToInt32(e)); if (propertyInfo.PropertyType == typeof(long)) SetFormValue(propertyInfo.Name, Convert.ToInt64(e)); if (propertyInfo.PropertyType == typeof(decimal)) { // Needs work SetFormValue(propertyInfo.Name, Convert.ToDecimal(e, new CultureInfo("nl-NL", false))); } if (propertyInfo.PropertyType == typeof(string)) SetFormValue(propertyInfo.Name, e.ToString()); //if (propertyInfo.PropertyType == typeof(DateTime) || propertyInfo.PropertyType == typeof(DateTime?)) // throw new NotImplementedException("DateTime nog niet geimplementeerd."); //if (propertyInfo.PropertyType == typeof(bool) || propertyInfo.PropertyType == typeof(bool)) // throw new NotImplementedException("Boolean nog niet geimplementeerd."); }
And some of the helper methods:
private FormField GetFormField(string propertyName) => FormDefinition.FormFields.SingleOrDefault(x => x.PropertyName == propertyName); protected string GetStringValue(string propertyName) => GetFormValue(propertyName)?.ToString(); protected decimal GetDecimalValue(string propertyName) => Convert.ToDecimal(GetFormValue(propertyName)); protected DateTime GetDateTimeValue(string propertyName) => Convert.ToDateTime(GetFormValue(propertyName)); protected object GetFormValue(string propertyName) => FormModel?.GetType().GetProperty(propertyName)?.GetValue(FormModel); protected void SetFormValue(string propertyName, object value) => FormModel.GetType().GetProperty(propertyName)?.SetValue(FormModel, value, null);