Skip to main content

jQuery in Lightning components

About Us
Published by admin
10 May 2019
1957

When working with the layout of traditional HTML pages, jQuery is used everywhere. This library significantly simplifies the work with JavaScript. It results in the optimization of many traditional approaches to interact with a page. The usage of jQuery contributes to the reduction of the code amount and also increases the overall page performance. The library also provides support for older browsers. These features make jQuery very popular among developers, including those ones who work with Salesforce. Moreover, due to its great popularity, the Internet provides a great amount of ready-made solutions and implementations based on jQuery.

In our blog, we discuss main jQuery usage aspects within Lightning components, in particular, its compatibility with the Lightning Locker Service.

jQuery makes it easier to work with a fast and feature-rich JavaScript library. It can be very helpful in the most common scenarios of interaction with an HTML page: access and manipulate the attributes and contents of DOM elements, work with events and CSS animation.

As a Salesforce user, you are surely interested in the compatibility of jQuery with Lightning framework, especially with Lightning  Locker Service.

We can’t use online JavaScript libraries in Lightning components, but we can enable jQuery as a Static Resource by the tag ltng:require:

<ltng:require scripts="{!$Resource.jquery331min}" afterScriptsLoaded="{!c.jqueryRun}"/>

Let's try to use common jQuery selectors on the simple Lightning component to check how  Lightning Locker Service works with the jQuery.

1

QueryTesting.cmp

<aura:component description="jQueryTesting">
   <ltng:require scripts="{! $Resource.jquery331min} " afterScriptsLoaded="{! c.jqueryRun }"/>
   <p>First paragraph</p>
   <p>Second paragraph</p>
   <lightning:button label="Click me" variant="brand" onclick="{! c.buttonHandler }"/>
</aura:component>

 

jQueryTestingController.js:

({
   jqueryRun: function (component, event, helper) {
       $("document").ready(function(){
           console.log('ready is run ');
       });
   },

   buttonHandler: function (component, event, helper) {
      console.log('button is pressed');
       var $firstP = $("p:first").text();

       var $lastP = $("p:last").text();    

       console.log('p: ',firstP);       //input: “p: Hello, I'm here!”
       console.log('p: ',lastP);           //input: “p: Second paragraph”
   },
})

As you can see, jQuery gets information from page and selectors work perfectly as well as simple functions like “hide()”.

Now add a couple of new elements:

<aura:attribute name="inputValue" type="String"/>
  <p class="slds-m-around--small">{! 'inputValue: ' + inputValue}</p>
  <input title="Just input" value="{! v.inputValue}"/>
   <lightning:input label="lightning input" value="{! v.inputValue}"/>

And try to change attributes of HTML tags by the method “attr()”.

$(input).attr({
           placeholder: 'Please enter the valid value'
       });

jQuery-in-salesforce-lightning-components

For the “Input” component this function works well, but if you try to change an attribute of “lightning: input” this logic will not work.

jQuery doesn’t support Lightning components. For sure, in the last case, you can use a standard button with appropriate SLDS (Salesforce Lightning Design System) styles, but using the lightning components is a proper approach.

In Visualforce, jQuery Data Tables plugin is considered popular, as it allows creating informative data tables by one row of code.

Let's try how it will work in Lightning. First, create the new static resource with Data Table jQuery Plugin, and add it in our ltng:require tag:

<ltng:require styles="{! $Resource.datatable + '/DataTables-1.10.16/media/css/jquery.dataTables.min.css'}"

scripts="{!join(',',  $Resource.jquery331min ,                         $Resource.datatable + '/DataTables-1.10.16/media/js/jquery.dataTables.min.js')
                          }"

afterScriptsLoaded="{!c.jqueryRun}"/>

Next, modify our page to provide a loading list of Accounts. Create Apex class jQueryTestingController:

public with sharing class jQueryTestingController {

    @AuraEnabled
    public static List<Account> getAccounts() {
        List<Account> accounts = [
                SELECT  Id,
                        Name,
                        CreatedDate,
                        Type
                FROM    Account
        ];
        return accounts;
    }
}

And add a simple init method in our controller:

init: function (component, event, helper) {

       var action = component.get('c.getAccounts');
       action.setCallback(this, $A.getCallback(function (response) {
           var state = response.getState();
           if (state === "SUCCESS") {
               component.set("v.accounts",  response.getReturnValue());
           }
           else if (state === "INCOMPLETE") {
               console.log('Status incomplete');
           }
           else if (state === "ERROR") {
               var errors = response.getError();
               if (errors) {
                   if (errors.length > 0) {
                       for (var i = 0; i < errors.length; i++) {
                           if (errors[0].pageErrors) {
                               if (errors[0].pageErrors.length > 0) {
                                   for (var j = 0; j < errors[i].pageErrors.length; j++) {
                                       console.log('Internal server error: ' + errors[i].pageErrors[j].message);
                                   }
                               }
                           }
                           console.log(errors[i].message);
                       }
                   }
               }
               else {
                   console.log('Internal server error');
               }
           }
       }));
       $A.enqueueAction(action);
   },

Now, let's modify our page. Add simple HTML page with our Accounts:

<table id="tableId" class="slds-table slds-table_bordered slds-table_cell-buffer" cellspacing="0" width="100%">

           <thead>
           <tr>
               <th>Name</th>
               <th>Type</th>
               <th>Created Date</th>
           </tr>
           </thead>
           <tbody>
           <aura:iteration items="{!v.accounts}" var="acc">
               <tr>
                   <td>{!acc.Name}</td>
                   <td>{!acc.Type}</td>
                   <td>{!acc.CreatedDate}</td>
               </tr>
           </aura:iteration>
           </tbody>
       </table>

Reload the page and see the usual non-complex SLDS table:

jQuery

How about adding more functionality? Time to use our new plugin.

To modify this table we need the following function:

 $('#tableId').DataTable();

Reload the page and enjoy the new powerful data table with searching, sorting, and pagination.

jQuery

All the features of our table work great.

Looks like helpful, but don't forget about the main issue of jQuery in Lightning: the library uses deprecated approaches to interact with DOM. If you gonna use your Lightning component in the managed package avoid jQuery in a component controller and helper.

To avoid issues with security review you should use jQuery only in the component renderer.

Still have questions? Contact JET BI experts


Julia Solomenko
Senior Project Manager
image
image

We have available resources to start working on your project within 5 business days

1 UX Designer

image

1 Admin

image

2 QA engineers

image

1 Consultant

image
Related Articles
All articles
image
Is Salesforce Winning the Public Sector Race?
An analysis of Salesforce's rapid expansion into the U.S. public sector, tracing its path from cautious early government licensing deals in the 2010s through the launch of Government Cloud in 2012, its pivotal role in COVID-19 vaccine rollouts, and its 2025–2026 push into military and intelligence work via Agentforce and Missionforce. The piece covers major 2026 contracts — including a $5.6 billion Army deal, a $1.6 billion VA agreement, and Pentagon Impact Level 5 authorization — alongside real-world case studies like California's REAL ID processing and the UK's NHS back-office operations. It also examines the structural obstacles still facing Salesforce and other vendors in government tech: legacy IT systems decades old, outdated federal procurement rules, budget constraints, and organizational caution around AI adoption, plus the competitive pressure from Palantir, Microsoft, and Oracle in the race for public sector AI spending.
28 August 2026
image
Why Your Salesforce Flows Are Agentforce's Biggest Problem
This article argues that the most underestimated risk in Agentforce deployments isn't data quality — it's the automation layer: years of overlapping Flows, Process Builder processes, Apex triggers, and managed package logic that no one has reviewed end-to-end. It explains why AI agents inherit automation complexity without the tribal knowledge human admins carry, why technical debt only becomes visible after an agent hits it in production, and why a clean demo is no indicator of production readiness. The article closes with a concrete, tool-by-tool inventory approach using Flow Trigger Explorer, Salesforce Optimizer, Setup Audit Trail, Apex Debug Logs, Agent Builder, and Health Check — scoped to the specific processes the agent will actually use rather than the whole org.
23 July 2026
image
How to Wire Multiple Salesforce Projects in One Org Without Breaking Everything
This article maps the real integration patterns that emerge when multiple Salesforce projects — both managed packages and unpackaged code — share a single org. It covers four concrete patterns: attaching custom triggers to package-owned objects, calling global members exposed by managed packages, writing directly into another project's objects, and runtime-guarded reads of package data. It then addresses access control for authenticated and guest users, including the Master-Detail wall and the without sharing elevation pattern. The piece closes with eight concrete risks (compile-time dependencies that block uninstall, upgrade coupling, silent cascade failures, access invisible to admins) and six actionable recommendations for keeping cross-project coupling manageable.
08 July 2026