---
sidebar_position: 5
title: Creation of a confirmation popup
---
## Creation of a confirmation popup
In order to create our popup, create the `Modals` folder at the root of the site.
Create the razor component `DeleteConfirmation.razor` and its class `DeleteConfirmation.razor.cs`.
```cshtml title="Modals/DeleteConfirmation.razor"
Are you sure you want to delete @item.DisplayName ?
```
```csharp title="Modals/DeleteConfirmation.razor.cs"
public partial class DeleteConfirmation
{
[CascadingParameter]
public BlazoredModalInstance ModalInstance { get; set; }
[Inject]
public IDataService DataService { get; set; }
[Parameter]
public int Id { get; set; }
private Item item = new Item();
protected override async Task OnInitializedAsync()
{
// Get the item
item = await DataService.GetById(Id);
}
void ConfirmDelete()
{
ModalInstance.CloseAsync(ModalResult.Ok(true));
}
void Cancel()
{
ModalInstance.CancelAsync();
}
}
```
Open the `Pages/List.razor.cs` file and add the changes:
```csharp title="Pages/List.razor.cs"
...
[Inject]
public NavigationManager NavigationManager { get; set; }
[CascadingParameter]
public IModalService Modal { get; set; }
...
private async void OnDelete(int id)
{
var parameters = new ModalParameters();
parameters.Add(nameof(Item.Id), id);
var modal = Modal.Show("Delete Confirmation", parameters);
var result = await modal.Result;
if (result.Cancelled)
{
return;
}
await DataService.Delete(id);
// Reload the page
NavigationManager.NavigateTo("list", true);
}
```
## Concept: Cascading Parameters
### Component `CascadingValue`
An ancestor component provides cascading value using the `CascadingValue` framework Blazor component, which encapsulates a subtree of a component hierarchy and provides a unique value to all components in its subtree.
The following example shows the flow of theme information through the component hierarchy of a layout component to provide a CSS style class to child component buttons.
The following `ThemeInfo` C# class is placed in a folder named `UIThemeClasses` and specifies theme information.
:::info
For the samples in this section, the application namespace is BlazorSample . When experimenting with the code in your own sample application, replace the application namespace with the namespace of your sample application.
:::
```csharp title="UIThemeClasses/ThemeInfo.cs"
namespace BlazorSample.UIThemeClasses
{
public class ThemeInfo
{
public string? ButtonClass { get; set; }
}
}
```
The following layout specifies theme information ( `ThemeInfo` ) as a cascading value for all components that make up the layout body of the `Body` property.
The value `ButtonClass` is assigned to `btn-success`, which is a style of start button. Any component descending in the component hierarchy can use the `ButtonClass` property through the cascading `ThemeInfo` value.
```cshtml title="Shared/MainLayout.razor"
@inherits LayoutComponentBase
@using BlazorSample.UIThemeClasses
@Body
@code {
private ThemeInfo theme = new() { ButtonClass = "btn-success" };
}
```
### Attribute `[CascadingParameter]`
To use cascading values, descendant components declare cascading parameters using the `[CascadingParameter]` attribute.
Cascading values are related to cascading parameters by type.
The following component binds the cascading `ThemeInfo` value to a cascading parameter, optionally using the same `ThemeInfo` name. The parameter is used to define the CSS class for the `Increment Counter (Themed)` button.
```cshtml title="Pages/ThemedCounter.razor"
@page "/themed-counter"
@using BlazorSample.UIThemeClasses
Themed Counter
Current count: @currentCount
@code {
private int currentCount = 0;
[CascadingParameter]
protected ThemeInfo? ThemeInfo { get; set; }
private void IncrementCount()
{
currentCount++;
}
}
```
### Cascading Multiple Values
To cascade multiple values of the same type in the same subtree, supply a unique `Name` string to each `CascadingValue` component and its corresponding `[CascadingParameter]` attributes.
In the following example, two `CascadingValue` components cascade different instances of `CascadingType`:
```cshtml
...
@code {
private CascadingType parentCascadeParameter1;
[Parameter]
public CascadingType ParentCascadeParameter2 { get; set; }
...
}
```
In a descendant component, cascading parameters receive their cascading values from the ancestor component with the `Name` attribute:
```cshtml
...
@code {
[CascadingParameter(Name = "CascadeParam1")]
protected CascadingType ChildCascadeParameter1 { get; set; }
[CascadingParameter(Name = "CascadeParam2")]
protected CascadingType ChildCascadeParameter2 { get; set; }
}
```
### Pass data in a component hierarchy
Cascading parameters also allow components to pass data through a component hierarchy.
Consider the following UI tab set example, where a tab set component manages a series of individual tabs.
Create an `ITab` interface that tabs implement in a folder named `UIInterfaces`.
```csharp title="UIInterfaces/ITab.cs"
using Microsoft.AspNetCore.Components;
namespace BlazorSample.UIInterfaces
{
public interface ITab
{
RenderFragment ChildContent { get; }
}
}
```
The following `TabSet` component manages a set of tabs. The components of the `Tab` tab set, which are created later in this section, provide the list items ( `
...
` ) of the list ( `
...
` ).
`Tab` child components are not explicitly passed as parameters to `TabSet`.
Instead, `Tab` child components are part of `TabSet` child content.
However, the `TabSet` still requires a `Tab` reference to each component in order to display the headers and the active tab.
To enable this coordination without requiring additional code, the `TabSet` component can present itself as a cascading value which is then retrieved by descendant `Tab` components.
```cshtml title="Shared/TabSet.razor"
@using BlazorSample.UIInterfaces
@ChildContent
@ActiveTab?.ChildContent
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public ITab ActiveTab { get; private set; }
public void AddTab(ITab tab)
{
if (ActiveTab == null)
{
SetActiveTab(tab);
}
}
public void SetActiveTab(ITab tab)
{
if (ActiveTab != tab)
{
ActiveTab = tab;
StateHasChanged();
}
}
}
```
Descendant `Tab` components capture the `TabSet` container as a cascading parameter. The `Tab` components add to the `TabSet` coordinate and to set the active tab.
```cshtml title="Shared/Tab.razor"
@using BlazorSample.UIInterfaces
@implements ITab