A Blazor toast Notification is a user interface used for displaying small, transient messages to end users. Notifications that appear briefly at the top or bottom of the screen and then fade away usually inform the users about events such as success or failure without disrupting the user’s workflow. In this post, we will see how to create a Blazor Toast Notification with pure C#, Html and CSS.

Check out the completed Blazor Toast Notification implemented in a Blazor Web App.

https://dotnetcoder.com/wp-content/uploads/2024/05/Blazor-Toast-Notification-with-Pure-C-HTML-and-CSS.webm

In the previous post, we created a Blazor Toast Component that show messages but in a slightly different way. In this post we will create a component that shows notifications as you have seen above. For more details you can read Blazor Toast Component first.

Creating the Blazor Toast Notification Solution and adding a Razor class library project .NET 8

Open Visual Studio and create a blank solution named Toast and add a new Razor Class library named Dnc.Common.Razor to the solution. I selected .NET 8 (Long Term Support) as the target Framework.

Creating the DncWrapper component – Unfinished

A wrapper component is a component that encapsulates other components or elements within itself, There are many uses for this encapsulation, Including adding functionality, changing behavior, or simply changing the appearance of the encapsulated content.

The wrapper component encapsulates the Body property in the MainLayout component, and makes the Blazor toast Notification component available to all child components.

We start by creating a new folder called Wrapper in the Dnc.Common.Razor project and add a new class file called DncWrapperComponent.cs, which is derived from the ComponentBase class.

namespace Dnc.Common.Razor.Wrapper
{
    public class DncWrapperComponent:ComponentBase
    {
        [Parameter]
        public RenderFragment ChildContent { get; set; }
    }
}

We will add methods to the DncWrapperComponent component later.

In the Wrapper folder create a new file called DncWrapper.razor, which inherits from the DncWrapperComponent class, and enter the following mark-up.

@inherits DncWrapperComponent

<div class="dnc-wrapper">
    <CascadingValue Value="this">
        @ChildContent
    </CascadingValue>
</div>

Note that the component instance  DncWrapperComponent is passed on as a complex type to all descendent components as a cascading parameter.

Creating the Blazor Toast Notification Service

First we need to create a new folder called Enums and add an enum called ToastType. Here we need to add the four different notification types as follows.

namespace Dnc.Common.Razor.Enums
{
    public enum ToastType
    {
        Success, 
        Error,
        Warning, 
        Info
    }
}

Second create a new folder called Interfaces in the Dnc.Common.Razor project and add a new interface file called IToastService.

namespace Dnc.Common.Razor.Interfaces
{
    public interface IToastService
    {
        Task ShowSuccessToast(string message, string header, TimeSpan? duration = null);
        Task ShowErrorToast(string message, string header, TimeSpan? duration = null);
        Task ShowWarningToast(string message, string header, TimeSpan? duration = null);
        Task ShowInfoToast(string message, string header, TimeSpan? duration = null);
        void Close();

    }
}

The IToastService interface contains methods that are responsible for displaying the messages for a specific time or permanently.

Also read https://dotnetcoder.com/azure-service-bus-queue-trigger-azure-function/

Creating the Blazor Toast Notification Component

The Blazor Toast Notification component is responsible for displaying notifications to end users.
The notifications appears for a short time when you set the time span value and then disappears, or can be displayed until the end user closes it by clicking the close button.
The Blazor Toast Notification component is created with pure C#, Html and CSS only.

Create a new folder called Toast and add a class file called DncToastComponent, which is derived from the ComponentBase class and implements the IToastService and IDisposable interfaces as follows.

namespace Dnc.Common.Razor.Toast
{
    public class DncToastComponent : ComponentBase, IToastService, IDisposable
    {
        [CascadingParameter]
        protected DncWrapperComponent DncWrapper { get; set; }

        [Inject]
        protected NavigationManager NavigationManager { get; set; }
        protected bool Show { get; set; }
        private string currentLocation = string.Empty;

        protected string Header { get; set; }
        protected MarkupString Message { get; set; }
        protected string ToastBackgroundColor { get; set; }
        protected string ToastIconCss { get; set; }

        protected override void OnInitialized()
        {
            DncWrapper.SetToastService(this);
        }
        public void Close()
        {
            Show = false;
        }
        public void Dispose()
        {
            NavigationManager.LocationChanged -= NavigationHandler;
        }
        public async Task ShowSuccessToast(string message, string header, TimeSpan? duration = null)
        {
            await ShowToast(message, header, ToastType.Success, duration);
        }
        public async Task ShowErrorToast(string message, string header, TimeSpan? duration = null)
        {
            await ShowToast(message, header, ToastType.Error, duration);
        }
        public async Task ShowWarningToast(string message, string header, TimeSpan? duration = null)
        {
            await ShowToast(message, header, ToastType.Warning, duration);
        }
        public async Task ShowInfoToast(string message, string header, TimeSpan? duration = null)
        {
            await ShowToast(message, header, ToastType.Info, duration);
        }
        private async Task ShowToast(string message, string header, ToastType toastType, TimeSpan? duration = null)
        {
            Show = true;
            Message = (MarkupString)message;

            switch (toastType)
            {
                case ToastType.Success:
                    ToastBackgroundColor = "dnc-toast-success";
                    ToastIconCss = "check";
                    Header = string.IsNullOrEmpty(header) ? "Success" : header;
                    break;

                case ToastType.Error:
                    ToastBackgroundColor = "dnc-toast-error";
                    ToastIconCss = "times";
                    Header = string.IsNullOrEmpty(header) ? "Error" : header;
                    break;

                case ToastType.Warning:
                    ToastBackgroundColor = "dnc-toast-warning";
                    ToastIconCss = "exclamation";
                    Header = string.IsNullOrEmpty(header) ? "Warning" : header;
                    break;

                case ToastType.Info:
                    ToastBackgroundColor = "dnc-toast-info";
                    ToastIconCss = "info";
                    Header = string.IsNullOrEmpty(header) ? "Info" : header;
                    break;
            }

            currentLocation = NavigationManager.Uri;
            NavigationManager.LocationChanged -= NavigationHandler;
            NavigationManager.LocationChanged += NavigationHandler;
            StateHasChanged();

            if (duration != null)
            {
                await Task.Delay((TimeSpan)duration);
                Clear();
            }
        }
        private void NavigationHandler(object sender, LocationChangedEventArgs args)
        {
            if (!string.Equals(args.Location, currentLocation, StringComparison.OrdinalIgnoreCase))
            {
                Clear();
                NavigationManager.LocationChanged -= NavigationHandler;
                StateHasChanged();
            }
        }
        public void Clear()
        {
            Show = false;
            StateHasChanged();
        }
    }
}

We define a few properties and fields that will be used in the markup, and the DncWrapper component is injected into the DncToast component as a cascading parameter.

Next, we override the OnInitialized of Blazors component lifecycle events to make the methods of the DncToast component available in the DncWarpper component by using the SetToastService method , that is added to the DncWrapper component in the next section.

Then we created an event handler NavigationHandler , which is responsible for closing the message when the location changes.

Finally, ShowToase method , which is used by the other methods to display the different type of messages, sets the style of the toast message, the Header property, and sets the Show property to true , so that the notification is visible for a certain time if the duration is not null .

The markup of the Blazor Toast Notification component is simple and self-explanatory. In the Toast folder, create a new file called DncToast.razor, which inherits from the DncToastComponent class, and enter the following markup.

@inherits DncToastComponent

<div class="dnc-toast-container">
    <div class="dnc-toast fade @(Show ? "show" : "hide") @ToastBackgroundColor" role="alert" aria-live="assertive" aria-atomic="true">
        <div class="dnc-toast-header">
            <i class="fas fa-@ToastIconCss" aria-hidden="true"></i>
            <strong class="me-auto">@Header</strong>
            <a href="javascript:void(0)" @onclick="Close">
                <i class="fa fa-times dnc-toast-close"></i>
            </a>
        </div>
        <div class="dnc-toast-body">
            @Message
        </div>
    </div>
</div>

The style of the Blazor Toast Notification component is off topic.
In the Toast folder, create a new file called DncToast.razor.css,  and enter the following styles.

.dnc-toast-container {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 9999;
}

.dnc-toast {
    display: flex;
    flex-direction: column;
    border-radius: 5px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    color: #fff;
    min-width: 300px;
    overflow: hidden;
}

.dnc-toast-header {
    display: flex;
    align-items: center;
    padding: 10px 20px;
}

    .dnc-toast-header i {
        color: #fff;
        margin-right: 10px;
        font-size: 1.5em;
    }

    .dnc-toast-header .me-auto {
        flex-grow: 1;
        font-weight: bold;
        color: #fff;
    }

.dnc-toast-close {
    color: #fff;
    font-size: 16px;
    line-height: 1;
    background: transparent;
    border: 0;
    cursor: pointer;
}

.dnc-toast-body {
    padding: 15px 20px;
    font-size: 1em;
}

.dnc-toast.fade.show {
    opacity: 1;
    animation: slide-in 0.5s forwards;
}

.dnc-toast.hide {
    opacity: 0;
    animation: slide-in 0.5s forwards;
}

.dnc-toast-success {
    background-color: #4caf50;
}

    .dnc-toast-success .dnc-toast-header {
        background-color: #388e3c;
        border-bottom: 1px solid #4caf50;
    }

.dnc-toast-error {
    background-color: #f44336;
}

    .dnc-toast-error .dnc-toast-header {
        background-color: #d32f2f;
        border-bottom: 1px solid #f44336;
    }

.dnc-toast-warning {
    background-color: #ff9800;
}

    .dnc-toast-warning .dnc-toast-header {
        background-color: #f57c00;
        border-bottom: 1px solid #ff9800;
    }

.dnc-toast-info {
    background-color: #2196f3;
}

    .dnc-toast-info .dnc-toast-header {
        background-color: #1976d2;
        border-bottom: 1px solid #2196f3;
    }

Completing the DncWrapper component

The DncWrapper component wraps the entire application and provides the functionality of the Toast Component for all its children.

First, edit the DncWrapperComponent by adding the following methods.

namespace Dnc.Common.Razor.Wrapper
{
    public class DncWrapperComponent:ComponentBase
    {
        [Parameter]
        public RenderFragment ChildContent { get; set; }
        protected IToastService ToastService { get; set; }

        public void SetToastService(IToastService toastService)
        {
            ToastService = toastService;
        }

        public void ShowSuccessToast(string message, string header = null, TimeSpan? duration = null)
        {
            ToastService?.ShowSuccessToast(message, header, duration);
        }
        public void ShowErrorToast(string message, string header = null, TimeSpan? duration = null)
        {
            ToastService?.ShowErrorToast(message, header, duration);
        }
        public void ShowWarningToast(string message, string header = null, TimeSpan? duration = null)
        {
            ToastService?.ShowWarningToast(message, header, duration);
        }
        public void ShowInfoToast(string message, string header =null, TimeSpan? duration = null)
        {
            ToastService?.ShowInfoToast(message, header, duration);
        }
    }
}

Use of the Blazor Toast Notification in the Blazor Web App .NET 8

In this section we will learn how to use our custom Blazor Toast Notification component in the Blazor application.

First, add a new Blazor Web App project template named Dnc.Toast.WebApp to the solution. I selected .NET 8 (Long Term Support) as the target Framework.

The solution should look like this.

Blazor Toast Notification Projects

Second reference the Dnc.Common.Razor project to the  Dnc.Toast.WebAppproject, and update the _Imports.razor as follows.

@using Dnc.Common.Razor.Wrapper
@using Dnc.Common.Razor.Toast
@using Dnc.Common.Razor.Enums

Then encapsulate the MainLayout.razor component with the DncWrapper component as follows.

@inherits LayoutComponentBase
<DncWrapper>
    <DncToast />
    <div class="container">
        @Body
    </div>
</DncWrapper>

Finally, insert the following code into the Home.razor and start the application.

@page "/"

<PageTitle>Home</PageTitle>

<div class="container">
    <div class="row">
        <div class="col">
            <div class="center-block">
                <div class="btn-group-vertical" role="group" aria-label="Vertical button group">
                    <button class="btn btn-success" @onclick="ShowSuccess">Show success toast</button>
                    <button class="btn btn-danger" @onclick="ShowError">Show error toast</button>
                    <button class="btn btn-warning" @onclick="ShowWarning">Show warning toast</button>
                    <button class="btn btn-info" @onclick="ShowInfo">Show info toast</button>
                </div>
            </div>
        </div>
    </div>
</div>

@code {

    [CascadingParameter]
    public DncWrapper DncWrapper { get; set; }

    public void ShowSuccess()
    {
        // DncWrapper.ShowSuccessToast("Success Toast Message", null, TimeSpan.FromSeconds(3));
        DncWrapper.ShowSuccessToast("Success Toast Message");
    }
    public void ShowError()
    {
        // DncWrapper.ShowErrorToast("This is Error Message", TimeSpan.FromSeconds(5));
        DncWrapper.ShowErrorToast("Error Toast Message");
    }
    public void ShowWarning()
    {
        // DncWrapper.ShowWarningToast("This is Warning Message", TimeSpan.FromSeconds(5));
        DncWrapper.ShowWarningToast("Warning Toast Message", "Custom title");
    }
    public void ShowInfo()
    {
        DncWrapper.ShowInfoToast("This will disappears after 3 sec", null, TimeSpan.FromSeconds(5));
        // DncWrapper.ShowInfoToast("This is Info Toast Message");
    }
}
Success blazor toast notification in action
Warning blazor toast notification in action

Conclusion

In this post we created a Blazor Toast Notification component that can be used in your different projects. We started by creating a wrapper component that encapsulates the Body property in the MainLayout component, which provides the Blazor Toast Notification functionality for the encapsulated content. I did not go through the CSS code because it’s off topic for this post.

The code for the Blazor Toast component can be found Here

Also read https://dotnetcoder.com/creating-a-blazor-dropdown-list-component/

Author

Exit mobile version