[SalesForce] Lighting Data table : Capture header column width when changed

Is there a way to capture the width of columns(header) in data table when user changes the width? I am trying to persist the changes which user makes to the columns(width) after the table is loaded. Thanks.

Best Answer

You can use resize event on datatable. You will get the parameter columnWidths in event.

When width is changed, you can store the new widths in localStorage. You should stringify for storing because storage can store only strings. While loading again you can parse the array of widths and set.

Below is the sample:

<lightning:datatable keyField="id"
                     data="{! v.data }"
                     columns="{! v.columns }"
                     hideCheckboxColumn="true"
                     onresize="{! c.handleResize }"/>

controller js:

handleResize : function(component, event, helper){
    localStorage.setItem('datatableColumnWidths', JSON.stringify(event.getParam('columnWidths')));
},
init : function(component, event, helper){
    let columns = [
        {label: 'Name', fieldName: 'Name', type: 'text'},
        {label: 'Title', fieldName: 'Title', type: 'text'},
        {label: 'Phone', fieldName: 'Phone', type: 'phone'},
        {label: 'Email', fieldName: 'Email', type: 'email'},
        {label: 'CreatedDate', fieldName: 'Created Date', type: 'date'}
    ];

    if(localStorage.getItem('datatableColumnWidths')) {
        if(Array.isArray(JSON.parse(localStorage.getItem('datatableColumnWidths')))) {
            let columnWidths = JSON.parse(localStorage.getItem('datatableColumnWidths'));
            columns = columns.map(function(col, ind) {
                col.initialWidth = columnWidths[ind];
                return col;
            });
        } else {
            localStorage.removeItem('datatableColumnWidths');
            alert('widths not stored properly. Pls contact admin'); // show toast
        }
    }

    component.set("v.columns", columns);

    var action = component.get("c.getContactList");
    action.setCallback(this, function(response){
        console.log('response.getReturnValue() ',response.getReturnValue());
        component.set("v.data",response.getReturnValue());
    });
    $A.enqueueAction(action);
}

NOTE:

Notice the check if stored widths are array or not. If its not array clear that item in storage and ask user to contact admin as the implementation is not correct.