0

Trying to get ngbTooltip to work within the secure confines of innerHTML. At first I thought this doesn't work cause the data to be inserted is retrieved a-synchronously and view rendering + strapping ngB-functionality is already done, so Implemented Route-resolving. Everything resolves fine before the view gets rendered, however,.. tooltip is still not working.

Please note (!) that when the tooltip is hard-coded in the according template stuff just works, as is other ngB-functionality, etc...

The tooltip is just a trivial example. I need more stuff to function, things like Modals, PopOvers, references to functions in the component.

Looked in the Dom after rendering and its just normal HTML in there, no isolated scope or what so over.

Component

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent {
  quote: string;
  isLoading = false;

  public sanitizedHtml: any;

  constructor(private portareServices: PortareServices,
    private sanitizer: DomSanitizer,
    private route: ActivatedRoute
  ) {
    this.sanitizedHtml = this.sanitizeHTMLstring(this.route.snapshot.data.content.pageContent);
  }

  public sanitizeHTMLstring(htmlStr: string) {
    return this.sanitizer.bypassSecurityTrustHtml(htmlStr);
  }
}

Routing

const routes: Routes = [
  {
    path: 'content',
    resolve: {
      content: ContentResolve
    },
    component: HomeComponent,
    pathMatch: 'full'
  },
  {
    path: '**',
    redirectTo: '',
    resolve: {
      content: ContentResolve
    },
    component: HomeComponent,
    pathMatch: 'full'
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: []
})
export class AppRoutingModule { }

Example JSON with the HTML to be inserted

{ "pageContent": "<button type=\"button\" class=\"btn btn-outline-secondary mr-2\" placement=\"bottom\" [ngbTooltip]=\"htmlContent\">Tooltip on top<\/button>" }

San Jay Falcon
  • 993
  • 1
  • 9
  • 20
  • 2
    That can't work. Templates need to be compiled. That happens at startup in development (JIT) mode, and that happens at build time in production (AOT) mode. – JB Nizet Dec 01 '18 at 16:46
  • So, then, maybe,.. I need something like a "dynamic template" ? There should be a way... even something simple like calling a function from injected HTML in the component... there should be a way. – San Jay Falcon Dec 01 '18 at 16:50
  • Can `pageContent` be any kind of HTML element? If there are only a few possible element types, you could insert predefined components, and pass the parameters with data binding. – ConnorsFan Dec 01 '18 at 16:57
  • Sounds interesting, there will be only a few, so thats do-able. Can you elaborate a bit more? For example how to get this working with the Tooltip,.. or give a online reference that I can dive into. – San Jay Falcon Dec 01 '18 at 17:05
  • could be, but for now, being able to show a tooltip, or open a Modal would be nice enough... Understood and read that binding within innerHTML will not function since that content is not evaluated bij the compiler (if i'm stating that correctly). Seeing stuff like dynamic component/template compiling but that is looking quite over the top for what i am in search of. – San Jay Falcon Dec 01 '18 at 17:45

1 Answers1

1

You can specify the element type in the data structure, along with the tooltip content:

data = { type: "input", content: "My initial text", tooltip: "This is a tooltip" };
data = { type: "button", content: "My caption", tooltip: "Hello world!" };

In the template, the appropriate element is inserted with an ng-switch directive. The tooltip content, and possibly other values, are supplied through data binding:

<ng-container [ngSwitch]="data.type">
  <button *ngSwitchCase="'button'" ... [ngbTooltip]="data.tooltip">{{data.content}}</button>
  <input *ngSwitchCase="'input'" ... [ngbTooltip]="data.tooltip" [value]="data.content">
</ng-container>

See this stackblitz for a demo.

ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
  • I see, this works quite well for organized "data structures", yes. At my side there is no structure, only a root node with a chunk of HTML, the tooltip is not there but for instance opening a Modal `Norwegian<\/a>` here is a screenshot: https://imgur.com/a/zKhZl3G – San Jay Falcon Dec 01 '18 at 18:50
  • Please ignore backslashes and or if – San Jay Falcon Dec 01 '18 at 18:53
  • Does it have to be that way? Saving/restoring HTML markup does not work well at all with Angular. If you could find a way to save the underlying model, it would be easy to recreate the HTML with it. That is what I do in my own projects. – ConnorsFan Dec 01 '18 at 21:29
  • Agreed upon, unfortunately I have to work with a legacy system/model, not my choice.. but your answer led me in a direction which helps me so I will accept it. – San Jay Falcon Dec 02 '18 at 08:35
  • That being said: (1) started fiddling around with jQuery and do some DOM manipulation on the innerHTML inserted HTML (2) started looking into this https://stackoverflow.com/questions/23062537/how-to-convert-html-to-json-using-php which looks absolutely promising. I am favouring this the later. @ConnorsFan simply led me to this by questioning the underlying Model. – San Jay Falcon Dec 02 '18 at 09:19