function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
eptrainingeptraining 

<lightning:datatable> can't be used in <lightning:tab>?

I've just tried to create a lightning tab component that simple contains just a <lightning:tabset> and in each of the tabs a <lightning:datatable> component. Data from server is rendered absolutely fine, the problem is that only in first tab column resizing works as expected. The tables in the rest of tabs have a weird behaviour (even the column divider is not displayed properly).
Did anyone else have the same experience?

Also I expected the "number" columns to be right aligned - does anyone know how to change style for columns using <lightning:datatable>?
Thank you!
 
PrabhaPrabha
Hi,

Sharing your code helps us help you... please share your code and highlight your challenge. it gets the quickest response.

did you try with attributes and expressions ?
​https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_aura_expression.htm?search_text=datatable
-- 

PrabhaN
eptrainingeptraining
It's not exactly easy to build all pieces, but here you go. I think that someone can help only if he/she tried something similar before. I'm sure that if the question would have been for VisualForce, many developers tried this type of page before. My question is specifically on these "new" components: <lightning:tab>, <lightning:datatable>, not about obtaining the same functionality using some other (more simple) aura components.
Once again: all data is displayed fine, sorting works fine, column resizing DOESN'T work correct (except for the table in the first tab, where is ok).
Thank you for trying to help!


The server method is working fine returning:
@AuraEnabled
    public static Map<String, Object> getData()
    {
        Map<string, Object> returnValue = new Map<string, Object>();
        ///data is selected from custom object and loaded into returnValue
        return returnValue;
    } 
The component code is:
==================
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes" controller="LTController_TyDash" >
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="avgColumns" type="List"/>
    <aura:attribute name="stColumns" type="List"/>
    <aura:attribute name="accAvg" type="Object"/>
    <aura:attribute name="accNew" type="Object"/>
    <aura:attribute name="accWor" type="Object"/>
    <aura:attribute name="accDis" type="Object"/>
    
    
    <!-- PAGE HEADER -->
    <div class="slds-page-header slds-page-header_object-home">
        <lightning:layout >
            <lightning:layoutItem >
                <lightning:icon iconName="standard:business_hours" />
            </lightning:layoutItem>
            <lightning:layoutItem class="slds-m-left_small">
                <p class="slds-text-title_caps slds-line-height_reset">XXXX</p>
                <h1 class="slds-page-header__title slds-p-right_x-small">Activities Dashboard</h1>
            </lightning:layoutItem>
        </lightning:layout>
    </div>        
    
    <div class="slds-grid slds-wrap slds-grid_pull-padded">
          <div class="slds-p-horizontal_small slds-size_1-of-1">
            <lightning:tabset variant="scoped">
                <lightning:tab label="PROSPECT STAGES (AVERAGES)" id="avg" >                   
                    <lightning:datatable data="{! v.accAvg}" aura:id="accAvg"  
                       columns="{! v.avgColumns}" 
                       keyField="name"                       
                       onsort="{! c.updateColumnSorting}"                                 
                       sortedBy="name"
                       sortedDirection="asc"
                       defaultSortDirection="asc"
                       hideCheckboxColumn="true"/>                           
                </lightning:tab>
        <lightning:tab label="SUSPECTS - NET NEW" id="new" >
            <lightning:datatable data="{! v.accNew}" aura:id="accNew"  
                       columns="{! v.stColumns}" 
                       keyField="account"
                       onsort="{! c.updateColumnSorting}"               
                       sortedBy="owner"
                       sortedDirection="asc"
                       defaultSortDirection="asc"
                       hideCheckboxColumn="true"/>    
        </lightning:tab>
        <lightning:tab label="SUSPECTS - WORKING" id="wor" >
            <lightning:datatable data="{! v.accWor}" aura:id="accWor"  
                       columns="{! v.stColumns}" 
                       keyField="account"
                       onsort="{! c.updateColumnSorting}"               
                       sortedBy="owner"
                       sortedDirection="asc"
                       defaultSortDirection="asc"
                       hideCheckboxColumn="true"/>
        </lightning:tab>
        <lightning:tab label="PROSPECTS - MI SET (DISCOVERY)" id="dis" >
            <lightning:datatable data="{! v.accDis}" aura:id="accDis"  
                       columns="{! v.stColumns}" 
                       keyField="account"
                       onsort="{! c.updateColumnSorting}"               
                       sortedBy="owner"
                       sortedDirection="asc"
                       defaultSortDirection="asc"
                       hideCheckboxColumn="true"/>
        </lightning:tab>
    </lightning:tabset> 
        </div>
    </div>
</aura:component> 

Controller code:
============
({
    doInit : function(component, event, helper) {
        helper.loadData(component);
    },
    updateColumnSorting : function(component, event, helper) {    
        
        console.info('>>event ', event.getSource().getLocalId());
        var tableId = event.getSource().getLocalId();
        
        var fieldName = event.getParam('fieldName');
        var sortDirection = event.getParam('sortDirection');        
        var avgT = component.find(tableId);
        avgT.set("v.sortedBy", fieldName);
        avgT.set("v.sortedDirection", sortDirection);
        helper.sortData(component, tableId, fieldName, sortDirection);
    }
})

Helper code:
===========
({
    loadData : function(component) {
        var action = component.get("c.getData");        
        action.setCallback(this, function (result) {
            var state = result.getState();
            if (state !== "SUCCESS") {
                console.info('>> getting daa was not successful:', result);
                return;
            }
            var data = result.getReturnValue();                        
            console.info('>> oninit data:', data);
            
            component.set("v.avgColumns", [
                    {label: "SALES REP NAME", fieldName:"name", type:"text", sortable: "true"},
                    {label: "#DAYS in NET NEW (average)", fieldName:"avgNew", type:"number", sortable: "true"},
                    {label: "#DAYS in WORKING (average)", fieldName:"avgWor", type:"number", sortable: "true"},
                    {label: "#DAYS in MI SET (average)", fieldName:"avgDis", type:"number", sortable: "true"},
                    {label: "#DAYS in PIPELINE (average)", fieldName:"avgPip", type:"number", sortable: "true"},
                   
                ]);
            component.set("v.stColumns", [
                    {label: "ACCOUNT NAME", fieldName:"account", type:"text", sortable: "true"},
                    {label: "Account OWNER", fieldName:"owner", type:"text", sortable: "true"},
                    {label: "#ACTIVITIES SINCE ASSIGNED to OWNER", fieldName:"cnt", type:"number", sortable: "true"},
                    {label: "#ACTIVITIES LAST 14 DAYS", fieldName:"cnt14", type:"number", sortable: "true"},
                    {label: "ACCOUNT STAGE", fieldName:"stage", type:"text", sortable: "true"},
                    {label: "#DAYS IN CURRENT STAGE", fieldName:"cntcrt", type:"number", sortable: "true"}
                ]);
                
            component.set("v.accAvg", data.t1);
            component.set("v.accNew", data.tn);
            component.set("v.accWor", data.tw);
            component.set("v.accDis", data.td);
        
        });
        $A.enqueueAction(action);
    },
    sortData: function (component, tableId, fieldName, sortDirection) {        
        var data = component.get("v." + tableId);
        var reverse = sortDirection !== 'asc';
        //sorts the rows based on the column header that's clicked
        data.sort(this.sortBy(fieldName, reverse))
        component.set("v." + tableId, data);
    },
    sortBy: function (field, reverse, primer) {
        var key = primer ?
            function(x) {return primer(x[field])} :
            function(x) {return x[field]};
        //checks if the two rows should switch places
        reverse = !reverse ? 1 : -1;
        return function (a, b) {
            return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
        }
    }
})
PrabhaPrabha
I've run your code, the second and other tabs are not getting the same styling as the first one, I blame parent nodes. I see it as a reportable bug. Please create a case with salesforce, this will help all of our developer get that clean.

Remember this is still a Beta feature, it is risky to get to prod as Beta.

If you still want to get around this, here is my workaround:
  1. Create multiple divs for each tabs below/outside the <lightning:tabset> have different ids for each div
  2. Add your tables under each div.
  3. call JScontroller to hide and show the divs by using "onactive" attribute of lightning:tab   Ex: <lightning:tab label="PROSPECT STAGES (AVERAGES)" id="avg" onactive="{!c.tabactivated}"> 
This should get you going.

And for number being right-aligned, I think we can use custom CSS class, I'll try that tomorrow and let you know,

Peace \\//
PrabhaN
eptrainingeptraining
Thank you so much for your answer! Big surprise this morning, sandbox was upgraded over the weekend and the tabs with grids work as expected without any change! Salesforce fixed the beta components (at least the columns resizing of table columns in each tab :)) Still there are things I would like to have in datatable (style per column customization, link type columns, etc.) I'll check latest documentation to see if there are any new features.