I'm trying to build a custom datable because I want the functionality to sort, search and paginate and also add action buttons in each row. Initially, my VF page was using jQuery DataTables but we have now decided to rebuild that page in LWC.
I found a similar post but it hasn't really worked for me.
I then found Vanilla Datatables (Javascript) and Simple Datatables (ES2018) I have tried to implement Vanilla Datatables but I keep running into issues such as:
TypeError: Cannot read property 'length' of undefined
The above error is thrown because the library is unable to find the body of the table.
My point is that I feel this library won't work because it's using document
, window
and so on.
I was wondering if there is a way I could convert this library to something that is more suited to LWC basically have it "export" the modules. Since I'm not a JS expert I'm unable to put the pieces together.
Just for some context, I'll post my code here:
<template>
<table class="sobject-table slds-table slds-table_cell-buffer slds-table_bordered">
<thead>
<tr class="slds-line-height_reset">
<template for:each={fieldSetData} for:item="field">
<th key={field.apiName} title={field.fieldLabel} class="" data-scope="col">
<div class="slds-truncate" title={field.fieldLabel}>{field.fieldLabel}</div>
</th>
</template>
</tr>
</thead>
<tbody>
<template for:each={records} for:item="row">
<tr key={row} class="slds-hint-parent">
<template for:each={row} for:item="data">
<td key={data.id} data-label="Name" data-scope="row">{data.value}</td>
</template>
</tr>
</template>
</tbody>
</table>
</template>
import {LightningElement, api, wire} from 'lwc';
import {processRecords} from 'c/recordGenerator';
import getFieldSetData from '@salesforce/apex/FieldSetData.getFieldSetData';
import getSobjectRecords from '@salesforce/apex/DeomoCTRL.getRecords';
import VanillaDatatable from '@salesforce/resourceUrl/VanillaDatatable';
import {loadScript, loadStyle} from 'lightning/platformResourceLoader';
export default class ManageSelectedIndicators extends LightningElement {
@api recordId;
records;
fieldSetData;
@wire(
getFieldSetData,
{objectName: 'SOBJECTName', fieldSet: 'FIELSETName'}
) wiredFieldSetData({error, data}) {
console.log('wired called in Child')
if (data) {
this.fieldSetData = data;
this.getData();
}
}
constructor() {
super();
console.log('Constructor called in Child');
}
connectedCallback() {
console.log('Connected callback');
}
renderedCallback() {
console.log('Rendered callback');
Promise.all([
loadScript(this, VanillaDatatable + '/VanillaDataTables/src/vanilla-dataTables.js')
]).then(() => {
const table = new DataTable(
document.getElementsByClassName('.sobject-table'),
//Also tried this.template.querySelector('.sobject-table'),
{searchable: true, sortable : true}
);
})
.catch(error => {
console.log(error);
});
}
getData() {
getSobjectRecords ({
sobjectId: this.recordId
})
.then(response => {
this.records= processRecords(response, this.fieldSetData);
})
.catch((error) => {
console.log(error);
});
}
}
Edit: I have also tried lwc:dom="manual"
that didn't seem to work either.
Is there any other way I could achieve these functionalities? Or do I have to write custom code to achieve this?