RadzenDataGrid OnFilter unable to manipulate FilterValue #405

Open
opened 2026-01-29 17:36:46 +00:00 by claunia · 0 comments
Owner

Originally created by @andrewaggb on GitHub (May 11, 2022).

Describe the bug
The DataGrid OnFilter operation doesn't appear to offer a way to manipulate the filter value after a user enters it. My particular use case is a phone number. I'd like a user to be able to paste a phone number in any format (eg +1 999 555-1234, (999) 555-1234, etc) into the filter box and I'll reformat the number to match the format used in the database. Adjusting the value in the OnFilter callback seems like the least effort approach but there doesn't appear to be a public way to do so. I have a couple thoughts below and I could submit a PR but as it basically involves making a few things public vs internal or private I figured maybe it's more a discussion point than anything.

In the example page RadzenBlazorDemos\Pages\DataGridFilterApiPage.razor in OnAfterRenderAsync(bool firstRender) an initial filter value is set using
column.FilterValue = "Nan";

This works because no filter was entered into the UI element. It also produces a warning in visual studio 'BL0005: Component parameter should not be set outside of its component'

Trying to manipulate a value in void OnFilter(DataGridColumnFilterEventArgs args) the same way doesn't work as a user entered value is stored in filterValue (which is private) and manipulating the public FilterValue is ignored once filterValue is set (per the code below filterValue ?? FilterValue). I think if the function SetFilterValue (below) was public instead of internal that might be sufficient but there are several internal methods that you might want to call in the OnFilter Callback - so perhaps several of the methods could be public or similar public facing versions could be implemented. Thoughts?

Radzen.Blazor\RadzenDataGridColumn.cs
internal object GetFilterValue()
{
	return **filterValue ?? FilterValue**;
}

**internal** void SetFilterValue(object value, bool isFirst = true)

It is also possible to do what I want using a filter template, which is what I've done below. This is an awful lot of effort in comparison and also runs into private/public issues when trying to access the Debounce class which means I had to make a local copy in my own namespace. The main challenge is the onkeydown logic to match the behavior of the automatic inputs, which eventually requires debouncing which is private. I don't see any reason the Debounce class couldn't be made public as-is.

                        <FilterTemplate>
                            <label class="rz-cell-filter-label" style="height:35px" onclick="event.preventDefault()">
                                <input id="phoneNumberFilter" type="text" class="rz-textbox" style="width:100%" value="@_phoneNumberFilter" @onchange="ChangePhoneNumberFilter" @onkeydown="@((args) => OnChangePhoneNumberFilterKeyPress(args))" />
                            </label>
                        </FilterTemplate>
...

private void ChangePhoneNumberFilter(ChangeEventArgs e)
    {
        _phoneNumberFilter = e.Value.ToString();
        _cleanPhoneNumberFilter = _phoneNumberFilter.Clean09();        
    }

    protected void OnChangePhoneNumberFilterKeyPress(EventArgs args)
    {
        Debounce(() => DebounceFilter(), 500);
    }

    async Task DebounceFilter()
    {
        var inputValue = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", new object[] { "phoneNumberFilter" });
        if (!object.Equals(_cleanPhoneNumberFilter, inputValue.Clean09()))
        {
            await InvokeAsync(() => { ChangePhoneNumberFilter(new ChangeEventArgs() { Value = inputValue }); StateHasChanged(); });
        }
    }

    protected void Debounce(Func<Task> action, int milliseconds = 500)
    {
        debouncer.Debounce(milliseconds, action);
    }
    **Debouncer debouncer = new Debouncer();**
Originally created by @andrewaggb on GitHub (May 11, 2022). **Describe the bug** The DataGrid OnFilter operation doesn't appear to offer a way to manipulate the filter value after a user enters it. My particular use case is a phone number. I'd like a user to be able to paste a phone number in any format (eg +1 999 555-1234, (999) 555-1234, etc) into the filter box and I'll reformat the number to match the format used in the database. Adjusting the value in the OnFilter callback seems like the least effort approach but there doesn't appear to be a public way to do so. I have a couple thoughts below and I could submit a PR but as it basically involves making a few things public vs internal or private I figured maybe it's more a discussion point than anything. In the example page RadzenBlazorDemos\Pages\DataGridFilterApiPage.razor in OnAfterRenderAsync(bool firstRender) an initial filter value is set using `column.FilterValue = "Nan";` This works because no filter was entered into the UI element. It also produces a warning in visual studio 'BL0005: Component parameter should not be set outside of its component' Trying to manipulate a value in void OnFilter(DataGridColumnFilterEventArgs<Employee> args) the same way doesn't work as a user entered value is stored in filterValue (which is private) and manipulating the public FilterValue is ignored once filterValue is set (per the code below **filterValue ?? FilterValue**). I think if the function SetFilterValue (below) was public instead of internal that might be sufficient but there are several internal methods that you might want to call in the OnFilter Callback - so perhaps several of the methods could be public or similar public facing versions could be implemented. Thoughts? ``` Radzen.Blazor\RadzenDataGridColumn.cs internal object GetFilterValue() { return **filterValue ?? FilterValue**; } **internal** void SetFilterValue(object value, bool isFirst = true) ``` It is also possible to do what I want using a filter template, which is what I've done below. This is an awful lot of effort in comparison and also runs into private/public issues when trying to access the Debounce class which means I had to make a local copy in my own namespace. The main challenge is the onkeydown logic to match the behavior of the automatic inputs, which eventually requires debouncing which is private. I don't see any reason the Debounce class couldn't be made public as-is. ``` <FilterTemplate> <label class="rz-cell-filter-label" style="height:35px" onclick="event.preventDefault()"> <input id="phoneNumberFilter" type="text" class="rz-textbox" style="width:100%" value="@_phoneNumberFilter" @onchange="ChangePhoneNumberFilter" @onkeydown="@((args) => OnChangePhoneNumberFilterKeyPress(args))" /> </label> </FilterTemplate> ... private void ChangePhoneNumberFilter(ChangeEventArgs e) { _phoneNumberFilter = e.Value.ToString(); _cleanPhoneNumberFilter = _phoneNumberFilter.Clean09(); } protected void OnChangePhoneNumberFilterKeyPress(EventArgs args) { Debounce(() => DebounceFilter(), 500); } async Task DebounceFilter() { var inputValue = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", new object[] { "phoneNumberFilter" }); if (!object.Equals(_cleanPhoneNumberFilter, inputValue.Clean09())) { await InvokeAsync(() => { ChangePhoneNumberFilter(new ChangeEventArgs() { Value = inputValue }); StateHasChanged(); }); } } protected void Debounce(Func<Task> action, int milliseconds = 500) { debouncer.Debounce(milliseconds, action); } **Debouncer debouncer = new Debouncer();** ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/radzen-blazor#405