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 codeIndex.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(); }