├── .gitattributes
├── force-app
└── main
│ └── default
│ ├── lwc
│ ├── .eslintrc.json
│ ├── lightningDataTable
│ │ ├── lightningDataTable.html
│ │ ├── lightningDataTable.js
│ │ └── lightningDataTable.js-meta.xml
│ └── jsconfig.json
│ └── classes
│ ├── LightningDataTableController.cls-meta.xml
│ └── LightningDataTableController.cls
├── .prettierignore
├── .vscode
├── extensions.json
├── settings.json
└── launch.json
├── config
└── project-scratch-def.json
├── sfdx-project.json
├── .prettierrc
├── .forceignore
├── .gitignore
├── manifest
└── package.xml
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/force-app/main/default/lwc/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@salesforce/eslint-config-lwc/recommended"]
3 | }
4 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running prettier
2 | # More information: https://prettier.io/docs/en/ignore.html
3 | #
4 |
5 | .sfdx
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "salesforce.salesforcedx-vscode",
4 | "redhat.vscode-xml",
5 | "dbaeumer.vscode-eslint",
6 | "esbenp.prettier-vscode"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/config/project-scratch-def.json:
--------------------------------------------------------------------------------
1 | {
2 | "orgName": "Demo Company",
3 | "edition": "Developer",
4 | "features": [],
5 | "settings": {
6 | "orgPreferenceSettings": {
7 | "s1DesktopEnabled": true
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "force-app",
5 | "default": true
6 | }
7 | ],
8 | "namespace": "",
9 | "sfdcLoginUrl": "https://login.salesforce.com",
10 | "sourceApiVersion": "46.0"
11 | }
12 |
--------------------------------------------------------------------------------
/force-app/main/default/lwc/lightningDataTable/lightningDataTable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/LightningDataTableController.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 46.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "none",
3 | "overrides": [
4 | {
5 | "files": "**/lwc/**/*.html",
6 | "options": { "parser": "lwc" }
7 | },
8 | {
9 | "files": "*.{cmp,page,component}",
10 | "options": { "parser": "html" }
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "salesforcedx-vscode-core.push-or-deploy-on-save.enabled": false,
3 | "search.exclude": {
4 | "**/node_modules": true,
5 | "**/bower_components": true,
6 | "**/.sfdx": true
7 | },
8 | "eslint.nodePath": "c:\\Users\\Phill\\.vscode\\extensions\\salesforce.salesforcedx-vscode-lwc-46.11.0\\node_modules"
9 | }
10 |
--------------------------------------------------------------------------------
/.forceignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
2 | # More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
3 | #
4 |
5 | package.xml
6 |
7 | # LWC configuration files
8 | **/jsconfig.json
9 | **/.eslintrc.json
10 |
11 | # LWC Jest
12 | **/__tests__/**
--------------------------------------------------------------------------------
/force-app/main/default/lwc/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "experimentalDecorators": true,
4 | "baseUrl": ".",
5 | "paths": {
6 | "c/lightningDataTable": [
7 | "lightningDataTable/lightningDataTable.js"
8 | ]
9 | }
10 | },
11 | "include": [
12 | "**/*",
13 | "../../../../.sfdx/typings/lwc/**/*.d.ts"
14 | ],
15 | "typeAcquisition": {
16 | "include": [
17 | "jest"
18 | ]
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Launch Apex Replay Debugger",
9 | "type": "apex-replay",
10 | "request": "launch",
11 | "logFile": "${command:AskForLogFileName}",
12 | "stopOnEntry": true,
13 | "trace": true
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # This file is used for Git repositories to specify intentionally untracked files that Git should ignore.
2 | # If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore
3 | # For useful gitignore templates see: https://github.com/github/gitignore
4 |
5 | # Salesforce cache
6 | .sfdx/
7 |
8 | # Logs
9 | logs
10 | *.log
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 |
15 | # Dependency directories
16 | node_modules/
17 |
18 | # Eslint cache
19 | .eslintcache
20 |
21 | # MacOS system files
22 | .DS_Store
23 |
24 | # Windows system files
25 | Thumbs.db
26 | ehthumbs.db
27 | [Dd]esktop.ini
28 | $RECYCLE.BIN/
--------------------------------------------------------------------------------
/manifest/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | *
5 | ApexClass
6 |
7 |
8 | *
9 | ApexComponent
10 |
11 |
12 | *
13 | ApexPage
14 |
15 |
16 | *
17 | ApexTestSuite
18 |
19 |
20 | *
21 | ApexTrigger
22 |
23 |
24 | *
25 | AuraDefinitionBundle
26 |
27 |
28 | *
29 | LightningComponentBundle
30 |
31 |
32 | *
33 | StaticResource
34 |
35 | 46.0
36 |
--------------------------------------------------------------------------------
/force-app/main/default/lwc/lightningDataTable/lightningDataTable.js:
--------------------------------------------------------------------------------
1 | import { LightningElement, wire, track, api } from 'lwc';
2 | import getSobjectRecords from '@salesforce/apex/LightningDataTableController.getSobjectRecords'
3 |
4 | export default class LightningDataTable extends LightningElement {
5 | @track mydata;
6 | @track mycolumns;
7 | @track error;
8 | @api sObjectName;
9 | @api fieldSetName;
10 | @api recordId = '';
11 | @api sObjectLookupIDField = '';
12 | @api additionalWhereClause = '';
13 |
14 | @wire(getSobjectRecords,({
15 | sObjectName : '$sObjectName',
16 | fieldSetName : '$fieldSetName',
17 | recordId : '$recordId',
18 | sObjectLookupIDField : '$sObjectLookupIDField',
19 | additionalWhereClause : '$additionalWhereClause',
20 | }))
21 | wiredAccounts({error, data}){
22 | if(data){
23 | this.mycolumns = data.listColumns;
24 | this.mydata = data.dataTableData;
25 | this.error = undefined;
26 | }else if(error){
27 | this.error = error;
28 | this.mydata = undefined;
29 | this.mycolumns = undefined;
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/force-app/main/default/lwc/lightningDataTable/lightningDataTable.js-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 46.0
4 | true
5 | LWC Data Table
6 |
7 | lightning__HomePage
8 | lightning__AppPage
9 | lightning__RecordPage
10 | lightningCommunity__Default
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Salesforce Lightning Web Component table that can be used in the Lightning App Builder or Community Builder and is driven off of a field set and object API name.
2 |
3 | # Types of Lists
4 | * List
5 | * a list of any records in the system
6 | * provide the Sobject API name and Field Set name
7 | * Related List
8 | * a list of any related records to a parent record
9 | * provide the Sobject API name, Field Set name, and Sobject Lookup Field API Name
10 | * Filtered List
11 | * a list of any records filted by a SOQL WHERE statement
12 | * provide the Sobject API name, Field Set name, and Additional Where Clause
13 | * Filtered Related List
14 | * a list of filtered related records to a parent record
15 | * Rendered if all attributes are filled out
16 |
17 | # Configure Components
18 | ## Drag Components onto a page
19 | This component works on app pages, record pages, home pages, and community pages.
20 |
21 | Here is a table breakdown of what lists work on what pages:
22 |
23 | | | App Pages | Record Pages | Home Pages | Community Pages |
24 | |:-:|:-:|:-:|:-:|:-:|
25 | | Lists | X | | X | X |
26 | | Related Lists | X | X | X | X |
27 | | Filtered Lists | X | X | X | X |
28 | | Filtered Related Lists | X | X | X | X |
29 |
30 | # Edit the attributes
31 | * Object API Name - The API name of the object where the layout was placed (Community Record Page only)
32 | * Field Set API Name - API name of the field set on the Object API Name
33 | * sObject Lookup Field API Name - API name of the sObject field used in a lookup or master-detail relationship
34 | * sObject API Name ==> sObject Lookup Field API Name
35 | * Contact ==> AccountId
36 | * Contact ==> AccountId
37 | * Opportunity ==> AccountId
38 | * (Additional) WHERE Clause in SOQL Query - optional filtering statement for WHERE clause in SOQL queries
39 |
40 | # Example Uses
41 | 
42 | 
43 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/LightningDataTableController.cls:
--------------------------------------------------------------------------------
1 | public with sharing class LightningDataTableController {
2 | /*
3 | Created by Phill Drum
4 | Purpose: Create a lightning-datatable based on configuration inputs to create lists, related lists, filtered lists, and filtered related lists.
5 | Based off of http://sfdcmonkey.com/2018/01/05/lightning-datatable-base-component/
6 | */
7 | @AuraEnabled(cacheable=true)
8 | public static DataTableResponse getSobjectRecords(String sObjectName, String fieldSetName, String sObjectLookupIDField, String additionalWhereClause, String recordId){
9 |
10 | //Get the fields from FieldSet
11 | Schema.SObjectType SObjectTypeObj = Schema.getGlobalDescribe().get(sObjectName);
12 | Schema.DescribeSObjectResult DescribeSObjectResultObj = SObjectTypeObj.getDescribe();
13 | Schema.FieldSet fieldSetObj = DescribeSObjectResultObj.FieldSets.getMap().get(fieldSetName);
14 |
15 | //List to hold table headers
16 | List lstDataColumns = new List();
17 |
18 | //Fields to be queried from fieldset
19 | List lstFieldsToQuery = new List();
20 |
21 | //Final wrapper response to return to component
22 | DataTableResponse response = new DataTableResponse();
23 |
24 | for( Schema.FieldSetMember eachFieldSetMember : fieldSetObj.getFields() ){
25 | String dataType = String.valueOf(eachFieldSetMember.getType()).toLowerCase();
26 | //This way we can set the type of a column
27 | //We do not get the exact type from schema object which matches to lightning-datatable component structure
28 | if(dataType == 'datetime'){
29 | dataType = 'date';
30 | }
31 | //Create a wrapper instance and store label, fieldname and type.
32 | DataTableColumns datacolumns = new DataTableColumns( String.valueOf(eachFieldSetMember.getLabel()) ,
33 | String.valueOf(eachFieldSetMember.getFieldPath()),
34 | String.valueOf(eachFieldSetMember.getType()).toLowerCase() );
35 | lstDataColumns.add(datacolumns);
36 | lstFieldsToQuery.add(String.valueOf(eachFieldSetMember.getFieldPath()));
37 | }
38 |
39 | //SOQL Queries for different lists: lists, related lists, filtered lists, and filtered related lists
40 | String query = '';
41 | if(!lstDataColumns.isEmpty() && String.isEmpty(recordId) && String.isEmpty(additionalWhereClause) && String.isEmpty(sObjectLookupIDField)){
42 | //List
43 | query = 'SELECT Id, ' + String.join(lstFieldsToQuery, ',') +
44 | ' FROM ' + sObjectName;
45 | System.debug(query);
46 | }else if (! lstDataColumns.isEmpty() && String.isEmpty(additionalWhereClause)){
47 | //Related List
48 | query = 'SELECT Id, ' + String.join(lstFieldsToQuery, ',') +
49 | ' FROM ' + sObjectName +
50 | ' WHERE ' + sObjectLookupIDField + ' = \'' + recordId + '\'';
51 | }
52 | else if (! lstDataColumns.isEmpty() && String.isEmpty(recordId)){
53 | //Filtered List
54 | query = 'SELECT Id, ' + String.join(lstFieldsToQuery, ',') +
55 | ' FROM ' + sObjectName +
56 | ' WHERE ' + additionalWhereClause;
57 | }
58 | else{
59 | //Filtered Related List
60 | query = 'SELECT Id, ' + String.join(lstFieldsToQuery, ',') +
61 | ' FROM ' + sObjectName +
62 | ' WHERE ' + sObjectLookupIDField + '= \'' + recordId + '\''+
63 | ' AND '+ additionalWhereClause;
64 | }
65 | response.dataTableData = Database.query(query);
66 | response.listColumns = lstDataColumns;
67 | return response;
68 | }
69 |
70 | //Wrapper class to hold Columns with headers
71 | public class DataTableColumns {
72 | @AuraEnabled
73 | public String label {get;set;}
74 | @AuraEnabled
75 | public String fieldName {get;set;}
76 | @AuraEnabled
77 | public String type {get;set;}
78 |
79 | //Create and set variables required by lightning-datatable (label, fieldname, and type)
80 | public DataTableColumns(String label, String fieldName, String type){
81 | this.label = label;
82 | this.fieldName = fieldName;
83 | this.type = type;
84 | }
85 | }
86 |
87 | //Wrapper calss to hold response
88 | public class DataTableResponse {
89 | @AuraEnabled
90 | public List listColumns {get;set;}
91 | @AuraEnabled
92 | public List dataTableData {get;set;}
93 |
94 | public DataTableResponse(){
95 | listColumns = new List();
96 | dataTableData = new List();
97 | }
98 | }
99 | }
--------------------------------------------------------------------------------