fonteva-design-guide
Version:
## Dev, Build and Test
270 lines (242 loc) • 9.07 kB
JavaScript
import { LightningElement, api, track } from 'lwc';
import { fireEvent, cloneDeep, updateElementInArray } from 'c/actionutils';
import { registerListener, unregisterAllListeners } from 'c/pubsub';
import { loadStyle } from 'lightning/platformResourceLoader';
import BASE from '@salesforce/resourceUrl/PFM_Base';
export default class PfmTable extends LightningElement {
columns;
name;
selectedRows = [];
keyField;
showPager = false;
pageSize = 100;
numberOfRecords;
showRowNumberColumn = false;
suppressBottomBar = false;
hideCheckboxColumn = false;
resizeColumnDisabled = false;
allDataProvided = false;
sortedBy;
sortedDirection = 'asc';
defaultSortDirection = 'asc';
errors;
sortWithCurrentData = false;
backend = false;
maxRowSelection = 9999;
padding; // Deprecated;
draftValues = [];
loading = false;
tablePagedData;
numberOfPages;
dataSet = false;
currentPage = 0;
localDraftValues = [];
readOnly; // boolean. default: false
_tableData;
get tableData() {
return this._tableData;
}
set tableData(value) {
this._tableData = value;
this.updateTableData(value, this.currentPage, this.sortedBy, this.sortedDirection);
}
connectedCallback() {
this.loadDependentStyles();
if (this.backend) {
this.setAttribute('class', 'pfm-table_backend');
}
if (this.padding) console.log('Padding is deprecated. Custom Padding is no longer supported');
registerListener('ClearDraftValues', this.handleClearDraftValues, this);
registerListener('DatatablePicklistChanged', this.handleDatatablePicklistChanged, this);
}
get showPageSet() {
return this.showPager && this.numberOfPages != null && this.numberOfPages > 1;
}
selectRows(selectedRows) {
this.selectedRows = selectedRows;
}
setErrors(errors) {
this.errors = errors;
}
updateTableDataOnly(tableData) {
this.updateTableData(tableData, null);
}
updateTableData(tableData, currentPage, sortBy, sortDirection) {
if (sortBy) {
this.sortedBy = sortBy;
}
if (sortDirection) {
this.sortedDirection = sortDirection;
}
if (currentPage != null && currentPage > 0) {
currentPage--;
this.currentPage = currentPage;
}
if (tableData == null || (tableData && tableData.length === 0)) {
this.tablePagedData = [];
this._tableData = [];
this.calculatePages(0);
return;
}
this.dataSet = false;
this._tableData = cloneDeep(tableData);
this.processData();
if (this.showPageSet && currentPage != null) {
currentPage++;
const cPager = this.template.querySelector('c-pfm-pager');
if (cPager) {
cPager.numberOfPages = this.numberOfPages;
cPager.setCurrentPage(currentPage);
}
}
}
renderedCallback() {
if (this.dataSet) {
return;
}
this.processData();
if (this.readOnly) {
this.template.querySelector('.pfm-table').classList.add('js-read-only');
}
}
processData() {
if (this._tableData != null && this._tableData.length > 0) {
if (this.numberOfRecords != null) {
this.calculatePages(this.numberOfRecords);
} else if (this.allDataProvided) {
this.calculatePages(this._tableData.length);
}
if (!this.allDataProvided) {
this.dataSet = true;
this.tablePagedData = this._tableData;
} else if (this.allDataProvided) {
this.dataSet = true;
let splicedData = cloneDeep(this._tableData);
this.tablePagedData = splicedData.splice(this.currentPage, this.pageSize);
}
}
}
calculatePages(numberOfRecords) {
let pages = numberOfRecords / this.pageSize;
this.numberOfPages = parseInt(numberOfRecords % this.pageSize === 0 ? pages : pages + 1);
}
disconnectedCallback() {
unregisterAllListeners(this);
}
handleRowAction(evt) {
fireEvent(this, 'rowaction', { actionName: evt.detail.action.name, row: evt.detail.row });
}
handleSaveAction(evt) {
this.loading = true;
const recordInputs = evt.detail.draftValues.slice().map(draft => {
const fields = Object.assign({}, draft);
return { fields };
});
fireEvent(this, 'saveaction', { values: recordInputs });
}
handleSortAction(evt) {
let sortParams = {
fieldName: evt.detail.fieldName,
sortDirection: evt.detail.sortDirection
};
if (this.sortWithCurrentData) {
let newSortDirection = '';
if (this.sortedBy === sortParams.fieldName) {
if (this.sortedDirection === 'asc') {
newSortDirection = 'desc';
} else {
newSortDirection = this.defaultSortDirection;
}
} else {
newSortDirection = this.sortedDirection;
}
let sortDir = newSortDirection === 'asc' ? 1 : -1;
let tableDataCloned = cloneDeep(this.tableData);
tableDataCloned.sort(function (a, b) {
return a[sortParams.fieldName] > b[sortParams.fieldName] ? sortDir : -sortDir;
});
this.updateTableData(tableDataCloned);
this.sortedDirection = newSortDirection;
this.sortedBy = sortParams.fieldName;
this.template.querySelector('c-pfm-pager').setCurrentPage(1);
} else {
fireEvent(this, 'sortaction', sortParams);
}
}
handleClearDraftValues(evt) {
if (this.name === evt.name) {
this.draftValues = [];
this.localDraftValues = [];
this.loading = false;
}
}
toggleLoading() {
this.loading = false;
}
pageChanged(evt) {
let currentPage = parseInt(evt.detail.currentPage);
if (currentPage > 0) {
currentPage--;
}
if (this.allDataProvided) {
this.dataSet = true;
let splicedData = cloneDeep(this.tableData);
let currentPageSize = parseInt(this.pageSize);
this.tablePagedData = splicedData.splice(currentPage * currentPageSize, currentPageSize);
} else {
fireEvent(this, 'pagechanged', { currentPage: currentPage });
this.dataSet = false;
this.loading = true;
}
}
handleDatatablePicklistChanged(evt) {
if (evt.name === this.name) {
let draftObject = {};
draftObject[this.keyField] = evt.key;
draftObject[evt.fieldName] = evt.value;
if (this.draftValues == null) {
this.draftValues = [];
}
this.localDraftValues = updateElementInArray(this.localDraftValues, draftObject, this.keyField);
this.draftValues = cloneDeep(this.localDraftValues);
}
}
handleCancelAction() {
this.handleClearDraftValues({ name: this.name });
}
handleCellChange(evt) {
let self = this;
cloneDeep(evt.detail.draftValues).forEach(function (element) {
self.localDraftValues = updateElementInArray(self.localDraftValues, element, self.keyField);
});
}
handleRowSelection(evt) {
fireEvent(this, 'rowselection', { selectedRows: evt.detail.selectedRows });
}
handleValueChange(evt) {
// called when update comes from pfmTableCustomInput
// update the underlying data so when callers ask for it, it matches what's on-screen
this._tableData = this._tableData.map(td => {
if (td[this.keyField] === evt.detail.rowId) {
td[evt.detail.colId] = evt.detail.value;
}
return td;
});
}
loadDependentStyles() {
if (!window.pfmTableStylesLoaded) {
loadStyle(this, BASE + '/css/component/table/table.css');
window.pfmTableStylesLoaded = true;
}
if (!window.pfmTableReadOnlyStylesLoaded && this.readOnly) {
loadStyle(this, BASE + '/css/component/table/table-read-only.css');
window.pfmTableReadOnlyStylesLoaded = true;
}
}
}