JavaScript UI Libraries & Blazor Components Suite – Smart UI Forums Docking Layout Dynamically Add Blazor Component into Docking Layout

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #101738
    Up
    0
    Down

    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?

    #101740
    admin
    Keymaster
    Up
    0
    Down

    Hi 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/

    #102476
    horacio camacho
    Participant
    Up
    0
    Down

    Hello,

    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;
        }
    }

     

    #102478
    Yavor Dashev
    Participant
    Up
    0
    Down

    Hi 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 the items 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 Dashev

    Smart UI Team
    https://www.htmlelements.com/

Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.