Datagrid filters -> using numeric / text dictionary

hi guys,

this is an interesting one...

in our database we have a status INT, i.e. 1 = new, 2 = in progress, 3 = XYZ, etc

these status's are uniqe for the table, so we have created a numeric, string dictionary of values we use in drop down lists on our pages

this way a user can select "NEW" in the drop down list and the #1 is stored in the DB

we have that all working really nicely, the issue is now on a datagrid filter....

when we select the filter, because it's referring to the underlying database type, i'm getting presented with a INT style filter....

is there a way to change the filter to a drop down list similar to the form ?

image
this image shows the filter being locked to a numeric input, how can i change it to be a drop down list as per the data dictionay ?

The easiest way will be to use enums instead:

Or you can define your own custom FilterValueTemplate:

1 Like

thanks @enchev , is there a guide as to how to do this in Radzen App instead of blazor studio ?

If you are using Radzen IDE you can still create custom component by writing manually razor/c# and reuse it across pages:

is there any tweaking of configuration that can be done on the data grid - column - filter settings ?

what about the filter template option ?

This is a template for the whole popup content. FilterValueTemplate is not available in Radzen IDE.

okay thanks @enchev, sounds like at some point i'm going to have to dive into blazor studio :smiley:

I have a very similar problem. I posted here because it is so related. I already have a database with years of data. I added the database to the project in Blazor Studio. I then modified the generated classes to include my enums. As they are int in the database. Then I generated a crud page based on an entity with a single enums. Now when the grid loads, it still loads the int and the filter drop-down is the int. I modified my grid column markup.

<RadzenDataGridColumn Property="AccountType" Title="Account Type" Type="typeof(Server.Models.AccountType)">
                  <Template Context="account">
                    @((Server.Models.AccountType)(object)account.AccountType)
                  </Template>
                   
                </RadzenDataGridColumn>

AccountType is my enum. The AccountType property on the AccountType has a data type of my enum.

So this loads the text value of my enum in the grid and will sort. I also get the expected drop-down in the filter popup.
However, when I select an item, it throws an error.
When I follow the trace, I notice that it makes the call to the server. I follow the OData link and find there is an error.
Further investigation shows the problem is with the OData filter query, it has quotes around the int value of the selected enum value. AccountType eq '3000' instead of AccountType eq 3000

How would I adjust that or do this differently that will work well?

I have seen that post, but I am not understanding how to accomplish this.

Check the issue I have linked, there is a link with sample.

While the StringToEnumResolver looks like a handy tool. The enum values are all integers in the database. I am using RBS to generate a dbContext for my database. Then I add in my enums from my previous application from 5 years ago. Next I update the model that was generated to change that property to the enum.
Then I add a page and point to the one model I updated.

A grid and add/edit pages are generated. The enum filter doesn’t work. The add/edit pages have no form control for the property that is an enum.

I feel like this should just work and I’m missing something.

Merged to: Data grid filter enum

I’m afraid that we are not aware of a way to make this work. Feel free to submit pull request if you know such.

So it's not possible to have an int in a database and map this to an enum to show user friendly text and be filterable with the default datagrid?

Here it seems to be working fine.

All of this code is in one page though.
I have a Blazor 8 with Auto Interactive and PWA.
There is a Server project and Client project.

I'm so confused.

If I change my field type back to int in the model, it works as expected.

[Table("Accounts", Schema = "dbo")]
public partial class Account
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

    [Required]
    public string AccountName { get; set; }

    [Required]
    [EnumDataType(typeof(AccountType))]
    public AccountType AccountType { get; set; }
    // I changed this from int to AccountType 

    [Required]
    public decimal AccountBalance { get; set; }

    [Required]
    public int AccountNumber { get; set; }

    public ICollection<TransactionEntry> TransactionEntries { get; set; }
}

public enum AccountType
{
Asset = 1000,
Liability = 2000,
Equity = 3000,
Revenue = 4000,
Expense = 6000,
COGS = 5000
}

With the property type set to AccountType, the items won't load in the grid.

Accounts.razor

@page "/accounts"
@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager
@inject DialogService DialogService
@inject ContextMenuService ContextMenuService
@inject TooltipService TooltipService
@inject NotificationService NotificationService

@inject BlazorPortalDbService BlazorPortalDbService

Accounts















<RadzenTextBox Placeholder="Search ..." style="display: block; width: 100%" @oninput="@Search" aria-label="Search by all string columns" />


<RadzenDataGrid @ref="grid0" ColumnWidth="200px" AllowFiltering="true" FilterMode="FilterMode.Advanced" AllowPaging="true" AllowSorting="true" ShowPagingSummary="true" PageSizeOptions=@(new int{5, 10, 20, 30})
Data="@accounts" LoadData="@Grid0LoadData" Count="@count" TItem="BlazorPortal.Server.Models.BlazorPortalDb.Account" RowDoubleClick="@EditRow">












                    <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Size="ButtonSize.Medium"
                        Shade="Shade.Lighter" Variant="Variant.Flat"
                        Click=@(args => GridDeleteButtonClick(args, account)) @onclick:stopPropagation="true" />
                </Template>
            </RadzenDataGridColumn>
        </Columns>

    </RadzenDataGrid>

</RadzenColumn>
@code {
protected IEnumerable<BlazorPortal.Server.Models.BlazorPortalDb.Account> accounts;

protected RadzenDataGrid<BlazorPortal.Server.Models.BlazorPortalDb.Account> grid0;
protected int count;

protected string search = "";

protected async Task Search(ChangeEventArgs args)
{
    search = $"{args.Value}";

    await grid0.GoToPage(0);

    await grid0.Reload();
}

protected async Task Grid0LoadData(LoadDataArgs args)
{
    try
    {
        var result = await BlazorPortalDbService.GetAccounts(filter: $@"(contains(AccountName,""{search}"")) and {(string.IsNullOrEmpty(args.Filter)? "true" : args.Filter)}", orderby: $"{args.OrderBy}", top: args.Top, skip: args.Skip, count:args.Top != null && args.Skip != null);
        accounts = result.Value.AsODataEnumerable();
        count = result.Count;
    }
    catch (System.Exception ex)
    {
        Console.WriteLine(ex.Message);
        NotificationService.Notify(new NotificationMessage(){ Severity = NotificationSeverity.Error, Summary = $"Error", Detail = $"Unable to load Accounts" });
    }
}

protected async Task AddButtonClick(MouseEventArgs args)
{
    await DialogService.OpenAsync<AddAccount>("Add Account", null);
    await grid0.Reload();
}

protected async Task EditRow(DataGridRowMouseEventArgs<BlazorPortal.Server.Models.BlazorPortalDb.Account> args)
{
    await DialogService.OpenAsync<EditAccount>("Edit Account", new Dictionary<string, object> { {"Id", args.Data.Id} });
    await grid0.Reload();
}

protected async Task GridDeleteButtonClick(MouseEventArgs args, BlazorPortal.Server.Models.BlazorPortalDb.Account account)
{
    try
    {
        if (await DialogService.Confirm("Are you sure you want to delete this record?") == true)
        {
            var deleteResult = await BlazorPortalDbService.DeleteAccount(id:account.Id);

            if (deleteResult != null)
            {
                await grid0.Reload();
            }
        }
    }
    catch (Exception ex)
    {
        NotificationService.Notify(new NotificationMessage
        {
            Severity = NotificationSeverity.Error,
            Summary = $"Error",
            Detail = $"Unable to delete Account"
        });
    }
}

protected async Task ExportClick(RadzenSplitButtonItem args)
{
    if (args?.Value == "csv")
    {
        await BlazorPortalDbService.ExportAccountsToCSV(new Query
    {
        Filter = $@"{(string.IsNullOrEmpty(grid0.Query.Filter)? "true" : grid0.Query.Filter)}",
        OrderBy = $"{grid0.Query.OrderBy}",
        Expand = "",
        Select = string.Join(",", grid0.ColumnsCollection.Where(c => c.GetVisible() && !string.IsNullOrEmpty(c.Property)).Select(c => c.Property.Contains(".") ? c.Property + " as " + c.Property.Replace(".", "") : c.Property))
    }, "Accounts");
    }

    if (args == null || args.Value == "xlsx")
    {
        await BlazorPortalDbService.ExportAccountsToExcel(new Query
    {
        Filter = $@"{(string.IsNullOrEmpty(grid0.Query.Filter)? "true" : grid0.Query.Filter)}",
        OrderBy = $"{grid0.Query.OrderBy}",
        Expand = "",
        Select = string.Join(",", grid0.ColumnsCollection.Where(c => c.GetVisible() && !string.IsNullOrEmpty(c.Property)).Select(c => c.Property.Contains(".") ? c.Property + " as " + c.Property.Replace(".", "") : c.Property))
    }, "Accounts");
    }
}

}

I’ve never heard of such technique and cannot add anything else.

Actually you might try IFormatProvider for desired column similar to this demo:

Read my previous reply. You cannot map an int database field to an enum and expect OData and EF to work properly.