I'm trying to create a common ngx-bootstrap modal component in Angular.
I've searched the internet and tried this way.
import { Component } from '@angular/core';
import { BsModalService } from 'ngx-bootstrap/modal';
import { BsModalRef } from 'ngx-bootstrap/modal/modal-options.class';
/* This is the Component from which we open the Modal Component */
@Component({
selector: 'my-component',
templateUrl: './service-component.html'
})
export class MyComponent {
bsModalRef: BsModalRef;
constructor(private modalService: BsModalService) {}
public openModalWithComponent() {
/* this is how we open a Modal Component from another component */
this.bsModalRef = this.modalService.show(ModalContentComponent);
}
}
/* This is the Modal Component */
@Component({
selector: 'child-modal',
template: `
<div class="modal-header">
<h4 class="modal-title pull-left">Title</h4>
<button type="button" class="close pull-right" aria-label="Close" (click)="bsModalRef.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" (click)="bsModalRef.hide()">Close</button>
</div>
`
})
export class ChildModalComponent {
constructor(public bsModalRef: BsModalRef) {}
}
<button type="button" class="btn btn-primary" (click)="openModalWithComponent()">Create modal with component</button>
<child-modal #childModal ></child-modal>
But it says 'Cannot find name 'ModalContentComponent'.
And I really don't understand where they get that from, although it seems to work for other people.
Finally I followed this other tutorial which worked for me.
The following example is used to add items to an array:
Create a simple component ItemList to display a list of items added to an Array.
ng g c itemList
item-list.component.html
<div>
<h1> Item List </h1>
<ul>
<li *ngFor=”let item of itemList”>{{item}}</li>
</ul>
<button type=”button” class=”btn btn-primary”>Add New Item</button>
</div>
item-list.component.ts
export class ItemListComponent implements OnInit {
itemList = ["Book","Pen"]
constructor() { }
ngOnInit() {
}
}
Let’s create another component to use as the modal.
ng g c itemAdd
The second component to add a new item, which will use as a modal in the future. Also, I have written a simple function called saveToList() which will also implement in the future. For now, I have put a simple console log, just to display the value in the input field.
numberOfItems will be the count of items in the existing array.
item-add.component.html
<div class="modal-body">
<h4>Add Item</h4>
<form [formGroup]="itemform" (ngSubmit)="saveToList(itemform)">
<div class="col-md-6">
<label>Number of Items : </label> {{numberOfItems}}
</div>
<div class="col-md-6">
<label>Item Name</label>
</div>
<div class="col-md-6">
<input type="text" class="form-control" formControlName="name">
<button class="button mt-1" type="submit">Save</button>
</div>
</form>
<div>
item-add.component.ts
export class ItemAddComponent implements OnInit {
itemform;
numberOfItems = 0;
constructor(private formBuilder: FormBuilder) {
this.itemform = this.formBuilder.group({
name: ""
})
}
ngOnInit() {
}
saveToList(form) {
console.log(form.value);
}
}
Add a modal.
Let's change the code to open add item form as a modal when clicking the Add New Item button.
item-list.component.ts
export class ItemListComponent implements OnInit {
itemList = ["Book","Pen"];
bsModalRef: BsModalRef;
constructor(private modalService: BsModalService) { }
ngOnInit() {
}
openModalWithComponent() {
this.bsModalRef = this.modalService.show(ItemAddComponent);
this.bsModalRef.content.closeBtnName = 'Close';
}
}
Don't forget to add ItemAddComponent into entryComponents list in app.module.ts
providers: [],
entryComponents: [ItemAddComponent],
Pass values from parent to modal.
We can simply use initialState to pass an initial value into the modal .
item-list.component.ts
openModalWithComponent() {
const initialState = {
list: [
"test"
]
};
this.bsModalRef = this.modalService.show(ItemAddComponent, {initialState});
this.bsModalRef.content.closeBtnName = 'Close';
}
To read this value from add Item modal.
Initialize a list inside modal, item-add.component.ts
list: any[] = [];
Then the initialState list can access as “list[]”.
We are sending a sample data “test” and it can be accessed as list[0] from item-add.component.html
<label>Number of Items : </label> {{list[0]}}
Think that we want to pass an object from the item list into modal.
item-list.component.ts
openModalWithComponent() {
const initialState = {
list: [
{"tag":'Count',"value":this.itemList.length}
]
};
this.bsModalRef = this.modalService.show(ItemAddComponent, {initialState});
this.bsModalRef.content.closeBtnName = 'Close';
}
--
<label>Number of Items : </label> {{list[0].value}}
Pass values from modal to child.
Let's see how to pass a value to the item list from the add item form. Declare an EventEmitter inside the item-add.component.ts
public event: EventEmitter<any> = new EventEmitter();
Emit an event when saving the item.
triggerEvent(item: string) {
this.event.emit({ data: item , res:200 });
}
item-add.component.ts
export class ItemAddComponent implements OnInit {
itemform;
numberOfItems = 0;
list: any[] = [];
public event: EventEmitter<any> = new EventEmitter();
constructor(private formBuilder: FormBuilder, public bsModalRef: BsModalRef) {}
ngOnInit() {
this.itemform = this.formBuilder.group({
name: ""
})
}
saveToList(form) {
this.triggerEvent(form.value.name);
this.bsModalRef.hide();
}
triggerEvent(item: string) {
this.event.emit({ data: item , res:200 });
}
}
And inside the item-list.component.ts we can subscribe to the event emitter.
item-list.component.ts
openModalWithComponent() {
const initialState = {
list: [
{"tag":'Count',"value":this.itemList.length}
]
};
this.bsModalRef = this.modalService.show(ItemAddComponent, {initialState});
this.bsModalRef.content.closeBtnName = 'Close';
this.bsModalRef.content.event.subscribe(res => {
this.itemList.push(res.data);
});
}