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>" }

5
  • 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. Commented Dec 1, 2018 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. Commented Dec 1, 2018 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. Commented Dec 1, 2018 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. Commented Dec 1, 2018 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. Commented Dec 1, 2018 at 17:45

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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 <a href=\"#\" (click)=\"open('Norwegian')\">Norwegian<\/a> here is a screenshot: imgur.com/a/zKhZl3G
Please ignore backslashes and or if <a href is the right approach.. that I can work around on the backend.
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.
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.
That being said: (1) started fiddling around with jQuery and do some DOM manipulation on the innerHTML inserted HTML (2) started looking into this stackoverflow.com/questions/23062537/… which looks absolutely promising. I am favouring this the later. @ConnorsFan simply led me to this by questioning the underlying Model.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.