1

I have a Blazor component which is rendered server-side. And I would like to have some collapsible divs inside of it. However since the code is server rendered the Javascript is not executed therefore the parts cannot collapse.

Here is the code inside my script.js file :

var coll = document.getElementsByClassName("collapsible");
var i;

for (i = 0; i < coll.length; i++) {
    coll[i].addEventListener("click", function() {
        this.classList.toggle("active");
        var content = this.nextElementSibling;
        if (content.style.maxHeight){
            content.style.maxHeight = null;
        } else if(window.matchMedia("(max-width:1440px)")){
            // content.style.maxHeight = content.scrollHeight + "px";
            content.style.maxHeight = "20vh";
        } 
        else {
            content.style.maxHeight = "50vh";
        }
    });
}

Here is my main.cshtml file :

<component type="typeof(Main)" render-mode="Server" />

<script src="~/js/script.js" type="text/javascript"></script>

And finally my Main component with the collapsible parts :

@using Microsoft.AspNetCore.Components;
@using Microsoft.AspNetCore.Components.Web;

<div class="collapsible">
    <label for="tutu">HEADER</label>
    <div id="mybtn" class="btn-rch"></div>
</div>

<div class="tutu content flex-column">
    <p>CONTENT HIDDEN IN COLLAPSE</p>
</div>

<div class="collapsible">
    <label for="tutu">HEADER</label>
    <div id="mybtn" class="btn-rch"></div>
</div>

<div class="tutu content flex-column">
    <p>CONTENT HIDDEN IN COLLAPSE</p>
</div>

<div class="collapsible">
    <label for="tutu">HEADER</label>
    <div id="mybtn" class="btn-rch"></div>
</div>

<div class="tutu content flex-column">
    <p>CONTENT HIDDEN IN COLLAPSE</p>
</div>

@code {

}

If I use render-mode="Static" instead of render-mode="Server" it works, but since my component will have event inside of it is not a possibility for me. How can I, with the use of JSInterop for example, call my JS script to make my div collapse ?

1 Answer 1

5

You can do all this in Blazor. Below is a simplistic working example of what I think you are trying to achieve.

This is a collapsible div component.

CollapseDiv.razor

<div @onclick="Collapse" style="cursor:pointer;" >
    <h2>@Label</h2>
</div>
@if (!Collapsed)
{
    <div>@ChildContent</div>
}

@code {

    [Parameter] public RenderFragment ChildContent { get; set; }

    [Parameter] public RenderFragment Label { get; set; }

    bool Collapsed;

    void Collapse(MouseEventArgs e)
    {
        Collapsed = !Collapsed;
    }
}

And this is the page to demo it:

Collapse.razor

@page "/collapse"
<h3>Collapse Test Page</h3>

<CollapseDiv>
    <Label>I'm Collapsible</Label>
    <ChildContent>
        I'm the collapsed content!
    </ChildContent>
</CollapseDiv>
<br />
<br />
<CollapseDiv>
    <Label>I'm Collapsible Too</Label>
    <ChildContent>
        More collapsed content!
    </ChildContent>
</CollapseDiv>

@code {

}

The key here is: Forget manipulating the DOM with Javascript, build components.

You should be able to adopt this to fit your needs.

Sign up to request clarification or add additional context in comments.

1 Comment

Sadly, we need to add some animations and change classes of stuff using javascript. But I keep your solution in mind as it is really simple and clean !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.