Browse Source

Update Part-3.md

applied the usual changes and fixed a few msitakes.
pull/11207/head
Hamza Albreem 5 years ago
parent
commit
cc032b7787
  1. 86
      docs/en/Tutorials/Part-3.md

86
docs/en/Tutorials/Part-3.md

@ -13,7 +13,7 @@ In this tutorial series, you will build an ABP based web application named `Acme
* **{{DB_Value}}** as the ORM provider.
* **{{UI_Value}}** as the UI Framework.
This tutorial is organized as the following parts;
This tutorial is organized as the following parts:
- [Part 1: Creating the server side](Part-1.md)
- [Part 2: The book list page](Part-2.md)
@ -51,19 +51,19 @@ This part is also recorded as a video tutorial and **<a href="https://www.youtub
## Creating a New Book
In this section, you will learn how to create a new modal dialog form to create a new book. The modal dialog will look like in the image below:
In this section, you will learn how to create a new modal dialog form to create a new book. The modal dialog will look like the image below:
![bookstore-create-dialog](images/bookstore-create-dialog-2.png)
### Create the Modal Form
Create a new razor page, named `CreateModal.cshtml` under the `Pages/Books` folder of the `Acme.BookStore.Web` project.
Create a new razor page named `CreateModal.cshtml` under the `Pages/Books` folder of the `Acme.BookStore.Web` project.
![bookstore-add-create-dialog](images/bookstore-add-create-dialog-v2.png)
#### CreateModal.cshtml.cs
Open the `CreateModal.cshtml.cs` file (`CreateModalModel` class) and replace with the following code:
Open the `CreateModal.cshtml.cs` file (`CreateModalModel` class) and replace it with the following code:
````C#
using System.Threading.Tasks;
@ -98,7 +98,7 @@ namespace Acme.BookStore.Web.Pages.Books
}
````
* This class is derived from the `BookStorePageModel` instead of standard `PageModel`. `BookStorePageModel` indirectly inherits the `PageModel` and adds some common properties & methods that can be shared in your page model classes.
* This class is derived from the `BookStorePageModel` instead of the standard `PageModel`. `BookStorePageModel` indirectly inherits the `PageModel` and adds some common properties & methods that can be shared in your page model classes.
* `[BindProperty]` attribute on the `Book` property binds post request data to this property.
* This class simply injects the `IBookAppService` in the constructor and calls the `CreateAsync` method in the `OnPostAsync` handler.
* It creates a new `CreateUpdateBookDto` object in the `OnGet` method. ASP.NET Core can work without creating a new instance like that. However, it doesn't create an instance for you and if your class has some default value assignments or code execution in the class constructor, they won't work. For this case, we set default values for some of the `CreateUpdateBookDto` properties.
@ -129,7 +129,7 @@ Open the `CreateModal.cshtml` file and paste the code below:
</abp-dynamic-form>
````
* This modal uses `abp-dynamic-form` [tag helper](../UI/AspNetCore/Tag-Helpers/Dynamic-Forms.md) to automatically create the form from the `CreateBookViewModel` model class.
* This modal uses `abp-dynamic-form` [tag helper](../UI/AspNetCore/Tag-Helpers/Dynamic-Forms.md) to automatically create the form from the `CreateBookViewModel` model class.
* `abp-model` attribute indicates the model object where it's the `Book` property in this case.
* `abp-form-content` tag helper is a placeholder to render the form controls (it is optional and needed only if you have added some other content in the `abp-dynamic-form` tag, just like in this page).
@ -155,7 +155,7 @@ Open the `Pages/Books/Index.cshtml` and set the content of `abp-card-header` tag
</abp-card-header>
````
The final content of the `Index.cshtml` is shown below:
The final content of `Index.cshtml` is shown below:
````html
@page
@ -193,7 +193,7 @@ This adds a new button called **New book** to the **top-right** of the table:
![bookstore-new-book-button](images/bookstore-new-book-button-2.png)
Open the `Pages/Books/Index.js` and add the following code just after the `Datatable` configuration:
Open the `Pages/Books/Index.js` file and add the following code right after the `Datatable` configuration:
````js
var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal');
@ -208,11 +208,11 @@ $('#NewBookButton').click(function (e) {
});
````
* `abp.ModalManager` is a helper class to manage modals in the client side. It internally uses Twitter Bootstrap's standard modal, but abstracts many details by providing a simple API.
* `abp.ModalManager` is a helper class to manage modals on the client side. It internally uses Twitter Bootstrap's standard modal, but abstracts many details by providing a simple API.
* `createModal.onResult(...)` used to refresh the data table after creating a new book.
* `createModal.open();` is used to open the model to create a new book.
The final content of the `Index.js` should be like that:
The final content of the `Index.js` file should be like this:
````js
$(function () {
@ -290,7 +290,7 @@ Create a new razor page, named `EditModal.cshtml` under the `Pages/Books` folder
### EditModal.cshtml.cs
Open the `EditModal.cshtml.cs` file (`EditModalModel` class) and replace with the following code:
Open the `EditModal.cshtml.cs` file (`EditModalModel` class) and replace it with the following code:
````csharp
using System;
@ -331,13 +331,13 @@ namespace Acme.BookStore.Web.Pages.Books
}
````
* `[HiddenInput]` and `[BindProperty]` are standard ASP.NET Core MVC attributes. `SupportsGet` is used to be able to get `Id` value from query string parameter of the request.
* In the `OnGetAsync` method, we get `BookDto ` from the `BookAppService` and this is being mapped to the DTO object `CreateUpdateBookDto`.
* `[HiddenInput]` and `[BindProperty]` are standard ASP.NET Core MVC attributes. `SupportsGet` is used to be able to get the `Id` value from the query string parameter of the request.
* In the `OnGetAsync` method, we get the `BookDto` from the `BookAppService` and this is being mapped to the DTO object `CreateUpdateBookDto`.
* The `OnPostAsync` uses `BookAppService.UpdateAsync(...)` to update the entity.
### Mapping from BookDto to CreateUpdateBookDto
To be able to map the `BookDto` to `CreateUpdateBookDto`, configure a new mapping. To do this, open the `BookStoreWebAutoMapperProfile.cs` in the `Acme.BookStore.Web` project and change it as shown below:
To be able to map the `BookDto` to `CreateUpdateBookDto`, configure a new mapping. To do this, open the `BookStoreWebAutoMapperProfile.cs` file in the `Acme.BookStore.Web` project and change it as shown below:
````csharp
using AutoMapper;
@ -385,16 +385,16 @@ Replace `EditModal.cshtml` content with the following content:
</abp-dynamic-form>
````
This page is very similar to the `CreateModal.cshtml`, except:
This page is very similar to `CreateModal.cshtml`, except:
* It includes an `abp-input` for the `Id` property to store `Id` of the editing book (which is a hidden input).
* It includes an `abp-input` for the `Id` property to store the `Id` of the editing book (which is a hidden input).
* It uses `Books/EditModal` as the post URL.
### Add "Actions" Dropdown to the Table
We will add a dropdown button to the table named *Actions*.
Open the `Pages/Books/Index.js` and replace the content as below:
Open the `Pages/Books/Index.js` file and replace the content as below:
````js
$(function () {
@ -482,8 +482,8 @@ $(function () {
* Added a new `ModalManager` named `editModal` to open the edit modal dialog.
* Added a new column at the beginning of the `columnDefs` section. This column is used for the "*Actions*" dropdown button.
* "*Edit*" action simply calls `editModal.open()` to open the edit dialog.
* `editModal.onResult(...)` callback refreshes the data table when you close the edit modal.
* The "*Edit*" action simply calls `editModal.open()` to open the edit dialog.
* The `editModal.onResult(...)` callback refreshes the data table when you close the edit modal.
You can run the application and edit any book by selecting the edit action on a book.
@ -493,7 +493,7 @@ The final UI looks as below:
## Deleting a Book
Open the `Pages/Books/Index.js` and add a new item to the `rowAction` `items`:
Open the `Pages/Books/Index.js` file and add a new item to the `rowAction` `items`:
````js
{
@ -512,8 +512,8 @@ Open the `Pages/Books/Index.js` and add a new item to the `rowAction` `items`:
}
````
* `confirmMessage` option is used to ask a confirmation question before executing the `action`.
* `acme.bookStore.books.book.delete(...)` method makes an AJAX request to the server to delete a book.
* The `confirmMessage` option is used to ask a confirmation question before executing the `action`.
* The `acme.bookStore.books.book.delete(...)` method makes an AJAX request to the server to delete a book.
* `abp.notify.info()` shows a notification after the delete operation.
Since we've used two new localization texts (`BookDeletionConfirmationMessage` and `SuccessfullyDeleted`) you need to add these to the localization file (`en.json` under the `Localization/BookStore` folder of the `Acme.BookStore.Domain.Shared` project):
@ -721,10 +721,10 @@ Open `/src/app/book/book.component.html` and make the following changes:
</abp-modal>
```
* Added `New book` button to the card header..
* Added a `New book` button to the card header..
* Added the `abp-modal` which renders a modal to allow user to create a new book. `abp-modal` is a pre-built component to show modals. While you could use another approach to show a modal, `abp-modal` provides additional benefits.
You can open your browser and click **New book** button to see the new modal.
You can open your browser and click the **New book** button to see the new modal.
![Empty modal for new book](images/bookstore-empty-new-book-modal.png)
@ -801,11 +801,11 @@ export class BookComponent implements OnInit {
```
* Imported `FormGroup`, `FormBuilder` and `Validators` from `@angular/forms`.
* Added `form: FormGroup` property.
* Added `bookTypes` property as a list of `BookType` enum members. That will be used in form options.
* Added a `form: FormGroup` property.
* Added a `bookTypes` property as a list of `BookType` enum members. That will be used in form options.
* Injected `FormBuilder` into the constructor. [FormBuilder](https://angular.io/api/forms/FormBuilder) provides convenient methods for generating form controls. It reduces the amount of boilerplate needed to build complex forms.
* Added `buildForm` method to the end of the file and executed the `buildForm()` in the `createBook` method.
* Added `save` method.
* Added a `buildForm` method to the end of the file and executed the `buildForm()` in the `createBook` method.
* Added a `save` method.
Open `/src/app/book/book.component.html` and replace `<ng-template #abpBody> </ng-template>` with the following code part:
@ -863,7 +863,7 @@ Also replace `<ng-template #abpFooter> </ng-template>` with the following code p
### Datepicker
We've used [NgBootstrap datepicker](https://ng-bootstrap.github.io/#/components/datepicker/overview) in this component. So, need to arrange dependencies related to this component.
We've used [NgBootstrap datepicker](https://ng-bootstrap.github.io/#/components/datepicker/overview) in this component. So, we need to arrange the dependencies related to this component.
Open `/src/app/book/book.module.ts` and replace the content as below:
@ -959,7 +959,7 @@ export class BookComponent implements OnInit {
```
* Imported ` NgbDateNativeAdapter` and `NgbDateAdapter`.
* We added a new provider `NgbDateAdapter` that converts Datepicker value to `Date` type. See the [datepicker adapters](https://ng-bootstrap.github.io/#/components/datepicker/overview) for more details.
* We added a new provider `NgbDateAdapter` that converts the Datepicker value to `Date` type. Check out the [datepicker adapters](https://ng-bootstrap.github.io/#/components/datepicker/overview) for more details.
Now, you can open your browser to see the changes:
@ -1054,14 +1054,14 @@ export class BookComponent implements OnInit {
```
* We declared a variable named `selectedBook` as `BookDto`.
* We added `editBook` method. This method fetches the book with the given `id` and sets it to `selectedBook` object.
* We added an `editBook` method. This method fetches the book with the given `id` and sets it to `selectedBook` object.
* We replaced the `buildForm` method so that it creates the form with the `selectedBook` data.
* We replaced the `createBook` method so it sets `selectedBook` to an empty object.
* We changed the `save` method to handle both of create and update operations.
### Add "Actions" Dropdown to the Table
Open the `/src/app/book/book.component.html`  and add the following `ngx-datatable-column` definition as the first column in the `ngx-datatable`:
Open `/src/app/book/book.component.html`  and add the following `ngx-datatable-column` definition as the first column in the `ngx-datatable`:
```html
<ngx-datatable-column
@ -1101,11 +1101,11 @@ Also, change the `ng-template #abpHeader` section as shown below:
</ng-template>
```
This template will show **Edit** text for edit record operation, **New Book** for new record operation in the title.
This template will show the **Edit** text for edit record operation, **New Book** for new record operation in the title.
## Deleting a Book
Open the `/src/app/book/book.component.ts` and inject the `ConfirmationService`.
Open the `/src/app/book/book.component.ts` file and inject the `ConfirmationService`.
Replace the constructor as below:
@ -1137,7 +1137,7 @@ delete(id: string) {
* We injected `ConfirmationService` to the constructor.
* Added a `delete` method.
> See the [Confirmation Popup documentation](../UI/Angular/Confirmation-Service) for more about this service.
> Check out the [Confirmation Popup documentation](../UI/Angular/Confirmation-Service) for more about this service.
### Add a Delete Button
@ -1169,7 +1169,7 @@ Clicking the "Delete" action calls the `delete` method which then shows a confir
In this section, you will learn how to create a new modal dialog form to create a new book. Since we've inherited from the `AbpCrudPageBase`, we only need to develop the view part.
### Add "New Button" Button
### Add a "New Button" Button
Open the `Books.razor` and replace the `<CardHeader>` section with the following code:
@ -1191,7 +1191,7 @@ This will change the card header by adding a "New book" button to the right side
![blazor-add-book-button](images/blazor-add-book-button.png)
Now, we can add a modal that will be opened when we click to the button.
Now, we can add a modal that will be opened when we click the button.
### Book Creation Modal
@ -1259,7 +1259,7 @@ This code requires a service; Inject the `AbpBlazorMessageLocalizerHelper<T>` at
````
* The form implements validation and the `AbpBlazorMessageLocalizerHelper` is used to simply localize the validation messages.
* `CreateModal` object, `CloseCreateModalAsync` and `CreateEntityAsync` method are defined by the base class. See the [Blazorise documentation](https://blazorise.com/docs/) if you want to understand the `Modal` and the other components.
* The `CreateModal` object, `CloseCreateModalAsync` and `CreateEntityAsync` methods are defined by the base class. Check out the [Blazorise documentation](https://blazorise.com/docs/) if you want to understand the `Modal` and the other components.
That's all. Run the application and try to add a new book:
@ -1267,7 +1267,7 @@ That's all. Run the application and try to add a new book:
## Updating a Book
Editing a books is similar to the creating a new book.
Editing a book is similar to creating a new book.
### Actions Dropdown
@ -1287,7 +1287,7 @@ Open the `Books.razor` and add the following `DataGridEntityActionsColumn` secti
* `OpenEditModalAsync` is defined in the base class which takes the entity (book) to edit.
`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:
The `DataGridEntityActionsColumn` component is used to show an "Actions" dropdown for each row in the `DataGrid`. The `DataGridEntityActionsColumn` shows a **single button** instead of a dropdown if there is only one available action inside it:
![blazor-edit-book-action](images/blazor-edit-book-action-2.png)
@ -1384,7 +1384,7 @@ You can now run the application and try to edit a book.
## Deleting a Book
Open the `Books.razor` page and add the following `EntityAction` under the "Edit" action inside the `EntityActions`:
Open the `Books.razor` page and add the following `EntityAction` code under the "Edit" action inside `EntityActions`:
````xml
<EntityAction TItem="BookDto"
@ -1405,7 +1405,7 @@ Run the application and try to delete a book.
## Full CRUD UI Code
Here the complete code to create the book management CRUD page, that has been developed in the last two parts:
Here's the complete code to create the book management CRUD page, that has been developed in the last two parts:
````xml
@page "/books"
@ -1596,4 +1596,4 @@ Here the complete code to create the book management CRUD page, that has been de
## The Next Part
See the [next part](Part-4.md) of this tutorial.
Check out the [next part](Part-4.md) of this tutorial.

Loading…
Cancel
Save