[SalesForce] Re-Evaluating Selected-Rows in Lightning-Datatable When Data Changed

I've been stuck on this issue for a few hours now and don't seem to be getting any closer to resolving it.

I currently have a Lightning-Datatable with pagination that renders 20 rows at a time. When the user clicks the next or previous page button it swaps out the data for the next 20 records. This is working fine.

When the table loads for the first time, my 'selected-rows' array is being read and the correct rows are ticked. However, when jumping to the next page and changing the data source, the datatable stops rendering any selected-row values even though it is in the list. If I jump back to the first page (which originally had checked rows) the rows remain unchecked.

I have tried updating both the selected-rows and data values to force the pages to refresh but I've had no luck. Do you know why this may be and how I can resolve this matter?


My Datatable

<lightning-datatable
    key-field="Id"
    data={homes}
    columns={columns}
    selected-rows={selectedRows}
    onsort={sortColumns}
    sorted-by={sortField} 
    sorted-direction={sortDirection}
    hide-checkbox-column={hideCheckboxes}
    resize-column-disabled=true>
</lightning-datatable>

My JS

export default class HomesList extends LightningElement {
    @api recordId;

    @track columns = columns;
    @track homes = [];
    @track tableLoadingState = true;
    @track isEditing = false;
    @track totalPages = 1;
    @track jumpToPageNum = 1;

    selectedIds = [];
    sortField = "Name";
    sortDirection = "asc";
    pageNum = 1;

    get selectedRows() {
        if (this.isEditing) {
            return this.selectedIds;
        }
        return [];
    }

    get hideCheckboxes() {
        return !this.isEditing;
    }

    get getPageNum() {
        return this.pageNum + " / " + this.totalPages;
    }

    get hasNextPage() {
        return this.pageNum >= this.totalPages;
    }

    get hasPreviousPage() {
        return this.pageNum <= 1;
    }

    connectedCallback() {
        this.getSelectedHomes();
        this.getHomes();
    }

    sortColumns(event) {
        this.sortField = event.detail.fieldName;
        this.sortDirection = event.detail.sortDirection;
        this.getHomes();
    }

    toggleEdit() {
        this.isEditing = !this.isEditing;
        this.pageNum = 1;
        this.getHomes();
    }

    getFirstPage() {
        this.pageNum = 1;
        this.getHomes();
    }

    getNextPage() {
        this.pageNum++;
        this.getHomes();
    }

    getPreviousPage() {
        this.pageNum--;
        this.getHomes();
    }

    getLastPage() {
        this.pageNum = this.totalPages;
        this.getHomes();
    }

    getHomes() {
        this.tableLoadingState = true;
        getHomes({ contractId: this.recordId, isEditing: this.isEditing, sortField : this.sortField, sortDirection : this.sortDirection, pageNum : this.pageNum})
            .then(result => {
                this.totalPages = Object.keys(result)[0];
                this.homes = Object.values(result)[0];
                this.error = undefined;
                this.tableLoadingState = false;     
            })
            .catch(error => {
                this.error = error;
                this.homes = undefined;
                this.totalPages = 1;
                this.tableLoadingState = false;
            });
    }

    getSelectedHomes() {
        getSelectedHomes({ contractId: this.recordId })
            .then(result => {
                this.selectedIds = result;
                this.error = undefined;
            })
            .catch(error => {
                this.error = error;
                this.selectedIds = [];
            });
    }
}

My Controller

@AuraEnabled
public static List<Id> getSelectedHomes(String contractId) {
    String query = 'SELECT Homes__c FROM Contract_Home__c WHERE Contract__c = \'' + contractId + '\' LIMIT 10000';
    List<Contract_Home__c> contractHomes = Database.query(query);

    List<Id> selectedHomes = new List<Id>();
    for (Contract_Home__c contractHome : contractHomes) {
        selectedHomes.add(contractHome.Home__c);
    }

    return selectedHomes;
}

Thanks!

Best Answer

There is no two-way binding, the rows you selected won't be in selected-rows={selectedRows} . You have use onrowselection attribute on datatable.

<lightning-datatable
        key-field="Id"
        data={homes}
        columns={columns}
        selected-rows={selectedRows}
        onsort={sortColumns}
        sorted-by={sortField}
        sorted-direction={sortDirection}
        hide-checkbox-column={hideCheckboxes}
        onrowselection={getSelectedName}>
        resize-column-disabled=true>
</lightning-datatable>

and in JS store it somewhere like :

getSelectedName(event) {
            const selectedRows = event.detail.selectedRows;

            for (let i = 0; i < selectedRows.length; i++){
                 if (!selectedId.includes(selectedRows[i].Id))
                 selectedId.push(selectedId);
            }


        }
Related Topic