diff --git a/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/POST.md b/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/POST.md new file mode 100644 index 0000000000..4904da48cf --- /dev/null +++ b/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/POST.md @@ -0,0 +1,372 @@ +# Convert Create/Edit Modals to Page +In this document we will explain how to convert BookStore's Books create & edit modals to regular blazor pages. + +## Before +![bookstore-crud-before](images/old.gif) + +## After + +![bookstore-crud-after](images/new.gif) + + +# Books.razor Page +Books.razor page is the main page of the books management. Create & Update operations are done in this page. So we'll remove create & update operations from this page and move a separate blazor component for each operation. Each component will be a page. + +- Remove both Create & Update modals. + + ![remove-all-modals](images/books-remove-modals.png) + +- Replace **NewBook** button with a link to **CreateBook** page. + + ```html + + ``` + +- Inject `NavigationManager` to `Books.razor` page. + ```csharp + @inject NavigationManager NavigationManager + ``` + +- Replace **Edit** button with a link to **UpdateBook** page. + + ```html + + ``` + + ```csharp + private void NavigateToEdit(Guid id) + { + NavigationManager.NavigateTo($"books/{id}/edit"); + } + ``` + +- Remove all methods in the `Books.razor` page except constructor. And add `GoToEditPage` as below: + + ```csharp + protected void GoToEditPage(BookDto book) + { + NavigationManager.NavigateTo($"books/{book.Id}"); + } + ``` + + ![bookstore-remove-methods](images/books-remove-methods.png) + +- Change Edit button to a link in the table. + + ```html + + ``` + + +# CreateBooks Page +Create new `CreateBook.razor` and `CreateBook.razor.cs` files in your project. + +- `CreateBook.razor` + +```html +@page "/books/new" +@attribute [Authorize(BookStorePermissions.Books.Create)] +@inherits BookStoreComponentBase + +@using Acme.BookStore.Books; +@using Acme.BookStore.Localization; +@using Acme.BookStore.Permissions; +@using Microsoft.Extensions.Localization; +@using Volo.Abp.AspNetCore.Components.Web; + +@inject IStringLocalizer L +@inject AbpBlazorMessageLocalizerHelper LH +@inject IBookAppService AppService +@inject NavigationManager NavigationManager + + + + + @L["NewBook"] + + + + + + + @L["Author"] + + + + @L["Name"] + + + + + + + + + @L["Type"] + + + + @L["PublishDate"] + + + + @L["Price"] + + + + + + + + + +``` + +- `CreateBook.razor.cs` + +```csharp +using Acme.BookStore.Books; +using Blazorise; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp; + +namespace Acme.BookStore.Blazor.Pages; + +public partial class CreateBook +{ + protected Validations CreateValidationsRef; + protected CreateUpdateBookDto NewEntity = new(); + IReadOnlyList authorList = Array.Empty(); + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + authorList = (await AppService.GetAuthorLookupAsync()).Items; + + if (!authorList.Any()) + { + throw new UserFriendlyException(message: L["AnAuthorIsRequiredForCreatingBook"]); + } + + NewEntity.AuthorId = authorList.First().Id; + + if (CreateValidationsRef != null) + { + await CreateValidationsRef.ClearAll(); + } + } + + protected virtual async Task CreateEntityAsync() + { + try + { + var validate = true; + if (CreateValidationsRef != null) + { + validate = await CreateValidationsRef.ValidateAll(); + } + if (validate) + { + await AppService.CreateAsync(NewEntity); + NavigationManager.NavigateTo("books"); + } + } + catch (Exception ex) + { + await HandleErrorAsync(ex); + } + } +} +``` + +# EditBooks Page +Create new `EditBook.razor` and `EditBook.razor.cs` files in your project. + +- `EditBook.razor` + +```html +@page "/books/{Id}" +@attribute [Authorize(BookStorePermissions.Books.Edit)] +@inherits BookStoreComponentBase +@using Acme.BookStore.Books; +@using Acme.BookStore.Localization; +@using Acme.BookStore.Permissions; +@using Microsoft.Extensions.Localization; +@using Volo.Abp.AspNetCore.Components.Web; + +@inject IStringLocalizer L +@inject AbpBlazorMessageLocalizerHelper LH +@inject IBookAppService AppService +@inject NavigationManager NavigationManager + + + + + @EditingEntity.Name + + + + + + + @L["Author"] + + + + @L["Name"] + + + + + + + + + @L["Type"] + + + + @L["PublishDate"] + + + + @L["Price"] + + + + + + + + + +``` + +- `EditBook.razor.cs` + +```csharp +using Acme.BookStore.Books; +using Blazorise; +using Microsoft.AspNetCore.Components; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp; + +namespace Acme.BookStore.Blazor.Pages; + +public partial class EditBook +{ + protected CreateUpdateBookDto EditingEntity = new(); + protected Validations EditValidationsRef; + IReadOnlyList authorList = Array.Empty(); + + [Parameter] + public string Id { get; set; } + + public Guid EditingEntityId { get; set; } + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + // Blazor can't parse Guid as route constraint currently. + // See https://github.com/dotnet/aspnetcore/issues/19008 + EditingEntityId = Guid.Parse(Id); + + authorList = (await AppService.GetAuthorLookupAsync()).Items; + + if (!authorList.Any()) + { + throw new UserFriendlyException(message: L["AnAuthorIsRequiredForCreatingBook"]); + } + + var entityDto = await AppService.GetAsync(EditingEntityId); + + EditingEntity = ObjectMapper.Map(entityDto); + + if (EditValidationsRef != null) + { + await EditValidationsRef.ClearAll(); + } + } + + protected virtual async Task UpdateEntityAsync() + { + try + { + var validate = true; + if (EditValidationsRef != null) + { + validate = await EditValidationsRef.ValidateAll(); + } + if (validate) + { + await AppService.UpdateAsync(EditingEntityId, EditingEntity); + + NavigationManager.NavigateTo("books"); + } + } + catch (Exception ex) + { + await HandleErrorAsync(ex); + } + } +} +``` + +You can check the following commit for details: +https://github.com/abpframework/abp-samples/commit/aae61ad6d66ebf6191dd4dcfb4e23d30bd680a4e \ No newline at end of file diff --git a/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/books-remove-methods.png b/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/books-remove-methods.png new file mode 100644 index 0000000000..a2df67fee2 Binary files /dev/null and b/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/books-remove-methods.png differ diff --git a/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/books-remove-modals.png b/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/books-remove-modals.png new file mode 100644 index 0000000000..0e9fd6e8d4 Binary files /dev/null and b/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/books-remove-modals.png differ diff --git a/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/new.gif b/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/new.gif new file mode 100644 index 0000000000..42784eb281 Binary files /dev/null and b/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/new.gif differ diff --git a/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/old.gif b/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/old.gif new file mode 100644 index 0000000000..80a97a80f2 Binary files /dev/null and b/docs/en/Community-Articles/2023-03-28-Converting-Create-Edit-Modal-To-Page/images/old.gif differ