Modal Dialog component for Blazor

Blazor Background 2

In this post, I explain how to implement a Modal Dialog component for Blazor WebAssembly that we can use everywhere in our applications. We learn how to use arguments in event callbacks, and we learn about the power of reusable components.

For more documentation, example and components about Blazor, here same links in this blog:

Create the Modal Dialog Component

First, let’s jump into Visual Studio and create the ModalDialog component. First of all, let’s create a new Razor component in the Components folder. We right-click the Components folder and add a new Razor Component.

Add New Item in Visual Studio 2019 - Modal Dialog component for Blazor
Add New Item in Visual Studio 2019

In the new item dialog, we name the component ModalDialog. I press the add button, and Visual Studio closes the dialog and creates a new file.

First of all, I insert a code snippet with the template for the modal dialog.

<div class="modal fade show" id="myModal" style="display:block; background-color: rgba(10,10,10,.8);" 
     aria-modal="true" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">This is the title</h4>
                <button type="button" class="close">&times;</button>
            </div>
            <div class="modal-body">
                <p>This is the message text.</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary">OK</button>
            </div>
        </div>
    </div>
</div>

So, I use Bootstrap to build the user interface. Bootstrap offers predefined CSS classes that we can use to create a modal dialog component. Before we change the template and make it more dynamic, let’s use the ModalDialog component on the Index page.

Now, scroll down to the end of the page and add a reference to the ModalDialog component. Let’s start the application and take a first look at our ModalDialog component in action.

<ModalDialog />
First look at the ModalDialog - Modal Dialog component for Blazor
First look at the ModalDialog

Now, run the application. The page shows immediately the ModalDialog. I would say it looks great. However, we cannot interact with the dialog yet. It doesn’t matter if you click the OK button or press the cross in the dialog’s top-right corner. Also, we see static text and a static title in the dialog.

So, let’s head back to Visual Studio to make the component more dynamic and useful.

Implement Parameters

Now, back in Visual Studio, we open the ModalDialog component. First of all, let’s create properties to hold the title and the text of the dialog. 

Again, we want to make those properties available when using the component in another component. Therefore, we add the Parameter attribute to the property definitions.

<div class="modal fade show" id="myModal" 
     style="display:block; background-color: rgba(10,10,10,.8);" 
     aria-modal="true" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">@Title</h4>
                <button type="button" class="close">&times;</button>
            </div>
            <div class="modal-body">
                <p>@Text</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary">OK</button>
            </div>
        </div>
    </div>
</div>

@code {
    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public string Text { get; set; }
}

Next, we replace the static text with the variables we just created. Remember to use the @ symbol in front of the variable name.

Implement Behavior

Now that we have the basic properties set up let’s add some behavior to the component. We want to build a component that can be used in different places across the application. That’s why we cannot implement business-specific code in this component. 

Instead, we let the caller of our component decide what to do based on how the user interacts with the ModalDialog component.

Let’s define another parameter for our ModalDialog component. This time, we use the EventCallback type again. But other than in the previous video, we also use the generic type argument and define the OnClose property as EventCallback of boolean.

[Parameter]
public EventCallback<bool> OnClose { get; set; }

Next, let’s implement methods that we can bind to the template and execute the OnClose callback.

We start by implementing a private ModalCancel method. The implementation is simple. We use the OnClose callback and call its InvokeAsync method and provide false as its argument.

private Task ModalCancel()
{
    return OnClose.InvokeAsync(false);
}

private Task ModalOk()
{
    return OnClose.InvokeAsync(true);
}

Next, we implement a private ModalOk method. Again, we use the OnClose callback and call its InvokeAsync method. However, this time, we provide true as its argument.

Now, let’s bind those methods to the template.

<div class="modal fade show" id="myModal" style="display:block; background-color: rgba(10,10,10,.8);" 
     aria-modal="true" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">@Title</h4>
                <button type="button" class="close" @onclick="@ModalCancel">&times;</button>
            </div>
            <div class="modal-body">
                <p>@Text</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary" @onclick=@ModalOk>OK</button>
            </div>
        </div>
    </div>
</div>

For the close button on the top-right corner defined on line 6, we add the onclick-attribute and use the ModalCancel method. Again, make sure to use the @ symbol in front of the method name.

We do the same for the OK button, except that we bind the ModalOk method instead.

Adjusting the page

So, before we can test the component again and complete the creation of the Modal Dialog component for Blazor, we need to adjust the code in the page where we use the component.

Let’s start by creating a bool property that we can use to decide if the page should show the modal dialog. We define a DeleteDialogOpen property of type bool.

public bool DeleteDialogOpen { get; set; }

Next, we change the template and use an if-statement to show the ModalDialog only when the DeleteDialogOpen property is true.

@if (DeleteDialogOpen)
{
    <ModalDialog Title="Are you sure?"
                 Text="Do you want to delete this entry?"
                 OnClose="@OnDeleteDialogClose">
    </ModalDialog>
}

Now, let’s add the missing arguments to the ModalDialog. We set the title and the text properties. For the OnClose property, we define a reference to the OnDeleteDialogClose method we are going to implement next.

The OnClose argument is not provided by IntelliSense. It turns out I forgot to add the Parameter-Attribute in the definition. Let’s head back to the ModalDialog component and fix that.

Back in the Earnings page, let’s implement the OnDeleteDialogClose method.

private async Task OnDeleteDialogClose(bool accepted)
    {
        DeleteDialogOpen = false;
        StateHasChanged();
    }

We define a private OnDeleteDialogClose method with a single argument of type bool. The argument contains the information on whether the user has confirmed or canceled the dialog. In this method, we set the DeleteDialogOpen property to false and call the StateHasChanged method.

Last but not least, we implement a private OpenDeleteDialog method returning void. In this method, we set the DeleteDialogOpen property to true.

private void OpenDeleteDialog()
{
    DeleteDialogOpen = true;
    StateHasChanged();
}

Now we need to use the OpenDeleteDialog method in the template. Let’s create another column in the table to hold the delete button. I prepared another snippet for the delete button itself.

<button type="button" class="btn btn-danger btn-sm" 
        @onclick="() => OpenDeleteDialog(earning)">Delete</button>

Now that’s everything in place, let’s start the application again.

Conclusion

At the end of this post, we have a Modal Dialog component for Blazor to reuse in our applications. The source code of the component is on GitHub or you can add the component from its NuGet package.

8 thoughts on “Modal Dialog component for Blazor

  1. I followed your code and also watched the same tutorial on Youtube. I created a new project for it and everything, new pages, etc. For the life of me I can’t get it to do a popup. So the popup work before placing the code in the if statement. So you go to the page and the modal happens instantly. anything after that fails and when I click on a button to test the modal, it redirects me to the homepage.

    Any advice you can give me would be greatly appreciated because I have spent 2 days going over tutorial after tutorial and every time I do a popup (modal) it just redirect to the homepage and I can’t seem to figure out why. Thank you for any hep you can give.

    -Mike

  2. To be more specific. Click on the button redirects to a “Hello World” & Survey page. I can’t seem to make it not go there.

  3. I am so incredibly sorry for all the messages. I finally solved the problem. I was using a different style of button . I decided to just used a button like you did and that solved the problem.

      1. Enrico, Actually I do need your help. I was able to get the popup to work on a standard .NET Blazor site. I am using a template and it’s fighting me every step of the way. I am trying to figure out why the close functions aren’t responding in the C# code. I am hoping you can help. Not sure where you are located, but would you be up for faster communication like Skype or something?

  4. Enrico, Just in case you don’t feel comfortable with an actual messaging platform. When using a template like Tabler that is built on top of Blazor, is there any way they can prevent me from creating a standard out of the box modal? Is there any specific files that need to be imported to make the Modal work? Anything like some javascript, css, or anything of that sort? Because I got your example to work in a standard Blazor, but standard Blazor has a crappy Menu system that is why I decided to use Tabler as a template. Just incase you want to see Tabler, they have a github where you can download the files.

    https://github.com/joadan/TabBlazor

    Thanks for any help you can give.

    -Mike

  5. Enrico. Again sorry for my stupidity. I spent yesterday and today resolving this stupid Modal, and when I ported it over from Blazor to this Tabler Blazor template, I forgot 1 thing. I am sorry for being an idiot. 🙂 Hope you have a great day, and thank you for the awesome video.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.