Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically change template for Angular 5 ng-bootstrap Modal Dialog

I'm working on a modal dialog that I need to be able to dynamically change out the templateURL for dynamically. What's shown is the default template. I'm just wondering about how to achieve that as this would be called with the templateURL name and location being passed in. Below is my component code :

import { ModalService } from './../../services/modal.service';
import {Component, Input} from '@angular/core';

import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'app-ngbd-modal-content',
  templateUrl: '../../templates/modal.tp1.html'
})

export class ModalOptionsComponent {
  @Input() name;

  constructor(public activeModal: NgbActiveModal, modelService: ModalService) {}
}

export class  NgbdModalComponent {
  constructor(private ngbModal: NgbModal) {}
}

Ideally I'd like to open it from my service class below versus the component but I'm not really sure how to do that. I've done quite a fair bit of research but I'm not finding much on how to accomplish this.

Modal.service.ts:

import { ModalOptionsComponent } from './../pages/modal-options/modal-options.component';
import { Injectable } from '@angular/core';
import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';

@Injectable()
export class ModalService {

  constructor(private ngbModal: NgbModal, private modalComp: ModalOptionsComponent) { }

  modalService(modal: any) {
    const modalDefaults = {
      templateUrl: '../templates/modal.tp1.html'
    };
    const modalOptions = {
      hasClose: true,
      closeButtonText: 'CLose',
      actionButtonText: 'OK',
      headerText: 'Proceed?',
      bodyText: 'Perform this action?',
      okResult: {}
    };
  }

  showModal(customModalDefaults: any, cusomeModalOptions: any) {

  }


}

One of the things I'm needing to do is create service class for this as well I'm very new to angular and wondering how to acheive this.

like image 778
yams Avatar asked Nov 08 '22 07:11

yams


1 Answers

Because there's not the ability that I can find to change out the templateUrl I had to make do with creating a component for each type of dialog I needed. The downside to this was that it was no longer dynamic but it suits what I need it for. And basically you can use the service to generate the type of component needed. One thing that is unfortunate is using dynamic component loading wasn't really a viable solution because of the complexity of doing it. Below is an example of what I did.

Component code for default modal dialog:

import {Component, Input} from '@angular/core';

import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'app-ngbd-modal-content',
  template: `
<div class="modal-header">
<h3 class="font-32" style="padding-bottom: 0px">{{headerText}}</h3>
</div>
<div class="modal-body">
<p>{{bodyText}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
  `,
  styleUrls: ['./default-modal-dialog.component.scss']
})
export class DefaultModalDialogComponent {
  @Input() bodyText;
  @Input() headerText;

  constructor(public activeModal: NgbActiveModal) {}

}

Component code for FeaturedSearch:

    import {Component, Input} from '@angular/core';

    import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';

    @Component({
    selector: 'app-featured-search-dialog',
    template: `
    <div>
        <div class="modal-header">
            <h3 class="font-32" style="margin-bottom: -16px;">Edit Heading and Subheading</h3>
        </div>
        <div class="modal-body" style="padding:30px;">
            <div class="row">
                <div class="col-md-12">
                    <label class="font-14-bold">Heading</label>
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <input style="box-shadow: rgb(102, 102, 102) 0px 0px 4px inset; border: 0px; margin-bottom: 50px;"  type="text" class="form-control input-sm" ng-model="modalOptions.okResult.heading" >
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <label class="font-14-bold">Subheading</label>
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <input style="box-shadow: rgb(102, 102, 102) 0px 0px 4px inset; border: 0px;" type="text" class="form-control input-sm" ng-model="modalOptions.okResult.subheading" >
                </div>
            </div>
        </div>
        <div class="modal-footer">
            <div style="margin-top: 8px; margin-bottom: 8px;">
                <button style="background-color: #999999; color: #ffffff;" type="button" ng-show="modalOptions.okResult.buttonText !== 'Close'"
                        class="btn font-14-bold"
                        data-ng-click="modalOptions.close()">Close
                </button>
                <button style="background-color: #004065; color: #ffffff; width: 70px;" type="button" class="btn ng-binding" ng-disabled="modalOptions.okResult.heading.length <= 0 || modalOptions.okResult.subheading.length <=0" data-ng-click="modalOptions.ok()">OK</button>
            </div>
        </div>
    </div>
    `,
    styleUrls: ['./featured-search-dialog.component.scss']
    })
    export class FeaturedSearchDialogComponent {

    @Input() heading;
    @Input() subheading;

    constructor(public activeModal: NgbActiveModal) {}

    }

Custom Modal Service :

import { Injectable, Input, ComponentFactoryResolver } from '@angular/core';
import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';
@Injectable()
export class ModalService {
    constructor(private ngbModal: NgbModal,
                private componentFactoryResolver: ComponentFactoryResolver) {}

  showDefaultModalComponent(theComponent: any, headerText: any, bodyText: any) {
    const componenetFactory = this.componentFactoryResolver.resolveComponentFactory(theComponent);
    const modalRef = this.ngbModal.open(theComponent);
    modalRef.componentInstance.bodyText = bodyText;
    modalRef.componentInstance.headerText = headerText;
    return modalRef;
  }

  showFeaturedDialog(theComponent: any, heading: any, subheading: any) {
    const componenetFactory = this.componentFactoryResolver.resolveComponentFactory(theComponent);
    const modalRef = this.ngbModal.open(theComponent);
    return modalRef;
  }


}
like image 174
yams Avatar answered Nov 14 '22 21:11

yams