Is it possible to set the visibility of grid columns when the columns are defined manually?

1 Answer 487 Views
Grid
Stefan
Top achievements
Rank 1
Iron
Stefan asked on 24 Sep 2021, 12:34 PM

I've created a generic TelerikGrid component that can handle any model is pass onto it. However, because of this, I cannot enable AutoGenerateColumns, since the model is not specified when the grid is being initialized. Instead, I have to manually define the columns using a variation of the example provided here: https://github.com/telerik/blazor-ui/blob/master/grid/binding-to-expando-object/BindingToExpandoObject/Pages/AutoGeneratedColumns.razor

@inject LocalStorageService _localStorage
@inject GenericHttpEntityService _entityService

@typeparam TItem

<div style="position: relative; width: 100%; min-height: 400px;">
    <TelerikLoaderContainer OverlayThemeColor="light" Visible="@(!IsDoneLoading)"
                            Text="@null" Class="initial-data-loader">
        <Template>
            <TelerikLoader Type="LoaderType.Pulsing" Size="LoaderSize.Large"></TelerikLoader>
        </Template>
    </TelerikLoaderContainer>

    <TelerikGrid Data="@GridData"
                 @ref="@Grid"
                 Height="460px"
                 RowHeight="60"
                 PageSize="10"
                 Pageable="true"
                 Sortable="true"
                 Resizable="true"
                 FilterMode="GridFilterMode.FilterMenu"
                 EditMode="GridEditMode.Popup"
                 OnRead="@ReadEntity"
                 OnStateInit="@((GridStateEventArgs<object> args) => OnStateInitHandler(args))"
                 OnStateChanged="@((GridStateEventArgs<object> args) => OnStateChangedHandler(args))">
        <GridColumns>
            @if (GridData != null && GridData.Any())
            {
                var firstItem = GridData.First();
                var dictionary = firstItem.GetType().GetProperties().ToDictionary(prop => prop.Name, prop => prop.GetValue(firstItem, null));

                foreach (var (key, value) in dictionary)
                {
                    if (value == null)
                    {
                        continue;
                    }

                    <GridColumn Field="@key" FieldType="@value.GetType()"></GridColumn>
                }
            }
        </GridColumns>
    </TelerikGrid>
</div>


@code {
    // Grid data
    private List<object> GridData { get; set; } = new();
    private int Total { get; set; }

    // Loading
    bool IsDoneLoading { get; set; }

    // Grid state
    TelerikGrid<object> Grid { get; set; }
    string StorageKey { get; set; }

    // Parameters
    [Parameter]
    public bool MaintainState { get; set; }
    [Parameter]
    public TItem Entity { get; set; }

    protected override void OnInitialized()
    {
        StorageKey = $"{typeof(TItem).Name}GridState";
    }

    private async Task ReadEntity(GridReadEventArgs args)
    {
        var data = await _entityService.GetAll<TItem>(args.Request);

        GridData = data.Records.Cast<object>().ToList();
        Total = data.Total;

        IsDoneLoading = true;
    }

    async Task OnStateInitHandler(GridStateEventArgs<object> args)
    {
        if (!MaintainState) return;

        try
        {
            var state = await _localStorage.GetItem<GridState<object>>(StorageKey);
            if (state != null)
            {
                args.GridState = state;
            }
        }
        catch (InvalidOperationException)
        {
    // The JS Interop for the local storage cannot be used during pre-rendering
    // so the code above will throw. Once the app initializes, it will work fine.
        }
    }

    async void OnStateChangedHandler(GridStateEventArgs<object> args)
    {
        if (!MaintainState) return;

        await _localStorage.SetItem(StorageKey, args.GridState);
    }
}

The problem with this is that the visibility of the columns can't be defined in the model with annotations like [Display(AutoGenerated = false)]. Is there any way to do what I want to achieve here?

1 Answer, 1 is accepted

Sort by
0
Nadezhda Tacheva
Telerik team
answered on 28 Sep 2021, 11:44 AM

Hello Stefan,

While you have created a generic Grid, I suppose you still want to include some logic for the various columns visibility - for example, not to display columns that contain IDs. If so, you may try conditionally rendering the columns based on the item key.

For example:

    <GridColumns>
        @if (GridData != null && GridData.Any())
        {
            var firstItem = GridData.First();
            var dictionary = firstItem.GetType().GetProperties().ToDictionary(prop => prop.Name, prop => prop.GetValue(firstItem, null));

            foreach (var (key, value) in dictionary)
            {
                if (value == null)
                {
                    continue;
                }

                if (key != "EmployeeId")
                {
                    <GridColumn Field="@key" FieldType="@value.GetType()"></GridColumn>
                }
            }
        }
    </GridColumns>

 

I hope you will find this information useful. If any further questions appear, please let us know.

Regards,


Nadezhda Tacheva
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tags
Grid
Asked by
Stefan
Top achievements
Rank 1
Iron
Answers by
Nadezhda Tacheva
Telerik team
Share this question
or