|
| 1 | +--- |
| 2 | +title: Transpose Grid |
| 3 | +description: Learn how to show transposed Grid data in a table or a Form. The transposed data may or may not support editing. |
| 4 | +type: how-to |
| 5 | +page_title: How to Transpose the Telerik Grid for Blazor |
| 6 | +slug: grid-kb-transposed |
| 7 | +tags: telerik, blazor, grid, transposed |
| 8 | +ticketid: 1569198, 1639288, 1660386 |
| 9 | +res_type: kb |
| 10 | +--- |
| 11 | + |
| 12 | +## Environment |
| 13 | + |
| 14 | +<table> |
| 15 | + <tbody> |
| 16 | + <tr> |
| 17 | + <td>Product</td> |
| 18 | + <td>Grid for Blazor</td> |
| 19 | + </tr> |
| 20 | + </tbody> |
| 21 | +</table> |
| 22 | + |
| 23 | +## Description |
| 24 | + |
| 25 | +This KB article answers the following questions: |
| 26 | + |
| 27 | +* How to transpose the data grid component? |
| 28 | +* How to convert the Grid columns to rows and the Grid rows to columns? |
| 29 | +* How to achieve a horizontal Grid configuration? |
| 30 | +* How to switch the Grid orientation? The model properties should display vertically and the model values should display horizontally. |
| 31 | + |
| 32 | +## Solution |
| 33 | + |
| 34 | +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](https://feedback.telerik.com/blazor/1468343-propertygrid-property-grid-vertical-oriented-grid-with-cell-labels-in-column-1). Vote for the feature request and follow it to receive future status updates. |
| 35 | + |
| 36 | +## Suggested Workarounds |
| 37 | + |
| 38 | +Here are a few possible ways to display transposed data: |
| 39 | + |
| 40 | +* Use the [Telerik Form component for Blazor]({%slug form-overview%}) instead of a Grid. The Form does not provide Grid features, but it can be databound to a model object and supports editing. |
| 41 | +* Render static HTML markup, which uses the Grid CSS classes. This will produce Grid-like UI, but without any additional built-in features. |
| 42 | +* Combine the previous two options to achieve a Form that looks like a Grid. Use the Grid's HTML markup in a [Form `FormItemsTemplate`]({%slug form-formitems-formitemstemplate%}). Optionally, remove the [built-in Form submit button by using an empty `<FormButtons>` tag]({%slug form-formitems-buttons%}). |
| 43 | + |
| 44 | +Alternatively, shape the data structure, so that it's suitable to display in a regular non-transposed Grid. |
| 45 | + |
| 46 | +The following example demonstrates all options. |
| 47 | + |
| 48 | +>caption Implement a PropertyGrid or a transposed Grid |
| 49 | +
|
| 50 | +````CSHTML |
| 51 | +@using System.Reflection |
| 52 | +
|
| 53 | +<h2>Form</h2> |
| 54 | +
|
| 55 | +<TelerikForm Model="@DataItem" |
| 56 | + Orientation="@FormOrientation.Horizontal" |
| 57 | + OnUpdate="@( () => { /* OnUpdate is an EventCallback, so it refreshes the UI */ } )" |
| 58 | + Width="300px" |
| 59 | + Class="bold-labels"> |
| 60 | +</TelerikForm> |
| 61 | +
|
| 62 | +<style> |
| 63 | + /* Emphasize the Form labels */ |
| 64 | + .bold-labels .k-form-label { |
| 65 | + font-weight: bold; |
| 66 | + } |
| 67 | +</style> |
| 68 | +
|
| 69 | +<h2>Editable HTML Table in Form <code>FormItemsTemplate</code></h2> |
| 70 | +
|
| 71 | +<TelerikForm Model="@DataItem" |
| 72 | + Orientation="@FormOrientation.Horizontal" |
| 73 | + OnUpdate="@( () => { /* OnUpdate is an EventCallback, so it refreshes the UI */ } )" |
| 74 | + Width="600px"> |
| 75 | + <FormItems> |
| 76 | + <FormItem Field="@nameof(GridItem.Id)"> |
| 77 | + <Template> |
| 78 | + <TelerikNumericTextBox @bind-Value="@DataItem.Id" /> |
| 79 | + </Template> |
| 80 | + </FormItem> |
| 81 | + <FormItem Field="@nameof(GridItem.Name)"> |
| 82 | + <Template> |
| 83 | + <TelerikTextBox @bind-Value="@DataItem.Name" /> |
| 84 | + </Template> |
| 85 | + </FormItem> |
| 86 | + <FormItem Field="@nameof(GridItem.Description)"> |
| 87 | + <Template> |
| 88 | + <TelerikTextBox @bind-Value="@DataItem.Description" /> |
| 89 | + </Template> |
| 90 | + </FormItem> |
| 91 | + <FormItem Field="@nameof(GridItem.Quantity)"> |
| 92 | + <Template> |
| 93 | + <TelerikNumericTextBox @bind-Value="@DataItem.Quantity" /> |
| 94 | + </Template> |
| 95 | + </FormItem> |
| 96 | + <FormItem Field="@nameof(GridItem.Active)"> |
| 97 | + <Template> |
| 98 | + <TelerikCheckBox @bind-Value="@DataItem.Active" /> |
| 99 | + </Template> |
| 100 | + </FormItem> |
| 101 | + </FormItems> |
| 102 | + <FormButtons></FormButtons> |
| 103 | + <FormItemsTemplate> |
| 104 | + <div class="k-grid k-grid-md html-grid"> |
| 105 | + <div class="k-grid-aria-root"> |
| 106 | + <div class="k-grid-header"> |
| 107 | + <div class="k-grid-header-wrap"> |
| 108 | + <table class="k-grid-header-table k-table k-table-md"> |
| 109 | + <colgroup> |
| 110 | + <col /> |
| 111 | + <col /> |
| 112 | + </colgroup> |
| 113 | + <thead class="k-table-thead"> |
| 114 | + <tr class="k-table-row"> |
| 115 | + <th class="k-header k-table-th"> Property Name </th> |
| 116 | + <th class="k-header k-table-th"> Editable Value </th> |
| 117 | + </tr> |
| 118 | + </thead> |
| 119 | + </table> |
| 120 | + </div> |
| 121 | + </div> |
| 122 | + <div class="k-grid-container"> |
| 123 | + <div class="k-grid-content"> |
| 124 | + <table class="k-grid-table k-table k-table-md"> |
| 125 | + <colgroup> |
| 126 | + <col /> |
| 127 | + <col /> |
| 128 | + </colgroup> |
| 129 | + <tbody class="k-table-tbody"> |
| 130 | + @{ int counter = 1; } |
| 131 | +
|
| 132 | + @foreach (IFormItem item in context.Items) |
| 133 | + { |
| 134 | + <tr class="k-master-row k-table-row k-grid-edit-row @( counter++ % 2 == 0 ? "k-table-alt-row" : "" )"> |
| 135 | + <th scope="row" class="k-table-td k-table-thead"> @item.Field </th> |
| 136 | + <td class="k-table-td k-grid-edit-cell"> |
| 137 | + <TelerikFormItemRenderer Item="@item" /> |
| 138 | + </td> |
| 139 | + </tr> |
| 140 | + } |
| 141 | + </tbody> |
| 142 | + </table> |
| 143 | + </div> |
| 144 | + </div> |
| 145 | + </div> |
| 146 | + </div> |
| 147 | + </FormItemsTemplate> |
| 148 | +</TelerikForm> |
| 149 | +
|
| 150 | +<style> |
| 151 | + /* Adjust the row headers to look better one below the other */ |
| 152 | + .html-grid tbody th.k-table-td { |
| 153 | + font-weight: bold; |
| 154 | + border-bottom-width: 0; |
| 155 | + } |
| 156 | +
|
| 157 | + /* Remove unnecessary space */ |
| 158 | + .html-grid div.k-form-field { |
| 159 | + margin-top: 0; |
| 160 | + } |
| 161 | +</style> |
| 162 | +
|
| 163 | +<h2>Read-Only HTML Table</h2> |
| 164 | +
|
| 165 | +<div class="k-grid k-grid-md html-grid" style="width:600px"> |
| 166 | + <div class="k-grid-aria-root"> |
| 167 | + <div class="k-grid-header"> |
| 168 | + <div class="k-grid-header-wrap"> |
| 169 | + <table class="k-grid-header-table k-table k-table-md"> |
| 170 | + <colgroup> |
| 171 | + <col /> |
| 172 | + <col /> |
| 173 | + </colgroup> |
| 174 | + <thead class="k-table-thead"> |
| 175 | + <tr class="k-table-row"> |
| 176 | + <th class="k-header k-table-th"> Property Name </th> |
| 177 | + <th class="k-header k-table-th"> Read-Only Value </th> |
| 178 | + </tr> |
| 179 | + </thead> |
| 180 | + </table> |
| 181 | + </div> |
| 182 | + </div> |
| 183 | + <div class="k-grid-container"> |
| 184 | + <div class="k-grid-content"> |
| 185 | + <table class="k-grid-table k-table k-table-md"> |
| 186 | + <colgroup> |
| 187 | + <col /> |
| 188 | + <col /> |
| 189 | + </colgroup> |
| 190 | + <tbody class="k-table-tbody"> |
| 191 | + @{ |
| 192 | + int counter = 1; |
| 193 | + foreach (var prop in GridItemProps) |
| 194 | + { |
| 195 | + <tr class="k-master-row k-table-row @( counter++ % 2 == 0 ? "k-table-alt-row" : "" )"> |
| 196 | + <th scope="row" class="k-table-td k-table-thead"> @prop.Name </th> |
| 197 | + <td class="k-table-td"> @prop.GetValue(DataItem) </td> |
| 198 | + </tr> |
| 199 | + } |
| 200 | + } |
| 201 | + </tbody> |
| 202 | + </table> |
| 203 | + </div> |
| 204 | + </div> |
| 205 | + </div> |
| 206 | +</div> |
| 207 | +
|
| 208 | +<h2>Editable Grid</h2> |
| 209 | +
|
| 210 | +<TelerikGrid @ref="@GridRef" |
| 211 | + Data="@GridData" |
| 212 | + EditMode="@GridEditMode.Incell" |
| 213 | + OnUpdate="@OnGridUpdate"> |
| 214 | + <GridColumns> |
| 215 | + <GridColumn Field="@nameof(GridItem.Id)" /> |
| 216 | + <GridColumn Field="@nameof(GridItem.Name)" /> |
| 217 | + <GridColumn Field="@nameof(GridItem.Description)" /> |
| 218 | + <GridColumn Field="@nameof(GridItem.Quantity)" /> |
| 219 | + <GridColumn Field="@nameof(GridItem.Active)" /> |
| 220 | + </GridColumns> |
| 221 | +</TelerikGrid> |
| 222 | +
|
| 223 | +@code { |
| 224 | + private TelerikGrid<GridItem>? GridRef { get; set; } |
| 225 | +
|
| 226 | + private List<GridItem> GridData { get; set; } = new(); |
| 227 | + private List<PropertyInfo> GridItemProps { get; set; } = new(); |
| 228 | +
|
| 229 | + private GridItem DataItem { get; set; } = new GridItem() |
| 230 | + { |
| 231 | + Id = 1, |
| 232 | + Name = "Sample Name 1", |
| 233 | + Description = "Dummy Descrition 1", |
| 234 | + Quantity = 123, |
| 235 | + Active = true |
| 236 | + }; |
| 237 | +
|
| 238 | + private void OnGridUpdate(GridCommandEventArgs args) |
| 239 | + { |
| 240 | + var updatedItem = (GridItem)args.Item; |
| 241 | +
|
| 242 | + DataItem.Active = updatedItem.Active; |
| 243 | + DataItem.Description = updatedItem.Description; |
| 244 | + DataItem.Id = updatedItem.Id; |
| 245 | + DataItem.Name = updatedItem.Name; |
| 246 | + DataItem.Quantity = updatedItem.Quantity; |
| 247 | + } |
| 248 | +
|
| 249 | + protected override void OnInitialized() |
| 250 | + { |
| 251 | + GridData = new List<GridItem>() { DataItem }; |
| 252 | +
|
| 253 | + GridItemProps = typeof(GridItem).GetProperties().ToList(); |
| 254 | +
|
| 255 | + base.OnInitialized(); |
| 256 | + } |
| 257 | +
|
| 258 | + public class GridItem |
| 259 | + { |
| 260 | + public int Id { get; set; } |
| 261 | + public string Name { get; set; } = string.Empty; |
| 262 | + public string Description { get; set; } = string.Empty; |
| 263 | + public int Quantity { get; set; } |
| 264 | + public bool Active { get; set; } |
| 265 | + } |
| 266 | +} |
| 267 | +```` |
| 268 | + |
| 269 | +## See Also |
| 270 | + |
| 271 | +* [Grid Overview]({%slug grid-overview%}) |
| 272 | +* [Form FormItemsTemplate]({%slug form-formitems-formitemstemplate%}) |
0 commit comments