New to Telerik UI for Blazor? Download free 30-day trial

Transpose Grid

Environment

Product Grid for Blazor

Description

This KB article answers the following questions:

  • How to transpose the data grid component?
  • How to convert the Grid columns to rows and the Grid rows to columns?
  • How to achieve a horizontal Grid configuration?
  • How to switch the Grid orientation? The model properties should display vertically and the model values should display horizontally.

Solution

The Telerik Grid for Blazor does not support transposing. A transposed Grid requires a different architecture, implementation and UI. Thus, a transposed Grid must be a separate component, such as the Telerik PropertyGrid for Blazor. Vote for the feature request and follow it to receive status updates.

Suggested Workarounds

Here are a few possible ways to display transposed data:

Alternatively, shape the data structure, so that it's suitable to display in a regular non-transposed Grid.

The following example demonstrates all options.

Implement a PropertyGrid or a transposed Grid

@using System.Reflection

<h2>Form</h2>

<TelerikForm Model="@DataItem"
             Orientation="@FormOrientation.Horizontal"
             OnUpdate="@( () => { /* OnUpdate is an EventCallback, so it refreshes the UI */ } )"
             Width="300px"
             Class="bold-labels">
</TelerikForm>

<style>
    /* Emphasize the Form labels */
    .bold-labels .k-form-label {
        font-weight: bold;
    }
</style>

<h2>Editable HTML Table in Form <code>FormItemsTemplate</code></h2>

<TelerikForm Model="@DataItem"
             Orientation="@FormOrientation.Horizontal"
             OnUpdate="@( () => { /* OnUpdate is an EventCallback, so it refreshes the UI */ } )"
             Width="600px">
    <FormItems>
        <FormItem Field="@nameof(GridItem.Id)">
            <Template>
                <TelerikNumericTextBox @bind-Value="@DataItem.Id" />
            </Template>
        </FormItem>
        <FormItem Field="@nameof(GridItem.Name)">
            <Template>
                <TelerikTextBox @bind-Value="@DataItem.Name" />
            </Template>
        </FormItem>
        <FormItem Field="@nameof(GridItem.Description)">
            <Template>
                <TelerikTextBox @bind-Value="@DataItem.Description" />
            </Template>
        </FormItem>
        <FormItem Field="@nameof(GridItem.Quantity)">
            <Template>
                <TelerikNumericTextBox @bind-Value="@DataItem.Quantity" />
            </Template>
        </FormItem>
        <FormItem Field="@nameof(GridItem.Active)">
            <Template>
                <TelerikCheckBox @bind-Value="@DataItem.Active" />
            </Template>
        </FormItem>
    </FormItems>
    <FormButtons></FormButtons>
    <FormItemsTemplate>
        <div class="k-grid k-grid-md html-grid">
            <div class="k-grid-aria-root">
                <div class="k-grid-header">
                    <div class="k-grid-header-wrap">
                        <table class="k-grid-header-table k-table k-table-md">
                            <colgroup>
                                <col />
                                <col />
                            </colgroup>
                            <thead class="k-table-thead">
                                <tr class="k-table-row">
                                    <th class="k-header k-table-th"> Property Name </th>
                                    <th class="k-header k-table-th"> Editable Value </th>
                                </tr>
                            </thead>
                        </table>
                    </div>
                </div>
                <div class="k-grid-container">
                    <div class="k-grid-content">
                        <table class="k-grid-table k-table k-table-md">
                            <colgroup>
                                <col />
                                <col />
                            </colgroup>
                            <tbody class="k-table-tbody">
                                @{ int counter = 1; }

                                @foreach (IFormItem item in context.Items)
                                {
                                    <tr class="k-master-row k-table-row k-grid-edit-row @( counter++ % 2 == 0 ? "k-table-alt-row" : "" )">
                                        <th scope="row" class="k-table-td k-table-thead"> @item.Field </th>
                                        <td class="k-table-td k-grid-edit-cell">
                                            <TelerikFormItemRenderer Item="@item" />
                                        </td>
                                    </tr>
                                }
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </FormItemsTemplate>
</TelerikForm>

<style>
    /* Adjust the row headers to look better one below the other */
    .html-grid tbody th.k-table-td {
        font-weight: bold;
        border-bottom-width: 0;
    }

    /* Remove unnecessary space */
    .html-grid div.k-form-field {
        margin-top: 0;
    }
</style>

<h2>Read-Only HTML Table</h2>

<div class="k-grid k-grid-md html-grid" style="width:600px">
    <div class="k-grid-aria-root">
        <div class="k-grid-header">
            <div class="k-grid-header-wrap">
                <table class="k-grid-header-table k-table k-table-md">
                    <colgroup>
                        <col />
                        <col />
                    </colgroup>
                    <thead class="k-table-thead">
                        <tr class="k-table-row">
                            <th class="k-header k-table-th"> Property Name </th>
                            <th class="k-header k-table-th"> Read-Only Value </th>
                        </tr>
                    </thead>
                </table>
            </div>
        </div>
        <div class="k-grid-container">
            <div class="k-grid-content">
                <table class="k-grid-table k-table k-table-md">
                    <colgroup>
                        <col />
                        <col />
                    </colgroup>
                    <tbody class="k-table-tbody">
                        @{
                            int counter = 1;
                            foreach (var prop in GridItemProps)
                            {
                                <tr class="k-master-row k-table-row @( counter++ % 2 == 0 ? "k-table-alt-row" : "" )">
                                    <th scope="row" class="k-table-td k-table-thead"> @prop.Name </th>
                                    <td class="k-table-td"> @prop.GetValue(DataItem) </td>
                                </tr>
                            }
                        }
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>

<h2>Editable Grid</h2>

<TelerikGrid @ref="@GridRef"
             Data="@GridData"
             EditMode="@GridEditMode.Incell"
             OnUpdate="@OnGridUpdate">
    <GridColumns>
        <GridColumn Field="@nameof(GridItem.Id)" />
        <GridColumn Field="@nameof(GridItem.Name)" />
        <GridColumn Field="@nameof(GridItem.Description)" />
        <GridColumn Field="@nameof(GridItem.Quantity)" />
        <GridColumn Field="@nameof(GridItem.Active)" />
    </GridColumns>
</TelerikGrid>

@code {
    private TelerikGrid<GridItem>? GridRef { get; set; }

    private List<GridItem> GridData { get; set; } = new();
    private List<PropertyInfo> GridItemProps { get; set; } = new();

    private GridItem DataItem { get; set; } = new GridItem()
    {
        Id = 1,
        Name = "Sample Name 1",
        Description = "Dummy Descrition 1",
        Quantity = 123,
        Active = true
    };

    private void OnGridUpdate(GridCommandEventArgs args)
    {
        var updatedItem = (GridItem)args.Item;

        DataItem.Active = updatedItem.Active;
        DataItem.Description = updatedItem.Description;
        DataItem.Id = updatedItem.Id;
        DataItem.Name = updatedItem.Name;
        DataItem.Quantity = updatedItem.Quantity;
    }

    protected override void OnInitialized()
    {
        GridData = new List<GridItem>() { DataItem };

        GridItemProps = typeof(GridItem).GetProperties().ToList();

        base.OnInitialized();
    }

    public class GridItem
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public string Description { get; set; } = string.Empty;
        public int Quantity { get; set; }
        public bool Active { get; set; }
    }
}

See Also

In this article