I have a Blazor .Net 8 webb app that uses a Bootstrap 5.3 Offcanvas component as a menu of items that can be selected from. When the user chooses the menu item, I want the Offcanvas component to close automatically.
The way I did this was to create a ButtonClicked
event that calls the JavaScript like this
`await JS.InvokeVoidAsync("closeOffcanvas");`
This is called right before the OnFilterSelected EventCallback
For the Bootstrap I’m using data-bs
attributes. I searched extensively for a solution to no avail. The JavaScript I came up with can be seen below closeOffcanvas.js
below). I’m at best a novice java script programmer
Below is the relevant code, for a working example see this GitHub repo
Any help would be appreciative.
closeOffcanvas.js
window.closeOffcanvas = function () {
var offcanvasElement = document.getElementById("offcanvasid");
var offcanvas = new bootstrap.Offcanvas(offcanvasElement);
offcanvas.hide();
};
Filter.razor
<button class="btn btn-primary btn-sm" data-bs-toggle="offcanvas" data-bs-target="#offcanvasid">
Contents
<i class="fas fa-bars"></i>
</button>
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasid">
<div class="offcanvas-header">
<span class=""></span>
<button type="button" class="btn-close"
data-bs-dismiss="offcanvas" aria-label="Close">
</button>
</div>
<div class="offcanvas-body">
<ul class="list-group">
@foreach (var item in Enums.MenuItem.List.OrderBy(o => o.Value))
{
<li class="list-group-item @ActiveFilter(item)">
<a @onclick="@(e => ButtonClicked(item))"
type="button"
id="@item.ButtonId">
@item.Value <small>@item.Title</small>
</a>
</li>
}
</ul>
</div>
</div>
@code
[Parameter, EditorRequired] public required Enums.MenuItem? CurrentFilter { get; set; }
[Parameter] public EventCallback<Enums.MenuItem> OnFilterSelected { get; set; }
protected Enums.MenuItem currentMenuItem = Enums.MenuItem.HebrewPassOverOrCrossOver;
private async Task ButtonClicked(Enums.MenuItem filter)
{
currentMenuItem = filter;
// calling this doesn't close the component
// It also disables the close button
await JS.InvokeVoidAsync("closeOffcanvas");
await OnFilterSelected.InvokeAsync(filter);
}
// other code
Index.razor
This is the razor page that calls Filter.razor component
@page "/"
<h1>Home</h1>
<div class="d-flex justify-content-end mx-1">
<Filter CurrentFilter=@CurrentFilter OnFilterSelected="@ReturnedFilter" />
</div>
<!-- Do something with the chosen filter -->
@code
public MenuItem CurrentFilter { get; set; } = MenuItem.HebrewPassOverOrCrossOver; // default item
private void ReturnedFilter(MenuItem filter)
{
CurrentFilter = filter;
StateHasChanged();
}
2
Answers
Here’s a demo page using the code example from the Bootstrap demo page that shows how to show and hide the off-canvas content directly in c#.