javascript.netblazorbootstrap-5off-canvas-menu

Disable bootstrap offcanvas closure on backdrop click in Blazor .NET app


I have been trying to create an offcanvas window form and I want to make sure the offcanvas window does not close unless the user explicitly click the close button on the offcanvas window. Due to couple of requirements provided by my client, I have to call the offcanvas window through C# call by injecting IJSRuntime rather than directly calling from HTML.

I am using Blazor framework .net 8 version and here are the codes that I wrote:

In my razor file:

<button class="btn btn-primary" type="button" data-bs-dismiss="offcanvas" data-bs-backdrop="static" @onclick="() => ShowCanvas()">Show Canvas</button>

And the C# code block:

async void ShowCanvas()
{
    await JS.InvokeVoidAsync("showOffCanvas");
}

And finally my Javascript code:

function showOffCanvas() {
    var myCanvas = new bootstrap.Offcanvas(document.getElementById('offcanvasWindow'));
    myCanvas.show();
}

After running the .net application, I came across an exception which I cant seem able to solve. Here are the details of the exception:

Microsoft.JSInterop.JSException: 'OFFCANVAS: Option "backdrop" provided type "string" but expected type "boolean".
TypeError: OFFCANVAS: Option "backdrop" provided type "string" but expected type "boolean".
    at https://localhost:7256/js/bootstrap.bundle.min.js:6:1030
    at Array.forEach (<anonymous>)
    at a (https://localhost:7256/js/bootstrap.bundle.min.js:6:862)
    at Fi._getConfig (https://localhost:7256/js/bootstrap.bundle.min.js:6:56127)
    at new Fi (https://localhost:7256/js/bootstrap.bundle.min.js:6:54655)
    at showModalItemMasterForm (https://localhost:7256/js/bootstrap-calls.js:42:20)
    at https://localhost:7256/_framework/blazor.web.js:1:3244
    at new Promise (<anonymous>)
    at y.beginInvokeJSFromDotNet (https://localhost:7256/_framework/blazor.web.js:1:3201)
    at fn._invokeClientMethod (https://localhost:7256/_framework/blazor.web.js:1:62914)'

Anyway I can solve this issue using IJSRuntime method?

Thanks

I also tried not putting data-bs-dismiss="offcanvas" attribute and instead modified the JS code to the following:

function showModalItemMasterForm() {
    var myCanvas = new bootstrap.Offcanvas(document.getElementById('offcanvasWindow'), 
    { backdrop: 'static', keyboard: false });
    myCanvas.show();
}

I am getting the same error.


Solution

  • You don't need to use any JS to interact with an OffCanvas. Here's a JS free very simplistic implementation.

    OffCanvas.razor

    <div class="@_showCss" tabindex="-1">
        <div class="offcanvas-header">
            <h5 class="offcanvas-title">Offcanvas Header</h5>
            <button type="button" class="btn-close text-reset" @onclick="this.Hide"></button>
        </div>
        <div class="offcanvas-body">
            <p>
                Content for the offcanvas goes here. You can place just about any Bootstrap component or custom elements here.
            </p>
        </div>
    </div>
    @if (this.Show)
    {
        <div class="modal-backdrop fade show"></div>
    }
    
    @code {
        [Parameter] public bool Show { get; set; }
        [Parameter] public EventCallback<bool> ShowChanged { get; set; }
        private string _showCss => this.Show ? "offcanvas offcanvas-start show off-canvas-show" : "offcanvas offcanvas-start  off-canvas-hide";
        private TaskCompletionSource? _taskCompletionSource;
    
        public void Hide()
        {
            this.ShowChanged.InvokeAsync(false);
        }
    }
    

    OffCanvas.razor.css

    .off-canvas-show {
        visibility:visible;
        z-index:1100 !important;
    }
    .off-canvas-hide {
        visibility: hidden;
    }
    

    And Home demo:

    @page "/"
    
    <PageTitle>Home</PageTitle>
    
    <h1>Hello, world!</h1>
    
    Welcome to your new app.
    
    <div class="m-2">
        <btn class="btn btn-primary" @onclick="Open">Show OffCanvas</btn>
    </div>
    
    <OffCanvas @bind-Show="_showOffCanvas"/>
    
    @code {
        private OffCanvas? _offCanvas;
        private bool _showOffCanvas;
    
        private void Open()
        {
            _showOffCanvas = true;
        }
    }