Use Javascript addEventListener within Blazor component

1.7k Views Asked by At

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

There are 1 best solutions below

1
On BEST ANSWER

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.