About this question
I have created a Custom LWC Datatable following Creating Custom Data Types in Salesforce Documentation. My Custom LWC cell component as below,
and it's Javascript Controller as below,
import { LightningElement, track, api } from 'lwc'; export default class invoiceCustomAction extends LightningElement { handlePayNow(event){ console.log('test A'); //console.log('value '+ this.value); } handleDownload(event){ console.log('test B'); //console.log('download '+ this.value); } }
My Custom Data table component as below: Markup
JS Controller
import LightningDatatable from 'lightning/datatable'; import invoiceCustomAction from './invoiceCustomAction.html'; export default class test_InvoicesCustomDatatable extends LightningDatatable { static customTypes = { customInvoiceCell: { template: invoiceCustomAction, standardCellLayout: true // Provide template data here if needed } //more custom types here }; }Consumer code:
component markup:
<!--<!-- -->
JS Controller
import { LightningElement,track,api } from 'lwc'; import FORM_FACTOR from '@salesforce/client/formFactor'; import getInvoices from '@salesforce/apex/Test_InvoiceListController.getInvoices'; const columns = [ { label: 'Date issued', fieldName: 'issueDate', type: 'date', sortable : true }, { label: 'Account', fieldName: 'accountNo' , sortable : true, type: 'text'}, { label: 'Invoice #', fieldName: 'invoiceNo', sortable : true, type: 'text'}, { label: 'Date due by', fieldName: 'dueDate', type: 'date', sortable : true }, { label: 'Amount', fieldName: 'amount', type: 'currency', sortable : true }, { label: 'Status', fieldName: 'status', sortable : true, type: 'text'}, { label: 'Action', type: 'customInvoiceCell', fieldName: 'index'} ]; export default class Test_InvoiceList_Outstanding extends LightningElement { @track idw = {listIW:[]}; // Invoices Display Wrapper Object @track page = 1; // Current Page number @api perpage = 10; // Records per Page @track pages = []; // Page numbers array set_size = 3; // Number of Page number buttons @track numberOfPages = 1; // Number of pages to show @track sortedBy = 'accountNo'; // Sort field @track sortDirection = 'asc'; // Sort direction @track isLoading = true; // Loading UI @track searchText = ''; // Search text @track filteredResults = [] // Filtered Invoice wrappers displayed on Datatable,etc. @track pageStartIdx = 0; // Page start record index @track pageEndIdx = 0; // Page end record index @track searchTextPlaceHolder = 'Search by keyword, name'; // Search Text Place holder @track selectedRows = []; // Current page's row selection @track allSelectedRows = new Map(); // PageNo => Selected row Ids[] map to keep persistent selection in paginated data table mapPage2SelIdx = new Map() navRefresh = false; renderedCallback(){ this.columns = columns; this.renderButtons(); } renderButtons = ()=>{ this.template.querySelectorAll('button').forEach((but)=>{ but.style.backgroundColor = this.page===parseInt(but.dataset.id,10)?'blue':'white'; }); } get pagesList(){ let mid = Math.floor(this.set_size/2) + 1 ; if(this.page > mid){ if (this.page==(this.pages.length)) // Last page return this.pages.slice(this.page-mid-1, this.page+mid-1); else return this.pages.slice(this.page-mid, this.page+mid-1); } return this.pages.slice(0,this.set_size); } async connectedCallback(){ this.isLoading = true; this.idw = await getInvoices(); if (this.idw!=null && this.idw.listIW!=null) this.filteredResults = this.idw.listIW.slice(0); this.isLoading = false; this.setPages(this.filteredResults); } pageData = ()=>{ let page = this.page; let perpage = this.perpage; let startIndex = (page*perpage) - perpage; let endIndex = (page*perpage); this.pageStartIdx = startIndex + 1; this.pageEndIdx = (endIndex > this.filteredResults.length) ? this.filteredResults.length : endIndex; return this.filteredResults.slice(startIndex,endIndex); } setPages = (data)=>{ this.page = 1; this.pages = []; this.numberOfPages = Math.ceil(data.length / this.perpage); for (let index = 1; index <= this.numberOfPages; index++) { this.pages.push(index); } } get hasPrev(){ return this.page > 1; } get hasNext(){ return this.page < this xss=removed>{ this.navRefresh = true; ++this.page; } onPrev = ()=>{ this.navRefresh = true; --this.page; } onPageClick = (e)=>{ this.navRefresh = true; this.page = parseInt(e.target.dataset.id,10); } get currentPageData(){ this.selectedRows = this.selectedRows.splice(0); return this.pageData(); } get currentSelection(){ let selectedRecs = this.mapPage2SelIdx.get(this.page); if (!Array.isArray(selectedRecs)) selectedRecs = []; return selectedRecs; } updateColumnSorting(event) { this.sortedBy = event.detail.fieldName; this.sortDirection = event.detail.sortDirection; this.sortData(this.sortedBy); } sortData(sortedBy){ var data = this.filteredResults; var reverse = this.sortDirection !== 'asc'; data.sort(this.sortBy(sortedBy, reverse)); this.filteredResults = data; } sortBy(field, reverse, primer) { var key = primer ? function(x) {return primer(x[field])} : function(x) {return x[field]}; reverse = !reverse ? 1 : -1; return function (a, b) { return a = key(a), b = key(b), reverse * ((a > b) - (b > a)); } } handleFilterChange(event) { } onRowSelection(event){ } }
On the custom datatable component cell, when you click any button/url except the one having event handler, it's throwing the below error.
Any help to understand what it means? And how to resolve typeerror: cannot read property 'apply' of undefined? what could be missing in the custom LWC component? Thanks!