0

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>
  • Are you running jquery code on onJqueryLoad function after the ltng:require loads your scripts. this link has doug's comment which basically states the same thing. salesforce.stackexchange.com/questions/106495/… If you still need help please post the entire HTML,controller data and CSS classes to debug this. – RedDevil Jun 12 '17 at 14:02
  • I am running the given jQuery code inside the method onJqueryLoad which is called when ltng:require completes the loading. Which according to dougs comments tells us this should be post render events. So it will only run that after render,rerender and afterRender have completed. Which if it worked is ideal. But it doesn't. Something seems to go in after it and reinitialise it all. This rendering lifecycle seems overly complex to me. The code I am using is pretty simple. I thought it was Lockerservice at first but I now think it is some sort of event chain thing. – sean healy Jun 12 '17 at 17:27
1

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

  • Thanks for the swift reply. I perform the construction of the tree in the init method. It constructs the markup as expected. The jquery is just used to perform the final initialisation of the nodes (expanding out the parent of a nested node, the selected node bold. I will post the code in question. – sean healy Jun 12 '17 at 12:05

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.