JavaScript UI Libraries & Blazor Components Suite – Smart UI › Forums › Docking Layout › Dynamically Add Blazor Component into Docking Layout
Tagged: blazor, blazor component, blazor docking layout, dynamic
- This topic has 3 replies, 2 voices, and was last updated 3 years ago by Yavor Dashev.
-
AuthorPosts
-
April 23, 2021 at 7:58 pm #101738softlandingcanadaMember
I would like to add an instance of a custom Blazor component as a smarttabwindow into an existing dockinglayout.
is this done through reder fragement, if so how do I do this?April 24, 2021 at 6:35 am #101740adminKeymasterHi Johnny,
You can use Blazor’s RenderFragment for that purpose.
Example:@page "/dockinglayout"<Example Name="DockingLayout"> <style> smart-docking-layout { width: 100%; height: 500px; max-width: 1000px; background-color: #EEEDF3; } smart-docking-layout .smart-items-container smart-splitter-item.smart-element, smart-docking-layout .smart-items-container > .smart-container > smart-splitter-item.smart-element { width: 50%; height: 50%; } smart-docking-layout smart-tabs-window smart-slider.smart-element, smart-docking-layout smart-tabs-window smart-multiline-text-box.smart-element { height: 100%; width: 100%; } smart-docking-layout smart-tabs-window smart-multiline-text-box.smart-element { display: block; } </style> <DockingLayout OnReady="OnReady" Layout=@layoutStructure> </DockingLayout> <div id="Input"> <br /> <br /> <TextArea Value="What is Lorem Ipsum?"></TextArea> </div> <div id="Slider"> <br /> <br /> <Slider Value="50" ShowButtons="true" TicksVisibility="TicksVisibility.Major" TicksPosition="TicksPosition.Track"></Slider> </div> <div id="Custom"> @DynamicRender </div> <Button @onclick="InjectBlazorComponent">Inject Component</Button></Example>@code { private object[] layoutStructure = new object[] { new { type = "LayoutGroup", orientation = "horizontal", items = new object[] { new { type = "LayoutGroup", size = 200, items = new object[] { new { type = "LayoutPanel", label = "Input", id = "tabPanel", items = new object[] { new { type = "LayoutPanel", label = "TextBox Tab", content = "#Input" }, new { type = "LayoutPanel", label = "Slider Tab", content = "#Slider" } } } } }, new { type = "LayoutPanel", label = "Output", items = new object[]{ new { id="outputTab", label = "Output", headerPosition = "none", content = "Write more text here..." } } } } }, new { id = "item0", label = "Tabs 0", items = new object[]{ new { label = "Tab A", selected = true, content = "#Custom" } } } }; private RenderFragment DynamicRender { get; set; } private void OnReady(DockingLayout dockingLayout) { } private RenderFragment CreateDynamicComponent() => builder => { builder.OpenComponent(0, typeof(SurveyPrompt)); builder.AddAttribute(1, "Title", "Some title"); builder.CloseComponent(); }; private void InjectBlazorComponent(MouseEventArgs args) { DynamicRender = CreateDynamicComponent(); }}
Hope this helps.
Best regards,
Boyko Markov
Smart UI Team
https://www.htmlelements.com/November 1, 2021 at 12:01 pm #102476horacio camachoParticipantHello,
With the example above a single docking item can be added dynamically. I tried to add multiple items dynamically (see example), but only the last item added renders its custom content.
Thank you,
Horacio
<hr />
<style> smart-docking-layout { width: 100%; height: 500px; max-width: 1000px; background-color: #EEEDF3; } smart-docking-layout .smart-items-container smart-splitter-item.smart-element, smart-docking-layout .smart-items-container > .smart-container > smart-splitter-item.smart-element { width: 50%; height: 50%; } smart-docking-layout smart-tabs-window smart-slider.smart-element, smart-docking-layout smart-tabs-window smart-multiline-text-box.smart-element { height: 100%; width: 100%; } smart-docking-layout smart-tabs-window smart-multiline-text-box.smart-element { display: block; } </style> <DockingLayout OnReady="OnReady" Layout=@layoutStructure> </DockingLayout> @foreach (var label in _labels) { <div id="@label"> "@label" </div> } <Button @onclick="InjectBlazorComponent">Inject Component</Button> @code { private List<object> layoutStructureTmp = new List<object>(); private List<object> layoutStructure = new List<object> { new { type = "LayoutGroup", orientation = "horizontal", items = new object[0] } }; private bool doRender; private RenderFragment DynamicRender { get; set; } private void OnReady(DockingLayout dockingLayout) { } private RenderFragment CreateDynamicComponent() => builder => { builder.OpenComponent(0, typeof(SurveyPrompt)); builder.AddAttribute(1, "Title", "Some title"); builder.CloseComponent(); }; protected override void OnAfterRender(bool firstRender) { if (doRender) { layoutStructure = layoutStructureTmp.ToList(); InvokeAsync(StateHasChanged).Wait(); } doRender = false; } int labelCounter = 0; List<string> _labels = new List<string>(); private void InjectBlazorComponent(MouseEventArgs e) { DynamicRender = CreateDynamicComponent(); layoutStructureTmp = layoutStructure.ToList(); labelCounter++; var label = "Custom" + labelCounter; if (!_labels.Contains(label)) { _labels.Add(label); } layoutStructureTmp.Add( new { id = "item" + labelCounter, label = "Tabs" + labelCounter, items = new object[]{ new { label = "Tab " + labelCounter, content = "#" + label } } } ); doRender = true; } }
November 1, 2021 at 3:25 pm #102478Yavor DashevParticipantHi horacio camacho,
I have modified you code snippet so that it may suit your needs and the cause of this behavior is because you are redefine the whole layout for the Docking layout in the
InjectBlazorComponent
method. You only need to set theitems
in order to add multiple tabs in the docking layout.Modified code:
<style> smart-docking-layout { width: 100%; height: 500px; max-width: 1000px; background-color: #EEEDF3; } smart-docking-layout .smart-items-container smart-splitter-item.smart-element, smart-docking-layout .smart-items-container > .smart-container > smart-splitter-item.smart-element { width: 50%; height: 50%; } smart-docking-layout smart-tabs-window smart-slider.smart-element, smart-docking-layout smart-tabs-window smart-multiline-text-box.smart-element { height: 100%; width: 100%; } smart-docking-layout smart-tabs-window smart-multiline-text-box.smart-element { display: block; } </style> <DockingLayout @red="dockingLayout" OnReady="OnReady" Layout=@layoutStructure> </DockingLayout> @foreach (var label in _labels) { <div id="@label"> "@label" </div> } <Button @onclick="InjectBlazorComponent">Inject Component</Button> @code { DockingLayout dockingLayout; private List<object> layoutStructureTmp = new List<object>(); private List<object> layoutStructure = new List<object> { new { type = "LayoutGroup", orientation = "horizontal", items = new object[0] } }; private bool doRender; private RenderFragment DynamicRender { get; set; } private void OnReady(DockingLayout dockingLayout) { } private RenderFragment CreateDynamicComponent() => builder => { builder.OpenComponent(0, typeof(SurveyPrompt)); builder.AddAttribute(1, "Title", "Some title"); builder.CloseComponent(); }; protected override void OnAfterRender(bool firstRender) { if (doRender) { layoutStructure = layoutStructureTmp.ToList(); InvokeAsync(StateHasChanged).Wait(); } doRender = false; } int labelCounter = 0; List<string> _labels = new List<string>(); private void InjectBlazorComponent(MouseEventArgs e) { List<object> NewItems = new List<object> (); for (int x=0;x<4;x++) { DynamicRender = CreateDynamicComponent(); layoutStructureTmp = layoutStructure.ToList(); labelCounter++; var label = "Custom" + labelCounter; if (!_labels.Contains(label)) { _labels.Add(label); } NewItems.Add( new { label = "Tab " + labelCounter, content = "#" + label } ); } doRender = true; layoutStructureTmp.Add( new { id = "item" + labelCounter, label = "Tabs" + labelCounter, items = NewItems } ); } }
Let me know if that works for you!
Please, do not hesitate to contact us if you have any additional questions.
Best regards,
Yavor DashevSmart UI Team
https://www.htmlelements.com/ -
AuthorPosts
- You must be logged in to reply to this topic.