3

I am displaying a list of cases in a table and want to use DataTables jQuery plugin to implement sorting, pagination, search on the table. The list of cases is retrieved as part of component initialization. The part that am struggling is how do I know that the aura:iteration is complete on the table so that I can invoke the initialization code of DataTables plugin?

CaseList.cmp

<aura:component controller="CaseController">
 <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

 <table id="myTable">
     <thead><tr><th>ID</th></tr></thead>
     <tbody>
       <aura:iteration items="{!v.cases}" var="case">
         <tr><td>{!case.Id}</td></tr>
       </aura:iteration>
     </tbody>
</table>
</aura:component>

CaseList.controller

({ doInit : function(cmp, evt, hlp){ hlp.getCaseList(component); } })

CaseList.helper

({
   getCaseList: function(component) {
       var action = component.get("c.getCases");
       action.setCallback(this, function(actionResult) {
           component.set("v.cases", actionResult.getReturnValue());  
       });
       $A.enqueueAction(action);
   }   
})

CaseController.cls

public class CaseController 
{
   @AuraEnabled
   public static List<Case> getCases() {
       return [SELECT Id FROM Case ORDER BY CreatedDate ASC limit 10];
   }   
}

I need to call "$('#myTable').DataTable()" after the table displays list of cases. I would think that after I set "v.cases" in CaseList.helper, I should be able to write the DataTable initialization code. While there were no javascript errors, the plugin was not able to work on the data that was dynamically added as part of the aura iteration. Hence I was thinking that the right place to add the initialization would be after aura:iteration has completed its work. Something on the lines of oncomplete of apex:repeat. Any thoughts?

2

If you just want the plugin to initialize after scripts has been loaded ,take a look at ltng require

This has afterScriptsloaded attribute to call your JS function

<ltng:require scripts="/resource/jsLibOne,/resource/jsLibTwo" 
    styles="/resource/cssOne,/resource/cssTwo"
    afterScriptsLoaded="{!c.afterScriptsLoaded}"/>

Its worth checking the lifecycle of the component Rendering

enter image description here

  • I've not seen someone try to directly handle the "doneRendering" event. I thought the proper way was to use a function named afterRender in the renderer sub-component. At least that's how I've done built a few components that needed to access the DOM. – pchittum Jan 24 '16 at 11:56
  • @peter Its worth adding your answer as well.I have not seen many doing aura:doneRendering but I don't see a caveat mentioned against this in docs – Mohith Shrivastava Jan 24 '16 at 12:03
  • Yeah...I might...and you're right...the docs are thin on best practice/right approach. – pchittum Jan 24 '16 at 14:49
  • 2
    afterRender is the better choice - aura:doneRendering is a very blunt instrument - afterRender was deigned specifically for scenarios where you need to work with DOM elements that have been placed/mounted into the live document. Also, with ltng:require and dynamic script loading doneRendering is going to happen too early and result in hard to repro timing bugs. – Doug Chasman Jan 26 '16 at 15:29
  • 3
    ... with that said since you also have a 3rd party library being loaded asynchronously you'll actually want to put your code in ltng:require's afterScriptsLoaded handler as mentioned above because ltng:require handles the multiple levels of async sequencing to load the library once and only once and insures that afterScriptsLoaded= only fires after afterRender(). If you put your code in your comp's afterRender() instead it will likely run before jquery is even loaded and fireworks will happen. – Doug Chasman Jan 26 '16 at 15:32

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.