2

I am struggling with how to get my component to render a list item that leverages a jQuery library. I have found that when I troubleshoot in the JAVA script console, I can get the function to work properly, however, other than that it will not work. I have seen several posts about render and rerender, but nothing seems to fit what I am attempting to do in this instance.

To explain:

I have my main component passing a variable through an event to a component within the application. Once the event fires, I am running a query and presenting a list of draggable items. The styling for the items render from the library, however the draggable ability is not there without the use of the troubleshooting. I have verified that the data is being passed correctly as well as the fact that all libraries are loading from static resources

Here is my component:

<aura:component controller="Evolve_lgt_Controller">
<aura:attribute name="userstory" type="object"/>
<aura:attribute name="sprint" type="object"/>
<aura:handler event="c:RefreshUserStories" action="{!c.list_Story_sprint}"/>
<style type="text/css">
li.draggable-story { width: 75px; height: 75px; padding: 0.5em; float: left; margin: 5px 5px 5px 5px; border-style: solid; text-align: center; list-style: none;}
#droppable { width: 200px; height: 400px; padding: 0.5em; float: left; margin: 10px; list-style: none; border-style: solid;}
</style>
<div class="userstory">
    <ul id="draggable">
        <aura:iteration items="{!v.userstory}" var="us">
            <li class="draggable-story ui-state-default">
                <p><ui:outputText value="{!us.Name}"/></p>
            </li>
        </aura:iteration>
    </ul>   
</div>

And here is my controller:

({
list_Story_sprint: function(component, event, helper) {
    var story = event.getParam("userstory");
    var sprint = event.getParam("sprint");
    helper.getStories(component, story);
    helper.getSprints(component, sprint);
    //$(document).ready(function() { 
        console.log($( "li.draggable-story" ).length);
        $( "li.draggable-story" ).draggable();
        $( "#droppable" ).droppable({
            drop: function( event, ui ) {
                $( this )
                .addClass( "ui-state-highlight" )
                .find( "p" );
            }
        });
    //});
},
})

Any assistance is appreciated.

Here is the App:

<aura:application >
<c:load filesInSeries="
/resource/bootstrap/bootstrap-3.3.5-dist/jquery-1.11.3.min.js,
/resource/bootstrap/bootstrap-3.3.5-dist/jquery-ui.min.js, 
/resource/bootstrap/bootstrap-3.3.5-dist/jquery-ui.min.css,
/resource/bootstrap/bootstrap-3.3.5-dist/js/bootstrap.min.js,
/resource/bootstrap/bootstrap-3.3.5-dist/css/bootstrap.min.css" />    
<c:ProjectViewer/>

Here is the loader:

Loader js:

({

init: function(component, event, helper) {

//Modified version of https://github.com/malko/l.js to support resource files without JS or CSS extensions.
!(function(t,e){var r=function(e){(t.execScript||function(e){t["eval"].call(t,e)})(e)},i=function(t,e){return t instanceof(e||Array)},s=document,n="getElementsByTagName",a="length",c="readyState",l="onreadystatechange",u=s[n]("script"),o=u[u[a]-1],f=o.innerHTML.replace(/^\s+|\s+$/g,"");if(!t.ljs){var h=o.src.match(/checkLoaded/)?1:0,d=s[n]("head")[0]||s.documentElement,p=function(t){var e={};e.u=t.replace(/#(=)?([^#]*)?/g,function(t,r,i){e[r?"f":"i"]=i;return""});return e},v=function(t,e,r){var i=s.createElement(t),n;if(r){if(i[c]){i[l]=function(){if(i[c]==="loaded"||i[c]==="complete"){i[l]=null;r()}}}else{i.onload=r}}for(n in e){e[n]&&(i[n]=e[n])}d.appendChild(i)},m=function(t,e){if(this.aliases&&this.aliases[t]){var r=this.aliases[t].slice(0);i(r)||(r=[r]);e&&r.push(e);return this.load.apply(this,r)}if(i(t)){for(var s=t[a];s--;){this.load(t[s])}e&&t.push(e);return this.load.apply(this,t)}if(t.match(/\.js\b/)||t.match(/\.sfjs\b/)){t=t.replace(".sfjs","");return this.loadjs(t,e)}else if(t.match(/\.css\b/)||t.match(/\.sfcss\b/)){t=t.replace(".sfcss","");return this.loadcss(t,e)}else{return this.loadjs(t,e)}},y={},g={aliases:{},loadjs:function(t,r){var i=p(t);t=i.u;if(y[t]===true){r&&r();return this}else if(y[t]!==e){if(r){y[t]=function(t,e){return function(){t&&t();e&&e()}}(y[t],r)}return this}y[t]=function(e){return function(){y[t]=true;e&&e()}}(r);r=function(){y[t]()};v("script",{type:"text/javascript",src:t,id:i.i,onerror:function(t){if(i.f){var e=t.currentTarget;e.parentNode.removeChild(e);v("script",{type:"text/javascript",src:i.f,id:i.i},r)}}},r);return this},loadcss:function(t,e){var r=p(t);t=r.u;y[t]||v("link",{type:"text/css",rel:"stylesheet",href:t,id:r.i});y[t]=true;e&&e();return this},load:function(){var t=arguments,r=t[a];if(r===1&&i(t[0],Function)){t[0]();return this}m.call(this,t[0],r<=1?e:function(){g.load.apply(g,[].slice.call(t,1))});return this},addAliases:function(t){for(var e in t){this.aliases[e]=i(t[e])?t[e].slice(0):t[e]}return this}};if(h){var j,b,x,A;for(j=0,b=u[a];j<b;j++){(A=u[j].getAttribute("src"))&&(y[A.replace(/#.*$/,"")]=true)}x=s[n]("link");for(j=0,b=x[a];j<b;j++){(x[j].rel==="stylesheet"||x[j].type==="text/css")&&(y[x[j].getAttribute("href").replace(/#.*$/,"")]=true)}}t.ljs=g}f&&r(f)})(window);

var loadInSeries = function(filesInSeries, cb) {
  filesInSeries.push(cb);
  ljs.load.apply(ljs, filesInSeries)
}

var loadInParallel = function(filesInParallel, cb) {
  ljs.load(filesInParallel, cb);
}

var finalCB = function() {
  $A.get("e.jam:staticResourcesLoaded").fire();
}

var filesInSeries = component.get("v.filesInSeries");
var filesInParallel = component.get("v.filesInParallel");

if (filesInParallel.length > 0) {
  loadInParallel(filesInParallel, function() {
    if (filesInSeries.length > 0) {
      loadInSeries(filesInSeries, finalCB);
    } else {
      finalCB();
    }
  });
} else if (filesInSeries.length > 0) {
  loadInSeries(filesInSeries, finalCB);
}

}

})

Evt to fire load:

<aura:event type="APPLICATION" description="Event template"/>

Main cmp:

<aura:component controller="Evolve_lgt_Controller">
<aura:attribute name="project" type="Projects__c" default="{'sobjectType':'Projects__c'}"/>
<aura:attribute name="projects" type="Projects__c[]"/>
<aura:attribute name="userstory" type="User_Story__c[]"/>
<aura:registerEvent name="refreshUserStoriesEvent" type="c:RefreshUserStories" />    
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<style>
p.project {
    border-style: inset;
    border-width: 10px;
    border-color: DeepSkyBlue;
    height: 100%;
    width: 20%;
    float: left;
    }
p.userstory_sprint {
    height: 100%;
    width: 80%;
    float: right;
    }
div.project {
    width: 100%;
    height: 100%;
    background-color: #C9C9C9;
    float: left;
    }
div.userstory_sprint {
    width: 100%;
    height: 100%;
    float: right;
}
</style>

<p class="project">
    <div class="project">
        <h3>
        Select Project:
        </h3>
        <div class="btn-group" align="left">
            <select onchange="{!c.change}">
                <aura:iteration items="{!v.projects}" var="p">
                    <option>{!p.Name}</option>
                </aura:iteration>
            </select>
        </div>
        <div>
            <span class="title">
                <h4><b>Project Information</b></h4>
            </span>
            Project Name: {!v.project.Name}<br></br>
            Project Owner: {!v.project.CRMDOC2014__Client_Project_Owner__c}<br></br>
            Consultant: {!v.project.CRMDOC2014__Consulting_Project_Owner__c}<br></br>
            Days Open: {!v.project.CRMDOC2014__Days_Open__c}<br></br>
            Stakeholder: {!v.project.CRMDOC2014__Key_Stakeholder__c}<br></br>
        </div>
    </div>
</p>
<p class="userstory_sprint">
    <div class="userstory_sprint">
        <c:UserStories_Sprints />
    </div>
</p>

Main cmp js controller

({
doInit : function(component, event, helper) {
    helper.getProjectInformationFN(component,'Test Project');
    helper.getProjectNameFN(component);
},
change : function(component, event, helper) {
    // get the value of the select option
    selectedName = event.target.value;
    console.log(selectedName);
    helper.getProjectInformationFN(component, selectedName);
    var evt = $A.get("e.c:RefreshUserStories");
    evt.setParams({
      "userstory" : selectedName,
      "sprint" : selectedName
    });
    evt.fire();
},

})

  • did you load the jquery libraries ? – Mohith Shrivastava Jul 13 '15 at 13:48
  • Yes all libraries are loaded and verified that they are there in the App. – JP Blonshine Jul 13 '15 at 14:21
  • One additional note: When I am in the Javascript console....if I set my target to the Application and execute $( "li.draggable-story" ).draggable(); - the dragging is enabled. – JP Blonshine Jul 13 '15 at 15:50
  • can you share code in your app has well .Please share as much code as possible ?Thanks – Mohith Shrivastava Jul 13 '15 at 16:46
  • added more code...the helpers are just calling the Apex...that is being returned – JP Blonshine Jul 13 '15 at 16:58
1

The list_Story_sprint event (and javascript function) is being called before the component is rendered. So, when you call $( "li.draggable-story" ).draggable(); there aren't any <li>s to match and become activated.

You need to add a UserStories_SprintsRenderer.js with an afterRender() function that makes your jQuery calls. Your afterRender() function will take a component as it's argument. You'll need to call superAfterRender in the after renderer, and then call the jQuery.

Remember: You should never modify the DOM outside a renderer.

  • Based on this blog post, it looks like afterRender only runs when the page is first loaded (component created). After that, any re-rendering of parts of the page will only call rerender and doneRendering. developer.salesforce.com/blogs/developer-relations/2015/06/… – Force2b_Mike Jul 14 '15 at 13:17
  • Thank you for this....it got me on the right track. I will be posting the total answer today at some point that got it working. – JP Blonshine Jul 14 '15 at 13:44
  • Ah yes, that is correct. Building a helper method that you call out from render and rerender is probably the most robust solution. – Christian Carter Jul 14 '15 at 15:04

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.