0

I'm facing an issue with html content dynamically injected inside unescapedHtml aura component. Inside the injected content there are links ('a' tags) which I want to intercept the click to perform stopPropagation / preventDefault in order to open the link (SF record) directly in a salesforce tab using workspace API. Those different approaches are dead ends:

  • Listening to onclick event on a higher level never provides the good event target (the link).
  • Manually trying to get the link elements at render time to add click event gives null
  • Using onclick pure javascript on the link element itself is forbidden

I'm running out of ideas to get the most of dynamic html + event handling, if someone has a trick, would be great. Thanks in advance

2
  • 1
    The ideal solution is to not use unescapedHtml, but instead use $A.createComponents to build a proper DOM yourself, which would include the ability to link to controller methods to be called on the anchor clicks. If you show us some code, we might be able to help you with a solution. If you haven't already, please take a moment to read about How to Ask and take the tour, then edit your question to include a Short, Self Contained, Correct (Compilable), Example for us to work with.
    – sfdcfox
    Sep 27, 2021 at 17:36
  • Thanks for your answer ;) No code really ready sorry. Not sure that I can use $A.createComponents because I don't know in advance the structure and content of the injected HTML. It comes from an editor available for content contributors, where we allow specific tags, everything sanitized before display. Would this be possible then ? calling $A.createComponent ["aura:html",{ 'tag': 'div' to create one wrapper element. In the callback of createComponent, using innerHTML (likely to fail) to update the div content, then manipulating childnodes to set onclick event (and finally set {!v.body})
    – M.C
    Sep 28, 2021 at 8:40

1 Answer 1

0

You are allowed to do this with innerHTML. Here's a quick copy-paste example I wrote for you:

<aura:application >
    <aura:handler name="render" value="{!this}" action="{!c.doRender}" />
    <div onclick="{!c.handleClick}" aura:id="container"></div>
</aura:application>

({
    doRender: function(component, event, helper) {
        component.find("container").getElement().innerHTML = '<a href="demo">Click Me!</a>';
    },
    handleClick: function(component, event, helper) {
        alert(event.target.href);
        event.preventDefault();
    }
})

Note how we handle the click at the container level. We can use event.target to determine what was clicked on, and if it's a link, we can perform specific actions.

The reason why aura:unescapedHtml doesn't work is that it is secured as a component would be, rather than being manipulated as a HTML element. By using a direct HTML element, we are allowed to manipulate it, mostly. innerHTML is still sanitized, so you can't directly inject script tags or attach event handlers directly in the HTML. You can't, for example, do:

<a href="#" onclick="alert('hello world')">Click Me!</a>

Such a script would be blocked by the runtime.

Note that if you choose to use innerHTML and then want to use document.querySelector to attach events, you can, but you should wait a render cycle using setTimeout. You'll also have to use component.getReference("c.methodName") to use controller methods, and $A.getCallback if you need to update any attributes during the process.

2
  • Thank your for this complete answer, it's more than helpful and would perfectly suit my needs ! As long as I receive the right event.target everything should be fine ! I'm gonna try this, thanks a lot.
    – M.C
    Sep 28, 2021 at 13:03
  • Works like a charm !
    – M.C
    Sep 28, 2021 at 14:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .