Button Click on Dynamically Loaded HTML Text

Paul Konstanski
Paul Konstanski used Ask the Experts™
on
I am upgrading a site from javascript and jquery to Angular 7.

The site makes API calls to a server to deliver the HTML code.

What I am running into is that the code that comes from the server does not work.  For example, here is a test example from my html component that shows the problem.

<div [innerHTML]="pageInfo.text | safeHtml"></div>
<p><button class="btn btn-default" (click)="btnclck('btngo')">Test</button></p>

Open in new window


The first line is loaded in on initiation when the site loads and then changes when you move to a new page.
The second is a test line that I placed in there just to illustrate my problem.

The second line works exactly as it is supposed to.

But if the same button code comes in from an api read from the database, it doesn't work.

If you look at the code in the code inspector, you will see that the Angular coding has been applied to the second, but not to the first.

Angular Button Description
My assumption is that because this dynamic text is loaded after the rest of the site, the angular coding is not applied to the button tag and as such, the onclick doesn't work.

How do I get around this?  

The code has to come dynamically from a database.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
Paul KonstanskiProject Specialist

Author

Commented:
It is related in that it is passing of the dynamic HTML text but the issue is with how TypeScript formats things.  

If I send what looks like an Angular formatted button click dynamically, and then inspect it with the code inspector, it show it as:

<p><button class="btn btn-default" (click)="btnclck('btngo')">Continue</button></p>

But if that same button click line was placed in the "Component" and not dynamically loaded, upon inspection it looks like this:

<p><button class="btn btn-default" _ngcontent-c11="">Continue</button></p> and it is labeled as an "Event".  See this image.

So for HTML that is in the component at the time the page loads, it converts it to typescript.

So I tried another experiment and I passed the exact same text as what the Typescript rendered text looks like (e.g. the _ngcontent-c11) and when I click on the two buttons, the one that is in the Component works fine.  But the dynamically read in text does not.  You can see from this "inspection" image that only the component button is labeled "Event" (as indicated by the blue button).
Inspector with Event HighlightedSo what I can't figure out is how to get a button press (or a submit button for that matter or any of the interactive elements of a form) to work when they are dynamically loaded.  It seems that only text that is on the page prior to loading works.

Is there a way around this?
Most Valuable Expert 2017
Distinguished Expert 2018
Commented:
The problem is that Angular2+ only does compiling on components - not on partial updates. You would need to wrap this in a component and then re-compile the component.

I can't give you a full solution now - but do some checking on recompiling components and you should find some code on how to do that. If you don't come right post back here and I will pick it up again.
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Paul KonstanskiProject Specialist

Author

Commented:
I haven't had a chance to test implementing the content of this article, but is this or something similar to it the process for recompiling components?

Dynamically Loading Components Article

If this is the right track, I'll work at getting something like this working.

Thanks.
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
Yes that looks like it is in the ballpark.
Paul KonstanskiProject Specialist

Author

Commented:
Here is the article that gave me what I needed. This is a GREAT explanation that walks you through step by step. They had this loading into the app.component but I was able to easily move it to my home component and it works great.  

Dynamic Form, Configurable Fields

They also have a stack blitz site with this in action.

Then once I got it working for when the site first loads, I then had to figure out how to get it to advance to the next dynamically loaded page. I did that by using this sequence.

  gotoPage(pgref: string) {
    let gopage = String('home/'+pgref);
    this.router.navigateByUrl('/home', {skipLocationChange: true}).then(()=>
    this.router.navigate([gopage])); 
  }

Open in new window


It is great to see it coming together.
Paul KonstanskiProject Specialist

Author

Commented:
Thanks again for the help.
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
You are welcome.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial