How to use jQuery (or any JS lib) in initial post rendering of Lightning Components
(Cross-posted from the answer on developer.salesforce.com)
Hi Peter,
Polling isn't really ideal as the timing may vary depending on the device, network, etc., and between standalone apps and the Salesforce1 Mobile App. Using a loader such as RequireJS works well, and a few folks have written samples that use this. Here's an unmanaged package that includes events, components, static resources, and a sample app that uses RequireJS to load jQuery and Bootstrap:
https://login.salesforce.com/packaging/installPackage.apexp?p0=04tB000000011BS
Because it's unmanaged, you will need to change the namespace from aotp1 to your own. Once you've done that you can access the test app with a URL similar to this:
https://XXX.lightning.force.com/yyyy/requiresTestApp.app
You can also use Setup to add the requiresTestTab to S1. It's the same as the standalone app, just in a component that can be accessed from the "stage left" menu in S1. These components demonstrate using a namespaced version of Bootstrap, along with setting up Bootstrap and jQuery via different ways. They are integrated via attributes, events, etc. jQuery selectors are constrained to the component, something that's important to consider as components ≠ full-page apps. A jQuery plugin to do this automatically is a good candidate for another sample.
We're working on how to best support this in the product. In the meantime samples such as this can help many users. If you improve on this, or find that lighter weight loaders such as headLoad work well, I'd be interested in hearing more.
Updates as of 10/30/2014:
I've updated the sample to include the script loading in the requires component, as Peter suggested. Included are:
- The requires component is now defined as follows:
<aura:component> <aura:attribute name="baseUrl" type="String" default="/resource/"/> <aura:attribute name="styles" type="Map"/> <aura:attribute name="scripts" type="Map"/> <aura:attribute name="deps" type="Map"/> <aura:attribute name="initScripts" type="Aura.Action"/> <aura:registerEvent name="requiresReady" type="aotp1:requiresReady"/> <aura:handler name="init" value="{!this}" action="{!c.init}"/> </aura:component>
- The requiresTest2 component uses the requires component as follows (note the ready flag used to indicate that the component has been initialized):
<aura:attribute name="ready" type="Boolean" default="false" description="Used to check..."/>
The requiresTest2 helper now has an initHandlers function that is called from the requiresReady event and the renderer. The ready flag mentioned above is used to check whether to proceed with the init. This is necessary because the loading order can vary depending on the container, for example the Lightning app vs. the Salesforce1 Mobile App tab.
The requiresReady event is now COMPONENT scoped, and includes the objects returned by the requirejs callback, using the names specified in the attributes.
Version 1.2 installation URL:
https://login.salesforce.com/packaging/installPackage.apexp?p0=04tB000000011BX
As with any samples, no guarantees are made, but I am interested in feedback or improvements!
In all documentation it states
<ltng:require scripts="/resource/jQuery1120" afterScriptsLoaded="{!c.afterScriptsLoaded}"/>
But you need to add / after the resource name
<ltng:require scripts="/resource/jQuery1120/" afterScriptsLoaded="{!c.afterScriptsLoaded}"/>
I've noticed that there is ltng:require component in auradocs: https://cs11.lightning.force.com/auradocs/reference.app#reference?descriptor=ltng:require&defType=component and usage is:
<ltng:require
scripts="/resource/styles/js/jquery.min.js,
/resource/styles/js/jquery.dataTables.min.js,
/resource/styles/js/calendar.js"
afterScriptsLoaded="c.onInit"/>
But there is no reference in Ligtning Comp Dev Quide. It seems safe to use what is available in auradocs.