Thursday, October 1, 2020

Dynamic table in LWC

Sometimes we come across scenarios when we need dynamic table where we have dynamic number of columns as well as rows.

One such was to display the Profiles with different users assigned to it in an org in Lightning Web Component (LWC).


pivotTable.html

<template>
    <div if:true={isLoading} class="cstm-spinner"> 
        <lightning-spinner alternative-text="Loading...">
        </lightning-spinner>
    </div>
    <div if:false={isLoading}>
        <table 
            class="slds-table slds-table_cell-buffer slds-table_bordered 
                    slds-max-medium-table_stacked-horizontal">
                   <thead>
                     <th class="" scope="col">
                       <div class="slds-truncate">
                        User
                        <lightning-icon if:false={val} 
                                icon-name="utility:down" 
                                size="x-small">
                        </lightning-icon>
                        /Profile
                        <lightning-icon if:false={val} 
                                icon-name="utility:right" 
                                size="x-small">
                        </lightning-icon></div>
                      </th>
                     <template for:each={profiles} for:item='prof' >
                       <th class="" scope="col" key={prof}>
                        <div class="slds-truncate" title={prof}>
                            {prof}
                        </div>
                        </th>
                      </template>
                      </thead>
                      <tbody>
                        <template for:each={users} for:item='user' >
                          <tr key={user.name}>
                            <td key={user.name} >
                                {user.name}
                            </td>
                            <template for:each={user.chex} for:item='val' >
                              <td class="" key={val} 
                                style="text-align: center;">
                                <lightning-icon if:true={val} 
                                    icon-name="utility:check" 
                                    variant="success" 
                                    size="small"></lightning-icon>
                                <lightning-icon if:false={val} 
                                    icon-name="utility:close" 
                                    variant="error" 
                                    size="xx-small"></lightning-icon>
                               </td>
                            </template>
                           </tr>
                          </template>
                       </tbody>
                     </table>
                    </div>
</template>

pivotTable.js

import { LightningElement } from 'lwc';
import getUserProfiles from '@salesforce/apex/pivotTableController.
                                getUserWithProfiles';

export default class PivotTable extends LightningElement {

    result = [];
    profiles = [];
    users = [];
    isLoading = true;

    connectedCallback(){
        getUserProfiles()
        .then(result =>{
            this.profiles = result[0].profiles;
            result.forEach(element => {
                this.users.push({
                    'chex' : element.isUserForProf,
                    'name' : element.userName
                });
            });
            this.isLoading = false;
        })
        .catch(error =>{
            console.log("error");
            this.isLoading = false;
        });
    }
}

pivotTableController.cls

public without sharing class pivotTableController {
    @AuraEnabled(cacheable=true)
    public static List<userProfWrappergetUserWithProfiles(){
        List<Userusers = [SELECT IdProfileIdProfile.Name
                            firstNamelastName, Name 
                            FROM User];
        List<Profileprofs = [SELECT IdName
                                      (SELECT Id,firstNamelastName 
                                       FROM Users
                               FROM Profile 
                               ORDER BY Name];
        List<userProfWrapperwrapperResult = new List<userProfWrapper>();
        List<Stringprofiles = new List<String>();
        for(User user : users){
            userProfWrapper wrapper = new userProfWrapper();
            List<Booleanbools = new List<Boolean>();
            String userName = '';
            for(Profile profile : profs){
                if(!profile.users.isEmpty()){
                    if(!profiles.contains(profile.Name))
                        profiles.add(profile.Name);
                    if(user.profileId == profile.Id)    
                        bools.add(true);
                    else    
                        bools.add(false);
                    userName = user.name;
                }
            }
            wrapper.isUserForProf = bools;
            wrapper.profiles = profiles;
            wrapper.userName = userName;
            wrapperResult.add(wrapper);
        }
        return wrapperResult;
    }

    public class userProfWrapper{
        @AuraEnabled
        public List<Stringprofiles;
        @AuraEnabled
        public List<BooleanisUserForProf;
        @AuraEnabled
        public String userName;
    }
}