I have an issue where the Rows and columns appear as plain text instead of rows and columns when Locker service is enabled, but when I disable the Locker service I can see the data as proper rows and columns.

Lightning component.

<aura:component >

  <table class="slds-table slds-table--bordered slds-table--cell-buffer" aura:id="targetTable">
        <thead aura:id="targetDetailsHead" class="targetHead"></thead>
        <tbody aura:id="targetDetailsBody" class="targetBody"></tbody>
<ui:button aura:id="button" buttonTitle="Click to see what you put into the table" class="button" label="Generate" press="{!c.myAction}"/>    


    myAction : function(component, event, helper) {
        var tableColList = ['<tr> <th>Colval1</th>' ,'<th>Colval2</th> ','<th>Colval3</th> ','<th>Colval4</th> ' ,'<th>Colval5</th> ','<th>Colval6</th> </tr>'];
        var tableRowList = ['<tr><td>Rowval1</td>' ,'<td>Rowval2</td>','<td>Rowval3</td>','<td>Rowval4</td>' ,'<td>Rowval5</td>','<td>Rowval6</td>'];
         var targetDetailsHead = component.find("targetDetailsHead");
          var targetDetailsBody = component.find("targetDetailsBody");
            var thead= '', tbody= '';
                for (var i = 0, listLength = tableColList.length; i < listLength; i++) {
                    if (tableColList.length > 0 && tableRowList.length > 0 ) {
                console.log('---Table Head---',thead);
                console.log('---Table Body---',tbody);
                targetDetailsHead.getElement().innerHTML += thead;
                targetDetailsBody.getElement().innerHTML += tbody;
                console.log('---Table Head with innerHTML---',targetDetailsHead.getElement().innerHTML);
                console.log('---Table Body with innerHTML---',targetDetailsBody.getElement().innerHTML);


Am I missing something? Any suggestions will help me, Thanks !

Image below indicates Locker Service Enabled : Locker Enabled

Image below indicates Locker Service Disabled Locker Disabled

1 Answer 1


LockerService will run any "raw" HTML text through a library called DOMPurify which will sanitize the HTML for any potential XSS threats. DOMPurify makes a call to new DOMParser().parseFromString() passing along the raw HTML before doing it's analysis. Using your example above, when you call innerHTML, the underlying call in DOMPurify is:

new DOMParser().parseFromString("<tr> <th>Colval1</th><th>Colval2</th> <th>Colval3</th> <th>Colval4</th> <th>Colval5</th> <th>Colval6</th> </tr>", 'text/html')

Which strips the <tr> and <th> element tags since that is not a valid HTML structure outside of the <table> element. If you run the same command with that code wrapped in <table> and <thead> elements you get the exected DOM back:

new DOMParser().parseFromString("<table><thead><tr> <th>Colval1</th><th>Colval2</th> <th>Colval3</th> <th>Colval4</th> <th>Colval5</th> <th>Colval6</th> </tr></thead></table>", 'text/html')

So I suggest only setting innerHTML values to DOM that is valid standalone, or using the HTMLTableElement javascript APIs, like createTHead() and insertRow(), to dynamically create your table.

  • Hi #TrevorBilss Thanks alot for response. can you please guide me where should I change my code exactly ?? Commented Apr 11, 2017 at 12:40
  • Hey thanks man! #Trevor It worked like a charm. Now I understand we need to pass the whole valid HTML to make it count ! Commented Apr 11, 2017 at 14:45

You must log in to answer this question.

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