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


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 ?? – Kashyap Kalakbandi Apr 11 '17 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 ! – Kashyap Kalakbandi Apr 11 '17 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.