[SalesForce] Lightning Component Renderer JQuery Conflict

I have been tasked with porting over a hierarchy tree feature from Visualforce to Lightning. It uses jQuery to highlight and expand the node in the tree hierarchy.

I am aware of the Lightning Design Systems tree area but this is not suitable to what I am doing.

Problem

When the component loads, the applied jQuery that has been written to perform the highlight and tree expansion is not applied. The nodes of the tree exist in the DOM (check via Chrome Tools) but the required jquery code to enable the behavior is not available.

After a lot of reading of articles like this:

How to use jQuery (or any JS lib) in initial post rendering of Lightning Components

Lightning Renderer External Script Dependency

I have ensured that jQuery is loaded into the component using ltng:require in the .cmp markup. I initially put my jquery code into the afterScriptLoads attribute. I then failing this and more reading put it into a custom renderer inside of the rerender method.

I step through the code and it loads jQuery finds the element I want to manipulate in the DOM.

So far so good. So I continue in the rendering cycle and it all just resets. It is like something comes in at the end and just performs a refresh.

For this feature to work I need jquery so wish to stick to getting this working.

This appears to be some sort of rendering lifecycle issue as the script is available.

Any ideas what I might be doing wrong?

The code that does the initialisation to the tree is:

var $j = jQuery.noConflict();

    //expand to show the current sobject in the tree
    $j("#" + recordId).parents("ul").show();

    // OPTION 1 expand the current node to show its children
    $j("#" + recordId).children("ul").show();

    // OPTION 2 expand the current node's descendants to show its children, grandchildren, yada yada
    $j("#" + recordId).find("ul").show();

    /***
    //epxose the current node...
    $("#" + currentPageId).slideToggle();
    ****/

    //highlight the current node...
    $j("#" + recordId).children("span.displayLine").addClass("currentRecord");

    //scroll to it... 

    //set up an action to highlight a section of the list when you mouse over its leader
    $j(".control").hover(function(){
        $j(this).closest("li").toggleClass("hierarchyHighlightHover");
    });

    //set up the click action
    $j(".control").click(function(){
        $j(this).closest("span.displayLine").siblings("ul").slideToggle();
    });  

CMP Code

    <aura:component controller="AccountHierarchyCtrl" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId">    
    <aura:attribute name="treeBody" type="string" description="Contains the body of the tree markup as generated by the JS" />    
    <aura:handler name="init" value="{!this}" action="{!c.init}"/>

      ...
    <ul id="treeContainer"><aura:unescapedHtml value="{!v.treeBody}"/></ul>    
    <ltng:require scripts="/resource/JQueryLightning" afterScriptsLoaded="{!c.onJqueryLoad}" />  
</aura:component>

Best Answer

I would follow the below in sequential order to find a solution to the problem.

1.Lightning components works on the concept that you manipulate data and UI gets manipulated automatically. I would see if i can manipulate the data to get UI work the way i want. I would use the components init event for building the hierarchical UI

2.I would really check if i need jquery for this. Jquery would manipulate a dom element, i would check if i can manipulate that using vanilla js.

Below information is what might help you solve this problem:

3.If you would still want to use jquery for manipulation then try Using the aura:valueRender event(summer 2017) to manipulate UI after dom is constructed.

  1. Be little cognizant of the race condition you would run into. sometimes your jquery resource might load after the rendering cycle is complete so use a boolean in your after scripts loaded to ensure your scripts are loaded and then modify the UI in your post rendering cycle.

If you need specific help then post your code to see where the issue is