Dynamic Tab creation logic

Hello,

I have this OrderDetails data;


Filter on OrderId(16) I want to dynamically create Tabs based on VendorId. According to these sample data at hand, 2 tabs need to be added dynamically.

Here is the pseudo logic but I couldn't find a way even though I pondered a lot. :slight_smile:

<RadzenTabs>
<Tabs>
  @foreach(var item in items)
  {
      <RadzenTabsItem Text=@item.Text>
  }
</Tabs>
</RadzenTabs>

I ask you to help.

Thank you.

We are not sure what you are asking us. Can you elaborate?

I want to show the information (product code, product name, unit cost, total buy price, currency) on the data grid with a single VendorId in separate tabs. I hope I was able to explain briefly @korchev.

According to this sample data, there will be 2 tabs created dynamically like in the pseudo. In the first tab, on the data grid, there will be VendorId = 1 values. In the second tab, on the data grid, there will be VendorId = 2 values.

PS. there is no data grid in the pseudo.

So what seems to be the problem with the pseudo code? It should work as long as you close the <RadzenTabsItem> tag.

Also check this thread: Dynamic Tabs - #2 by korchev and my reply in it. Setting the @key attribute is needed in such cases.

So changing the pseudo to something like this will work? Frankly, I don't understand it sorry. Can you explain it, please?

<RadzenTabsItem @key="@item.VendorId">

I suggest to check the linked thread - it contains some runnable code and links to the documentation of the @key attribute.

Also this thread may help: Dynamic Tabs with showing razor pages in each tab

In general the forum search is quite good: Search results for 'dynamic tabs' - Radzen

1 Like

Thank you for your support.

I changed my code with the help of your sample threads like this;

@if(orderDetails != null)
    {
        <div class="row my-4">
            <div class="col-md-12">
                <RadzenCard>
                    <h3 class="h5">
                        Order @Order.OrderId Details
                        <RadzenBadge BadgeStyle="BadgeStyle.Secondary" Text=@($"{String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", orderDetails?.Select(x => x.TotalBuyPrice).Sum())}") Class="float-right" />
                    </h3>
                    <RadzenTabs>
                        <Tabs>
                            @foreach (var detail in orderDetails)
                            {
                                <RadzenTabsItem @key="@detail.VendorId" Text="@detail.Vendor.Name">
                                    <RadzenDataGrid AllowFiltering="true" AllowPaging="true" AllowSorting="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
                                            Data="@orderDetails" TItem="OrderDetail" Class="mt-3">
                                        <Columns>
                                            <RadzenDataGridColumn TItem="OrderDetail" Property="Id" Title="Number" Width="100px" />
                                            <RadzenDataGridColumn TItem="OrderDetail" Property="ProductCode" Title="Code" Width="130px" />
                                            <RadzenDataGridColumn TItem="OrderDetail" Property="ProductName" Title="Name" Width="130px" />
                                            <RadzenDataGridColumn TItem="OrderDetail" Property="Currency" Title="Currency" Width="95px" />
                                            <RadzenDataGridColumn TItem="OrderDetail" Property="Quantity" Title="Quantity" Width="95px" />
                                            <RadzenDataGridColumn TItem="OrderDetail" Property="BuyUnitPrice" Title="Unit Price" Width="95px" />
                                            <RadzenDataGridColumn TItem="OrderDetail" Property="TotalBuyPrice" Title="Total Price" Width="95px" />

                                        </Columns>
                                    </RadzenDataGrid>
                                </RadzenTabsItem>
                            }
                        </Tabs>
                    </RadzenTabs>
                </RadzenCard>
            </div>
        </div>
    }

I am getting this error;

Error: System.InvalidOperationException: More than one sibling of component 'Radzen.Blazor.RadzenTabsItem' has the same key value, '1'. Key values must be unique.

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ThrowExceptionForDuplicateKey(Object key, RenderTreeFrame& frame)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.BuildKeyToInfoLookup(DiffContext diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)

   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, Int32 componentId, ArrayRange`1 oldTree, ArrayRange`1 newTree)

   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)

   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue() 

Here is my sample data:

SET IDENTITY_INSERT [dbo].[OrdersDetail] ON
INSERT INTO [dbo].[OrdersDetail] ([Id], [ProductCode], [ProductName], [Quantity], [CostRatio], [UnitCost], [TotalBuyPrice], [TotalSellPrice], [ShippingNumber], [Status], [TrackingNumber], [Description], [OrderId], [VendorId], [Currency], [BuyUnitPrice], [SellUnitPrice]) VALUES (24, N'000001', N'Shirt', 100, 12, 0, 0, 0, N'shipment1', N'Shipped', N'tracking1', N'description1', 16, 1, N'TL', 11.1, 13)
INSERT INTO [dbo].[OrdersDetail] ([Id], [ProductCode], [ProductName], [Quantity], [CostRatio], [UnitCost], [TotalBuyPrice], [TotalSellPrice], [ShippingNumber], [Status], [TrackingNumber], [Description], [OrderId], [VendorId], [Currency], [BuyUnitPrice], [SellUnitPrice]) VALUES (25, N'000002', N'Gol', 50, 12, 22.512, 1005.0000000000001, 1250, N'shipment2', N'At customs', N'tracking2', N'description2', 16, 1, N'TL', 20.1, 25)
INSERT INTO [dbo].[OrdersDetail] ([Id], [ProductCode], [ProductName], [Quantity], [CostRatio], [UnitCost], [TotalBuyPrice], [TotalSellPrice], [ShippingNumber], [Status], [TrackingNumber], [Description], [OrderId], [VendorId], [Currency], [BuyUnitPrice], [SellUnitPrice]) VALUES (26, N'000003', N'Excipal', 35, 6, 62.54, 2065, 2310, N'shipment3', N'Getting ready', N'tracking3', N'description3', 16, 2, N'TL', 59, 66)
SET IDENTITY_INSERT [dbo].[OrdersDetail] OFF

According to my sample data, VendorId is keyed, and Blazor is supposed to ignore rerendering VendorId = 1 which hasn't changed. I don't understand why the error occurred.

I think the error explains itself - you seem to have multiple items with VendorId = 1. You can debug your code to inspect what the collection contains.

this old school comparison solved my issue;

@if(orderDetails != null)
    {
        <div class="row my-4">
            <div class="col-md-12">
                <RadzenCard>
                    <h3 class="h5">
                        Order @Order.OrderId Details
                        <RadzenBadge BadgeStyle="BadgeStyle.Secondary" Text=@($"{String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", orderDetails?.Select(x => x.TotalBuyPrice).Sum())}") Class="float-right" />
                    </h3>
                    <RadzenTabs>
                        <Tabs>
                            @{var detailVendorId = 0;}
                            @foreach (var detail in orderDetails)
                            {
                                @if(detailVendorId != detail.VendorId){
                                    <RadzenTabsItem Text="@detail.Vendor.Name">
                                        <RadzenDataGrid AllowFiltering="true" AllowPaging="true" AllowSorting="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
                                                        Data="@orderDetails.Where(x=>x.VendorId == detail.VendorId)" TItem="OrderDetail" Class="mt-3">
                                            <Columns>
                                                <RadzenDataGridColumn TItem="OrderDetail" Property="Id" Title="Number" Width="100px" />
                                                <RadzenDataGridColumn TItem="OrderDetail" Property="ProductCode" Title="Code" Width="130px" />
                                                <RadzenDataGridColumn TItem="OrderDetail" Property="ProductName" Title="Name" Width="130px" />
                                                <RadzenDataGridColumn TItem="OrderDetail" Property="Currency" Title="Currency" Width="95px" />
                                                <RadzenDataGridColumn TItem="OrderDetail" Property="Quantity" Title="Quantity" Width="95px" />
                                                <RadzenDataGridColumn TItem="OrderDetail" Property="BuyUnitPrice" Title="Unit Price" Width="95px" />
                                                <RadzenDataGridColumn TItem="OrderDetail" Property="TotalBuyPrice" Title="Total Price" Width="95px" />

                                            </Columns>
                                        </RadzenDataGrid>
                                    </RadzenTabsItem>
                                }
                                detailVendorId = detail.VendorId;
                            }
                        </Tabs>
                    </RadzenTabs>
                </RadzenCard>
            </div>
        </div>
    }