[SalesForce] LWC is it Possible to Load the JQuery Plugin Datatables in a Lightning Web Component

Edit: Solved!

I'm struggling to load the infamous datatables.net jQuery plugin into my Lightning Web Component. Even using the most basic example, I haven't had any luck. It seems like there are a few similar Stack Exchange posts from earlier this year mentioning the same, so maybe it's not possible?

HTML example taken from https://datatables.net/examples/data_sources/dom.html

MyLwc.html

<template>
    <table id="example" class="example-table display" style="width:100%">
        <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Tiger Nixon</td>
                <td>System Architect</td>
                <td>Edinburgh</td>
                <td>61</td>
                <td>2011/04/25</td>
                <td>$320,800</td>
            </tr>
            <tr>
                <td>Garrett Winters</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </tfoot>
    </table>
</template

MyLwc.js

import { loadStyle, loadScript } from 'lightning/platformResourceLoader';

import JQUERY from '@salesforce/resourceUrl/jQuery311';
import DATATABLES_JS from '@salesforce/resourceUrl/DataTablesMinJs11020';
import DATATABLES_CSS from '@salesforce/resourceUrl/DataTablesMinCSS';

constructor() {
    super();
    this.loadExternalLibraries();
}

async loadExternalLibraries() {
    loadScript(this, JQUERY).then(() => {
        console.log('Loaded JQUERY');
        loadStyle(this, DATATABLES_CSS).then(() => {
            console.log('Loaded Datatables CSS');
            loadScript(this, DATATABLES_JS).then(() => {
                console.log('Loaded Datatables JS');
                $('#example').DataTable();
            })
        })
    })
}

I'm able to confirm the static resources load:

static resources loaded
table

But when I call $('#example').DataTable(); either in a function after the page loads, or in the asynchronous load, the styling is never applied and the plugin doesn't seem to load. I don't get any errors in the console.

I realize that LWC likes to rename your ids. So calling $('#example') probably shouldn't work anyway, but giving the table a class of 'example-table' and doing $('.example-table').DataTable() also seems to result in nothing happening.

Has anyone had luck getting this library working?

Edit: Quick Troubleshooting Update: It looks like jquery might be to blame here. Adding an HTML element like so:

<div lwc:dom="manual" class="lwc-manual" id="lwc-manual"></div>

And trying to reference it in jquery doesn't seem to work:

$(".lwc-manual").text("Some appended text.");

Is there some initialization that needs to happen? For instance:
this.$ = await loadScript(this, JQUERY); ?

EDIT 2: I GOT JQUERY TO WORK! DATATABLES IS NOW RECOGNIZED:

const table = this.template.querySelector('.example-table');
$(table).DataTable(); 

I had to use this.template.querySelector('') to first get the element, then apply DataTable();

Best Answer

SOLVED!

Here's how I did it:

MyLwc.html

<table lwc:dom="manual" class="example-table display" style="width:100%"></table>
  1. Query for the table using this.template.querySelector();
const table = this.template.querySelector('.example-table');
  1. Manually construct the table's headers
const columnHeaders = ['Id', 'Name'];

let columnHeaderHtml = '<thead><tr>';

columnHeaders.forEach(function(header) {
    columnHeaderHtml += '<th>' + header + '</th>';
});

columnHeaderHtml += '</tr></thead>';

table.innerHTML = columnHeaderHtml;

  1. Initialize DataTables
let dataTable = $(table).DataTable();
  1. Populate the Data Table!

Note: 'recordsQueried' is just a list of SOQL'd records.

this.recordsQueried.forEach(function(r) {
    dataTable.row.add([
        r.Id,
        r.Name
    ]);
}) 
dataTable.draw();
Related Topic