AndyW
AndyW

Reputation: 441

How to use Bootstrap Collapse in Blazor app

I am just trying to create a small prototype application in Visual Studio using .Net 5/Blazor server app, where I need to have Bootstrap collapse functionality in a Blazor component - this would contain a separate Blazor component when expanded.

I am trying to avoid where possible to use JavaScript or jQuery in the prototype as much as possible. However, I can see that in some cases such as Bootstrap Collapse I may need to do this. I would like to have code local to the component if possible, but ok to having a .js file containing common helper functions if needed.

The code below gives an example with some ideas on how I might do this - does anyone have any ideas on how to get this to work.

    <div class="btn btn-primary" @onclick="ViewDetails" data-toggle="collapse" role="button" aria-expanded="false" aria-controls="details">
            this is some text for a button
        </div>
        <div class="collapse" id="details">
            this is the details screen for this record
        </div>
    
    @code {
     private async void ViewDetails()
        {
            // Button click indicates an event so should be able to get redraw to occur.  
    
            // Some mechanism to change the toggle state without calling javascript (dhtml style)
            // Use a boolean to change the ARIA state or something like that
            _viewDetails = (_viewDetails == false) ? true : false;
            this.StateHasChanged();
            
            // Or, call inline jquery to toggle control (preferred) something like.
            await _JSRuntime.InvokeVoidAsync("$('#details).collapse('toggle');", "");
        }
    }

Upvotes: 6

Views: 11548

Answers (2)

AndyW
AndyW

Reputation: 441

Here are the two solutions I used. I have upvoted replies above as they provided the info to resolve the issue.

solution 1:
In this solution I used the button click to toggle the visibility of a div tag (as above) to display the component.

Solution 2: (the one I used). Is to download the bootstrap bundle and extract it into my wwwroot directory (this contains all of the files required including popper). I then added a .js and .css reference in _host.cshtml to bootstrap.bundle.min.js and bootstrap.min.css respectively.

     <!-- using a bootstrap container with a unique id e.g. entity@1 -->
    <div class=container-fluid collapse" id="entity@(myid)">
    <div class="row">
       <div class="col-lg-12">
          <!-- the component that is displayed when the collapse is toggled -->
          <MyComponent componentId=@myid />
       </div>
    </div>
    </div>

The component is 
   @if (componentId > 0)
   {
      <!-- do razor code -->
   }
[Parameter] public Int32 componentId {get; set;}

Upvotes: 0

M. Folmer
M. Folmer

Reputation: 300

You could create a component dedicated to doing this. This will however not have the smooth transition from open to close as Bootstrap collapse. Notice this is wrapped in a Bootstrap card - use can simply remove that if not needed.

@using Microsoft.AspNetCore.Components

<div class="pb-3">
   <div class="card">
       <div class="card-header">
            <button class="btn btn-link" style="color: black; text-decoration: none" @onclick="Toggle">
               <b>@CardHeaderTitle</b>
            </button>
            @CardHeader
            <button @onclick="Toggle" type="button" class="btn btn-secondary btn-sm float-right">
                <span class="@BtnClass"></span>
            </button>
        </div>
        @if (ShowCardBody)
        {
            <div class="card-body">
                @CardBody
            </div>
        }
    </div>
</div>

@code {
    [Parameter] public RenderFragment CardBody { get; set; }
    [Parameter] public RenderFragment CardHeader { get; set; }
    [Parameter] public string CardHeaderTitle { get; set; }


    [Parameter] public bool ShowCardBody { get; set; } = false;
    public string BtnClass => ShowCardBody ? "oi oi-collapse-up" : "oi oi-collapse-down";
    public void Toggle()
    {
        ShowCardBody = !ShowCardBody;
    }
}

And then you can use it like this:

<CollapsibleCard CardHeaderTitle="Title">
    <CardHeader>
        ...
    </CardHeader>
    <CardBody>
        ...
    </CardBody>
</CollapsibleCard>

If you would like to use Bootstrap collapse try out the approach use a data-target explained here. This worked for me previous. Let me know if you need further help.

Upvotes: 7

Related Questions