diff --git a/docs/en/UI/Angular/Modal.md b/docs/en/UI/Angular/Modal.md new file mode 100644 index 0000000000..c1c9d21633 --- /dev/null +++ b/docs/en/UI/Angular/Modal.md @@ -0,0 +1,248 @@ +# Modal + +`ModalComponent` is a pre-built component exposed by `@abp/ng.theme.shared` package to show modals. The component uses the [`ng-bootstrap`](https://ng-bootstrap.github.io/)'s modal service inside to render a modal. + +The `abp-modal` provides some additional benefits: + + - It is **flexible**. You can pass header, body, footer templates easily by adding the templates to the `abp-modal` content. It can also be implemented quickly. + - Provides several inputs be able to customize the modal and several outputs be able to listen some events. + - Automatically detects the close button which have a `#abpClose` variable declaration and close the modal when pressed this button. + - Automatically detects the `abp-button` and trigger its loading spinner when the `busy` input value of the modal component is true. + - Automatically checks if the form inside the modal **has changed, but not saved**. It warns the user in this case when user tries to close the modal or refresh/close the tab of the browser. + + +> Note: A modal can also be rendered by using the `ng-bootstrap` modal. For further information, see [Modal doc](https://ng-bootstrap.github.io/#/components/modal) on the `ng-bootstrap` documentation. + +## Getting Started + +In order to use the `abp-modal` in an HTML template, the **`ThemeSharedModule`** should be imported into your module like this: + +```js +// ... +import { ThemeSharedModule } from '@abp/ng.theme.shared'; + +@NgModule({ + //... + imports: [..., ThemeSharedModule], +}) +export class MyFeatureModule {} +``` + +## Usage + +You can add the `abp-modal` to your component very quickly. See an example: + +```html + + + + + + +

Modal Title

+
+ + +

Modal content

+
+ + + + +
+``` + +```js +// sample.component.ts + +@Component(/* component metadata */) +export class SampleComponent { + isModelOpen = false +} +``` + +![Example modal result](./images/modal-result-1.jpg) + + +See an example form inside a modal: + +```html + + + + +

Book

+
+ + +
+
+ * + +
+ +
+ * + +
+ +
+ * + +
+ +
+ * + +
+ +
+ * + +
+
+
+ + + + + + +
+``` + +```ts +// book.component.ts + +import { Component } from '@angular/core'; +import { FormBuilder, Validators } from '@angular/forms'; + +@Component(/* component metadata */) +export class BookComponent { + form = this.fb.group({ + author: [null, [Validators.required]], + name: [null, [Validators.required]], + price: [null, [Validators.required, Validators.min(0)]], + type: [null, [Validators.required]], + publishDate: [null, [Validators.required]], + }); + + inProgress: boolean; + + isModalOpen: boolean; + + constructor(private fb: FormBuilder, private service: BookService) {} + + save() { + if (this.form.invalid) return; + + this.inProgress = true; + + this.service.save(this.form.value).subscribe(() => { + this.inProgress = false; + }); + } +} +``` + +The modal with form looks like this: + +![Form example result](./images/modal-result-2.jpg) + +## API + +### Inputs + +#### visible + +```js +@Input() visible: boolean +``` + +**`visible`** is a boolean input that determines whether the modal is open. It is also can be used two way binding. + +#### busy + +```js +@Input() busy: boolean +``` + +**`busy`** is a boolean input that determines whether the modal busy status is true. When `busy` is true, the modal cannot be closed and the `abp-button` loading spinner is triggered. + + +#### options + +```js +@Input() options: NgbModalOptions +``` + +**`options`** is an input typed [NgbModalOptions](https://ng-bootstrap.github.io/#/components/modal/api#NgbModalOptions). It is configuration for the `ng-bootstrap` modal. + +#### suppressUnsavedChangesWarning + +```js +@Input() suppressUnsavedChangesWarning: boolean +``` + +**`suppressUnsavedChangesWarning`** is a boolean input that determines whether the confirmation popup triggering active or not. It can also be set globally as shown below: + +```ts +//app.module.ts + +// app.module.ts + +import { SUPPRESS_UNSAVED_CHANGES_WARNING } from '@abp/ng.theme.shared'; + +// ... + +@NgModule({ + // ... + providers: [{provide: SUPPRESS_UNSAVED_CHANGES_WARNING, useValue: true}] +}) +export class AppModule {} +``` + +Note: The `suppressUnsavedChangesWarning` input of `abp-modal` value overrides the `SUPPRESS_UNSAVED_CHANGES_WARNING` injection token value. + +### Outputs + +#### visibleChange + +```js +@Output() readonly visibleChange = new EventEmitter(); +``` + +**`visibleChange`** is an event emitted when the modal visibility has changed. The event payload is a boolean. + +#### appear + +```js + @Output() readonly appear = new EventEmitter(); +``` + +**`appear`** is an event emitted when the modal has opened. + +#### disappear + +```js + @Output() readonly disappear = new EventEmitter(); +``` + +**`disappear`** is an event emitted when the modal has closed. diff --git a/docs/en/UI/Angular/images/modal-result-1.jpg b/docs/en/UI/Angular/images/modal-result-1.jpg new file mode 100644 index 0000000000..89dbbc0cb1 Binary files /dev/null and b/docs/en/UI/Angular/images/modal-result-1.jpg differ diff --git a/docs/en/UI/Angular/images/modal-result-2.jpg b/docs/en/UI/Angular/images/modal-result-2.jpg new file mode 100644 index 0000000000..e17f2631ab Binary files /dev/null and b/docs/en/UI/Angular/images/modal-result-2.jpg differ diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 3337521b89..f855338d13 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -819,6 +819,10 @@ "text": "Projecting Angular Content", "path": "UI/Angular/Content-Projection-Service.md" }, + { + "text": "Modal", + "path": "UI/Angular/Modal.md" + }, { "text": "Confirmation Popup", "path": "UI/Angular/Confirmation-Service.md"