razor.net-coreblazorblazor-client-side

How to use Bootstrap modal in Blazor client app?


I am trying to show bootstrap modal then bind its buttons. But I cannot pass the first step showing the modal. I am using Blazor client template of .net core 3.1. I have a page named Modal.razor which contains the bootstrap modal I found from getbootstrap.com.

@if (Show)
{
    <div class="modal" tabindex="-1" role="dialog">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Modal title</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <p>Modal body text goes here.</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary">Save changes</button>
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
}
@code {
    [Parameter]
    public bool Show { get; set; } = false;
}

An I called the modal in the index.razor file

@page "/"

<button @onclick="(()=>switchModal=!switchModal)">Switch Modal</button>

<Modal Show="switchModal"/>

@code{
    bool switchModal = false;
}

You might say StateHasChanged should be called here. But even if I copy and paste the modal code in the index.razor, I won't see anything.


Solution

  • There is likely a better way to do this, but here's a working example to get you started:

    Page:

    @page "/modal-test"
    
    <BlazorApp1.Components.Modal @ref="Modal"></BlazorApp1.Components.Modal>
    
    <button @onclick="() => Modal.Open()">Open Modal</button>
    
    @code {
        private BlazorApp1.Components.Modal Modal { get; set; }
    }
    

    Component:

    <div class="modal @ModalClass" tabindex="-1" role="dialog" style="display:@ModalDisplay">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Modal title</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <p>Modal body text goes here.</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary">Save changes</button>
                    <button type="button" class="btn btn-secondary" data-dismiss="modal" @onclick="() => Close()">Close</button>
                </div>
            </div>
        </div>
    </div>
    
    
    @if (ShowBackdrop)
    {
        <div class="modal-backdrop fade show"></div>
    }
    
    
    @code {
    
    
      public Guid Guid = Guid.NewGuid();
        public string ModalDisplay = "none;";
        public string ModalClass = "";
        public bool ShowBackdrop = false;
    
        public void Open()
        {
            ModalDisplay = "block;";
            ModalClass = "Show";
            ShowBackdrop = true;
            StateHasChanged();
        }
    
        public void Close()
        {
            ModalDisplay = "none";
            ModalClass = "";
            ShowBackdrop = false;
            StateHasChanged();
        }
    }
    

    Another option to go about this, would be to use JSInterop to call $('#modalId').modal()

    You could have each version of the component have a unique id by doing something like this: <div id="bootstrap-modal-@Guid" then use the saved ID to call .modal() with jQuery.