[SalesForce] Can we manipulate row selections in lightning:datatable

I'm trying to use lightning:datatable with row selection enabled, but also build a custom filter mechanism so that users can filter the records shown.
For example, filtering records by State.

I don't want the user's row selections to be cleared when they change filters, I want to remember them and reapply them as they change filters.

For example, if a user filtered rows based on the state "California" and selected some records, then changed the filter to "Nevada" and selected more records, and then went back to "California" (or "All"), all their previous selections would display again.

But since lightning:datatable doesn't seem to support any kind of filtering yet, I think I'd have to rebuild it's data attribute each time, which means I need to be able to store all the row selections myself and reset them as I rebuild the data based on the filters.

I think I can use the existing methods to get the list of selected rows, and store that off each time they change a filter. But I'm not finding a way to set row selections when they change filters, and I need to rebuild the data attribute.

Is it possible to set which records are initially selected when the data attribute is set with new data?

If not, I may have to abandon trying to use lightning:datatable in favor of something more robust, such as jQuery's DataTables, but I'd rather not do that, as I'd prefer to use a built-in Lightning component if possible.

Thanks for any guidance on this!

Best Answer

It's possible to preselect items, however I noticed a bug on API v42 (current version) and I confirmed that with SFDC support team. When using the attribute to bind the selected rows, it simply doesn't work, however if you find the lightning:datatable and then change the selectedRows, it works properly.

    component = component.find("partnerTable");
    component.set("v.selectedRows", selectedRowsIds);

Please find an example below, I'm creating a mockdata and selecting the first item by the Id.

Component

    <aura:attribute name="partnerdata" type="Object" access="private" />
    <aura:attribute name="partnercolumns" type="List" access="private" />
    <aura:attribute name="partnerSelectedRows" type="List" access="private" default="" />

    <!--
    <lightning:datatable aura:id="partnerTable" data="{!v.partnerdata}" 
    columns="{!v.partnercolumns}" keyField="Id" selectedRows="{!v.partnerSelectedRows}"/>
    -->

    <lightning:datatable aura:id="partnerTable" data="{!v.partnerdata}" 
    columns="{!v.partnercolumns}" keyField="Id" /> 

Controller

({
    doInit : function(component, event, helper) {
        helper.getMockData(component, event, helper);
    }
})

Helper

({
    getMockData: function(component, event) {
        console.log("Load mock data!");
        component.set("v.partnercolumns", [{
                label: "Name",
                fieldName: "Name",
                type: "text"
            },
            {
                label: "Status",
                fieldName: "status__c",
                type: "text"
            },
            {
                label: "Created Date",
                fieldName: "createdate__c",
                type: "date"
            }
        ]);
        component.set("v.partnerdata", [{
                Id: "a0319000001GtsjAAC",
                Name: "John Doe",
                status__c: "Active",
                createdate__c: "2005-01-01"
            },
            {
                Id: "a0319000001GtsjAAD",
                Name: "Mary Doe",
                status__c: "Active",
                createdate__c: "2005-02-10"
            }
        ]);

        var selectedRowsIds = ["a0319000001GtsjAAC"];

        // I was expecting the line below to work
        //component.set("v.partnerSelectedRows", selectedRowsIds);

        // Workaround to selectRows
        component = component.find("partnerTable");
        component.set("v.selectedRows", selectedRowsIds);

    }
})