@ -1267,78 +1267,81 @@ Editing a books is similar to the creating a new book.
### Actions Dropdown
Open the `Books.razor` and add the following `DataGrid Column` section inside the `DataGridColumns` as the first item:
Open the `Books.razor` and add the following `DataGrid EntityActions Column` section inside the `DataGridColumns` as the first item:
````xml
< DataGridColumn Width = "150px"
TItem="BookDto"
Field="@nameof(BookDto.Id)"
Sortable="false"
Caption="@L["Actions"]">
< DataGridEntityActionsColumn TItem = "BookDto" @ref ="@ EntityActionsColumn " >
< DisplayTemplate >
< Dropdown >
< DropdownToggle Color = "Color.Primary" >
@L ["Actions"]
< / DropdownToggle >
< DropdownMenu >
< DropdownItem Clicked = "() => OpenEditModalAsync(context)" >
@L ["Edit"]
< / DropdownItem >
< / DropdownMenu >
< / Dropdown >
< EntityActions TItem = "BookDto" EntityActionsColumn = "@EntityActionsColumn" >
< EntityAction TItem = "BookDto"
Text="@L["Edit"]"
Clicked="() => OpenEditModalAsync(context)" />
< / EntityActions >
< / DisplayTemplate >
< / DataGrid Column>
< / DataGridEntityActionsColumn >
````
* `OpenEditModalAsync` is defined in the base class which takes the entity (book) to edit.
This adds an "Actions" dropdown to all the books inside the `DataGrid` with an `Edit` action :
`DataGridEntityActionsColumn` component is used to show an "Actions" dropdown for each row in the `DataGrid` . `DataGridEntityActionsColumn` shows a **single button** instead of a dropdown if there is only one available action inside it :


### Edit Modal
We can now define a modal to edit the book. Add the following code to the end of the `Books.razor` page:
````xml
< Modal @ref =" EditModal " >
< Modal @ref =" @ EditModal " >
< ModalBackdrop / >
< ModalContent IsCentered = "true" >
< ModalHeader >
< ModalTitle > @EditingEntity.Name< / ModalTitle >
< CloseButton Clicked = "CloseEditModalAsync" / >
< / ModalHeader >
< ModalBody >
< Field >
< FieldLabel > @L["Name"]< / FieldLabel >
< TextEdit @bind -text = "EditingEntity.Name" />
< / Field >
< Field >
< FieldLabel > @L["Type"]< / FieldLabel >
< Select TValue = "BookType" @bind -SelectedValue = "@EditingEntity.Type" >
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
< SelectItem TValue = "BookType" Value = "@((BookType)bookTypeValue)" >
@L [$"Enum:BookType:{bookTypeValue}"]
< / SelectItem >
}
< / Select >
< / Field >
< Field >
< FieldLabel > @L["PublishDate"]< / FieldLabel >
< DateEdit TValue = "DateTime" @bind -Date = "EditingEntity.PublishDate" />
< / Field >
< Field >
< FieldLabel > @L["Price"]< / FieldLabel >
< NumericEdit TValue = "float" @bind -Value = "EditingEntity.Price" />
< / Field >
< / ModalBody >
< ModalFooter >
< Button Color = "Color.Secondary"
Clicked="CloseEditModalAsync">@L["Cancel"]< / Button >
< Button Color = "Color.Primary"
Clicked="UpdateEntityAsync">@L["Save"]< / Button >
< / ModalFooter >
< Form >
< ModalHeader >
< ModalTitle > @EditingEntity.Name< / ModalTitle >
< CloseButton Clicked = "CloseEditModalAsync" / >
< / ModalHeader >
< ModalBody >
< Validations @ref ="@ EditValidationsRef " Model = "@NewEntity" ValidateOnLoad = "false" >
< Validation MessageLocalizer = "@LH.Localize" >
< Field >
< FieldLabel > @L["Name"]< / FieldLabel >
< TextEdit @bind -Text = "@EditingEntity.Name" >
< Feedback >
< ValidationError / >
< / Feedback >
< / TextEdit >
< / Field >
< / Validation >
< Field >
< FieldLabel > @L["Type"]< / FieldLabel >
< Select TValue = "BookType" @bind -SelectedValue = "@EditingEntity.Type" >
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
< SelectItem TValue = "BookType" Value = "@((BookType) bookTypeValue)" >
@L [$"Enum:BookType:{bookTypeValue}"]
< / SelectItem >
}
< / Select >
< / Field >
< Field >
< FieldLabel > @L["PublishDate"]< / FieldLabel >
< DateEdit TValue = "DateTime" @bind -Date = "EditingEntity.PublishDate" />
< / Field >
< Field >
< FieldLabel > @L["Price"]< / FieldLabel >
< NumericEdit TValue = "float" @bind -Value = "EditingEntity.Price" />
< / Field >
< / Validations >
< / ModalBody >
< ModalFooter >
< Button Color = "Color.Secondary"
Clicked="CloseEditModalAsync">@L["Cancel"]< / Button >
< Button Color = "Color.Primary"
Type="@ButtonType.Submit"
PreventDefaultOnSubmit="true"
Clicked="UpdateEntityAsync">@L["Save"]< / Button >
< / ModalFooter >
< / Form >
< / ModalContent >
< / Modal >
````
@ -1373,17 +1376,26 @@ You can now run the application and try to edit a book.

> Tip: Try to leave the *Name* field empty and submit the form to show the validation error message.
## Deleting a Book
Open the `Books.razor` page and add the following ` DropdownItem` under the "Edit" action inside the "Actions" `DropdownMenu `:
Open the `Books.razor` page and add the following ` EntityAction` under the "Edit" action inside the `EntityActions `:
````xml
< DropdownItem Clicked = "() => DeleteEntityAsync(context)" >
@L ["Delete"]
< / DropdownItem >
< EntityAction TItem = "BookDto"
Text="@L["Delete"]"
Clicked="() => DeleteEntityAsync(context)"
ConfirmationMessage="@() => GetDeleteConfirmationMessage(context)" />
````
* `DeleteEntityAsync` is defined in the base class.
* `DeleteEntityAsync` is defined in the base class that deletes the entity by performing a call to the server.
* `ConfirmationMessage` is a callback to show a confirmation message before executing the action.
* `GetDeleteConfirmationMessage` is defined in the base class. You can override this method (or pass another value to the `ConfirmationMessage` parameter) to customize the localization message.
The "Actions" button becomes a dropdown since it has two actions now:

Run the application and try to delete a book.
@ -1394,26 +1406,22 @@ Here the complete code to create the book management CRUD page, that has been de
````xml
@page "/books"
@using Volo.Abp.Application.Dtos
@using Volo.Abp.BlazoriseUI
@using Acme.BookStore.Books
@using Acme.BookStore.Localization
@using Microsoft.Extensions.Localization
@inject IStringLocalizer< BookStoreResource > L
@inject AbpBlazorMessageLocalizerHelper< BookStoreResource > LH
@inherits AbpCrudPageBase< IBookAppService , BookDto , Guid , PagedAndSortedResultRequestDto , CreateUpdateBookDto >
< Card >
< CardHeader >
< Row >
< Column ColumnSize = "ColumnSize.Is 6 ">
< Row Class = "justify-content-between" >
< Column ColumnSize = "ColumnSize.Is Auto ">
< h2 > @L["Books"]< / h2 >
< / Column >
< Column ColumnSize = "ColumnSize.Is6" >
< Paragraph Alignment = "TextAlignment.Right" >
< Column ColumnSize = "ColumnSize.IsAuto" >
< Button Color = "Color.Primary"
Clicked="OpenCreateModalAsync">
@L ["NewBook"]
< / Button >
< / Paragraph >
Clicked="OpenCreateModalAsync">@L["NewBook"]< / Button >
< / Column >
< / Row >
< / CardHeader >
@ -1425,27 +1433,19 @@ Here the complete code to create the book management CRUD page, that has been de
ShowPager="true"
PageSize="PageSize">
< DataGridColumns >
< DataGridColumn Width = "150px"
TItem="BookDto"
Field="@nameof(BookDto.Id)"
Sortable="false"
Caption="@L["Actions"]">
< DataGridEntityActionsColumn TItem = "BookDto" @ref ="@ EntityActionsColumn " >
< DisplayTemplate >
< Dropdown >
< DropdownToggle Color = "Color.Primary" >
@L ["Actions"]
< / DropdownToggle >
< DropdownMenu >
< DropdownItem Clicked = "() => OpenEditModalAsync(context)" >
@L ["Edit"]
< / DropdownItem >
< DropdownItem Clicked = "() => DeleteEntityAsync(context)" >
@L ["Delete"]
< / DropdownItem >
< / DropdownMenu >
< / Dropdown >
< EntityActions TItem = "BookDto" EntityActionsColumn = "@EntityActionsColumn" >
< EntityAction TItem = "BookDto"
Text="@L["Edit"]"
Clicked="() => OpenEditModalAsync(context)" />
< EntityAction TItem = "BookDto"
Text="@L["Delete"]"
Clicked="() => DeleteEntityAsync(context)"
ConfirmationMessage="()=>GetDeleteConfirmationMessage(context)" />
< / EntityActions >
< / DisplayTemplate >
< / DataGrid Column>
< / DataGridEntityActionsColumn >
< DataGridColumn TItem = "BookDto"
Field="@nameof(BookDto.Name)"
Caption="@L["Name"]">< / DataGridColumn >
@ -1453,7 +1453,7 @@ Here the complete code to create the book management CRUD page, that has been de
Field="@nameof(BookDto.Type)"
Caption="@L["Type"]">
< DisplayTemplate >
@L [$"Enum:BookType:{(int)context.Type}"]
@L [$"Enum:BookType:{(int) context.Type}"]
< / DisplayTemplate >
< / DataGridColumn >
< DataGridColumn TItem = "BookDto"
@ -1479,85 +1479,109 @@ Here the complete code to create the book management CRUD page, that has been de
< / CardBody >
< / Card >
< Modal @ref =" CreateModal " >
< Modal @ref =" @ CreateModal " >
< ModalBackdrop / >
< ModalContent IsCentered = "true" >
< ModalHeader >
< ModalTitle > @L["NewBook"]< / ModalTitle >
< CloseButton Clicked = "CloseCreateModalAsync" / >
< / ModalHeader >
< ModalBody >
< Field >
< FieldLabel > @L["Name"]< / FieldLabel >
< TextEdit @bind -text = "NewEntity.Name" />
< / Field >
< Field >
< FieldLabel > @L["Type"]< / FieldLabel >
< Select TValue = "BookType" @bind -SelectedValue = "@NewEntity.Type" >
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
< SelectItem TValue = "BookType" Value = "@((BookType)bookTypeValue)" >
@L [$"Enum:BookType:{bookTypeValue}"]
< / SelectItem >
}
< / Select >
< / Field >
< Field >
< FieldLabel > @L["PublishDate"]< / FieldLabel >
< DateEdit TValue = "DateTime" @bind -Date = "NewEntity.PublishDate" />
< / Field >
< Field >
< FieldLabel > @L["Price"]< / FieldLabel >
< NumericEdit TValue = "float" @bind -Value = "NewEntity.Price" />
< / Field >
< / ModalBody >
< ModalFooter >
< Button Color = "Color.Secondary"
Clicked="CloseCreateModalAsync">@L["Cancel"]< / Button >
< Button Color = "Color.Primary"
Clicked="CreateEntityAsync">@L["Save"]< / Button >
< / ModalFooter >
< Form >
< ModalHeader >
< ModalTitle > @L["NewBook"]< / ModalTitle >
< CloseButton Clicked = "CloseCreateModalAsync" / >
< / ModalHeader >
< ModalBody >
< Validations @ref ="@ CreateValidationsRef " Model = "@NewEntity" ValidateOnLoad = "false" >
< Validation MessageLocalizer = "@LH.Localize" >
< Field >
< FieldLabel > @L["Name"]< / FieldLabel >
< TextEdit @bind -Text = "@NewEntity.Name" >
< Feedback >
< ValidationError / >
< / Feedback >
< / TextEdit >
< / Field >
< / Validation >
< Field >
< FieldLabel > @L["Type"]< / FieldLabel >
< Select TValue = "BookType" @bind -SelectedValue = "@NewEntity.Type" >
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
< SelectItem TValue = "BookType" Value = "@((BookType) bookTypeValue)" >
@L [$"Enum:BookType:{bookTypeValue}"]
< / SelectItem >
}
< / Select >
< / Field >
< Field >
< FieldLabel > @L["PublishDate"]< / FieldLabel >
< DateEdit TValue = "DateTime" @bind -Date = "NewEntity.PublishDate" />
< / Field >
< Field >
< FieldLabel > @L["Price"]< / FieldLabel >
< NumericEdit TValue = "float" @bind -Value = "NewEntity.Price" />
< / Field >
< / Validations >
< / ModalBody >
< ModalFooter >
< Button Color = "Color.Secondary"
Clicked="CloseCreateModalAsync">@L["Cancel"]< / Button >
< Button Color = "Color.Primary"
Type="@ButtonType.Submit"
PreventDefaultOnSubmit="true"
Clicked="CreateEntityAsync">@L["Save"]< / Button >
< / ModalFooter >
< / Form >
< / ModalContent >
< / Modal >
< Modal @ref =" EditModal " >
< Modal @ref =" @ EditModal " >
< ModalBackdrop / >
< ModalContent IsCentered = "true" >
< ModalHeader >
< ModalTitle > @EditingEntity.Name< / ModalTitle >
< CloseButton Clicked = "CloseEditModalAsync" / >
< / ModalHeader >
< ModalBody >
< Field >
< FieldLabel > @L["Name"]< / FieldLabel >
< TextEdit @bind -text = "EditingEntity.Name" />
< / Field >
< Field >
< FieldLabel > @L["Type"]< / FieldLabel >
< Select TValue = "BookType" @bind -SelectedValue = "@EditingEntity.Type" >
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
< SelectItem TValue = "BookType" Value = "@((BookType)bookTypeValue)" >
@L [$"Enum:BookType:{bookTypeValue}"]
< / SelectItem >
}
< / Select >
< / Field >
< Field >
< FieldLabel > @L["PublishDate"]< / FieldLabel >
< DateEdit TValue = "DateTime" @bind -Date = "EditingEntity.PublishDate" />
< / Field >
< Field >
< FieldLabel > @L["Price"]< / FieldLabel >
< NumericEdit TValue = "float" @bind -Value = "EditingEntity.Price" />
< / Field >
< / ModalBody >
< ModalFooter >
< Button Color = "Color.Secondary"
Clicked="CloseEditModalAsync">@L["Cancel"]< / Button >
< Button Color = "Color.Primary"
Clicked="UpdateEntityAsync">@L["Save"]< / Button >
< / ModalFooter >
< Form >
< ModalHeader >
< ModalTitle > @EditingEntity.Name< / ModalTitle >
< CloseButton Clicked = "CloseEditModalAsync" / >
< / ModalHeader >
< ModalBody >
< Validations @ref ="@ EditValidationsRef " Model = "@NewEntity" ValidateOnLoad = "false" >
< Validation MessageLocalizer = "@LH.Localize" >
< Field >
< FieldLabel > @L["Name"]< / FieldLabel >
< TextEdit @bind -Text = "@EditingEntity.Name" >
< Feedback >
< ValidationError / >
< / Feedback >
< / TextEdit >
< / Field >
< / Validation >
< Field >
< FieldLabel > @L["Type"]< / FieldLabel >
< Select TValue = "BookType" @bind -SelectedValue = "@EditingEntity.Type" >
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
< SelectItem TValue = "BookType" Value = "@((BookType) bookTypeValue)" >
@L [$"Enum:BookType:{bookTypeValue}"]
< / SelectItem >
}
< / Select >
< / Field >
< Field >
< FieldLabel > @L["PublishDate"]< / FieldLabel >
< DateEdit TValue = "DateTime" @bind -Date = "EditingEntity.PublishDate" />
< / Field >
< Field >
< FieldLabel > @L["Price"]< / FieldLabel >
< NumericEdit TValue = "float" @bind -Value = "EditingEntity.Price" />
< / Field >
< / Validations >
< / ModalBody >
< ModalFooter >
< Button Color = "Color.Secondary"
Clicked="CloseEditModalAsync">@L["Cancel"]< / Button >
< Button Color = "Color.Primary"
Type="@ButtonType.Submit"
PreventDefaultOnSubmit="true"
Clicked="UpdateEntityAsync">@L["Save"]< / Button >
< / ModalFooter >
< / Form >
< / ModalContent >
< / Modal >
````