Skip to content

Commit f6d152c

Browse files
committed
Init commit
1 parent 84e702a commit f6d152c

File tree

5 files changed

+292
-0
lines changed

5 files changed

+292
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
public with sharing class RelatedList {
2+
@AuraEnabled public static List<SObject> getRecords(String soql) {
3+
System.debug('soql::' + soql);
4+
return Database.query(soql);
5+
}
6+
7+
@AuraEnabled(cacheable = true) public static Integer countRecords(String objectName) {
8+
if(String.isNotEmpty(objectName)) {
9+
return database.countQuery('SELECT count() FROM ' + objectName);
10+
}
11+
return 0;
12+
}
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<apiVersion>48.0</apiVersion>
4+
<status>Active</status>
5+
</ApexClass>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<template>
2+
<div style="height: 300px;">
3+
<lightning-card variant="Narrow" title={title} icon-name={iconName}>
4+
<lightning-button label="New" title="Non-primary action" onclick={newRecord} class="slds-m-left_x-small"
5+
slot="actions"></lightning-button>
6+
<template if:true={data}>
7+
<lightning-datatable key-field="id" data={data} columns={columns} onrowaction={handleRowAction} hide-checkbox-column >
8+
</lightning-datatable>
9+
</template>
10+
<div slot="footer" style="text-align: right;">
11+
<lightning-button variant="brand" disabled={isDisablePrev} label="First" title="Primary action" onclick={firstPage}
12+
class="slds-m-left_xx-small"></lightning-button>
13+
<lightning-button variant="brand" disabled={isDisablePrev} label="Previous" title="Primary action" onclick={previous}
14+
class="slds-m-left_xx-small"></lightning-button>
15+
<lightning-button variant="brand" disabled={isDisableNext} label="Next" title="Primary action" onclick={next}
16+
class="slds-m-left_xx-small"></lightning-button>
17+
<lightning-button variant="brand" disabled={isDisableNext} label="Last" title="Primary action" onclick={lastPage}
18+
class="slds-m-left_xx-small slds-m-right_xx-small"></lightning-button>
19+
</div>
20+
</lightning-card>
21+
</div>
22+
</template>
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
import { LightningElement, wire, track, api } from "lwc";
2+
import { NavigationMixin } from "lightning/navigation";
3+
import { deleteRecord } from "lightning/uiRecordApi";
4+
import { ShowToastEvent } from "lightning/platformShowToastEvent";
5+
import getRecords from "@salesforce/apex/RelatedList.getRecords";
6+
import countRecords from "@salesforce/apex/RelatedList.countRecords";
7+
// import deleteRecord from "@salesforce/apex/RelatedList.deleteRecord";
8+
9+
let cols;
10+
const actions = [
11+
{ label: "Show details", name: "show_details" },
12+
{ label: "Edit", name: "edit" },
13+
{ label: "Delete", name: "delete" }
14+
];
15+
export default class LightningDatatable extends NavigationMixin(
16+
LightningElement
17+
) {
18+
// Public Property
19+
@api recordId;
20+
@api iconName;
21+
@api title;
22+
@api objectName;
23+
@api columns;
24+
@api relatedFieldAPI;
25+
@api whereClause;
26+
@api limit = 10;
27+
// Private Property
28+
@track data;
29+
@track soql;
30+
@track offSet = 0;
31+
@track totalRows = 0;
32+
33+
// Do init funtion
34+
connectedCallback() {
35+
cols = JSON.parse(this.columns);
36+
cols.push({
37+
type: "action",
38+
typeAttributes: { rowActions: actions }
39+
});
40+
this.columns = cols;
41+
this.buildSOQL();
42+
countRecords({ objectName: this.objectName }).then(result => {
43+
this.totalRows = result;
44+
});
45+
this.fetchRecords();
46+
}
47+
48+
fetchRecords() {
49+
getRecords({ soql: this.soql }).then(data => {
50+
if (data) {
51+
data.map(e => {
52+
for (let key in e) {
53+
if (typeof e[key] === "object") {
54+
for (let onLevel in e[key]) {
55+
e[key + "." + onLevel] = e[key][onLevel];
56+
}
57+
}
58+
}
59+
});
60+
this.data = data;
61+
} else if (error) {
62+
}
63+
});
64+
}
65+
66+
newRecord() {
67+
this[NavigationMixin.Navigate]({
68+
type: "standard__objectPage",
69+
attributes: {
70+
objectApiName: this.objectName,
71+
actionName: "new"
72+
}
73+
});
74+
}
75+
76+
handleRowAction(event) {
77+
const actionName = event.detail.action.name;
78+
const row = event.detail.row;
79+
switch (actionName) {
80+
case "edit":
81+
this.editRecord(row);
82+
break;
83+
case "delete":
84+
this.deleteRow(row);
85+
break;
86+
case "show_details":
87+
this.showRowDetails(row);
88+
break;
89+
default:
90+
}
91+
}
92+
93+
//Next button to get the next data
94+
next(event) {
95+
this.offSet = this.offSet + this.limit;
96+
this.buildSOQL();
97+
this.fetchRecords();
98+
}
99+
100+
//Previous button to get the previous data
101+
previous(event) {
102+
this.offSet = this.offSet - this.limit;
103+
this.buildSOQL();
104+
this.fetchRecords();
105+
}
106+
107+
firstPage(event) {
108+
this.offSet = 0;
109+
this.buildSOQL();
110+
this.fetchRecords();
111+
}
112+
113+
lastPage(event) {
114+
this.offSet = Math.floor(this.totalRows / this.limit) * this.limit;
115+
this.buildSOQL();
116+
this.fetchRecords();
117+
}
118+
119+
get isDisablePrev() {
120+
return this.offSet == 0 ? true : false;
121+
}
122+
123+
get isDisableNext() {
124+
return this.offSet + this.limit >= this.totalRows ? true : this.totalRows <= this.limit ? false : false;
125+
}
126+
127+
/*********************************************************************
128+
* All Helper Method's
129+
*********************************************************************/
130+
deleteRow(row) {
131+
let id = row["Id"],
132+
index = this.findRowIndexById(id);
133+
console.log(index);
134+
if (index !== -1) {
135+
deleteRecord(id)
136+
.then(() => {
137+
this.data = this.data
138+
.slice(0, index)
139+
.concat(this.data.slice(index + 1));
140+
this.showToast("Success", "Record deleted", "success");
141+
})
142+
.catch(error => {
143+
this.showToast("Error deleting record", error.body.message, "error");
144+
});
145+
}
146+
}
147+
148+
findRowIndexById(id) {
149+
let ret = -1;
150+
this.data.some((row, index) => {
151+
if (row.Id === id) {
152+
ret = index;
153+
return true;
154+
}
155+
return false;
156+
});
157+
return ret;
158+
}
159+
160+
showRowDetails(row) {
161+
this[NavigationMixin.Navigate]({
162+
type: "standard__recordPage",
163+
attributes: {
164+
recordId: row["Id"],
165+
objectApiName: this.objectName,
166+
actionName: "view"
167+
}
168+
});
169+
}
170+
171+
editRecord(row) {
172+
this[NavigationMixin.Navigate]({
173+
type: "standard__recordPage",
174+
attributes: {
175+
recordId: row["Id"],
176+
objectApiName: this.objectName,
177+
actionName: "edit"
178+
}
179+
});
180+
}
181+
182+
//Generic function to build soql
183+
buildSOQL() {
184+
let soql = this.appendField();
185+
soql += this.appendWhere();
186+
soql += this.appendLimit();
187+
soql += this.appendOffset();
188+
console.log("soql:::", soql);
189+
this.soql = soql;
190+
}
191+
192+
appendField() {
193+
let soql = "SELECT Id,",
194+
col = [];
195+
if (cols) {
196+
cols.map(val => {
197+
if (val.hasOwnProperty("fieldName")) {
198+
col.push(val["fieldName"]);
199+
}
200+
});
201+
soql = soql + `${col.join(",")} FROM ${this.objectName}`;
202+
}
203+
return soql;
204+
}
205+
206+
appendWhere() {
207+
let where = " WHERE ";
208+
if (this.relatedFieldAPI)
209+
where += `${this.relatedFieldAPI} = '${this.recordId}'`;
210+
if (this.whereClause && this.relatedFieldAPI)
211+
where += ` AND ${this.whereClause}`;
212+
else if (this.whereClause) where += `${this.whereClause}`;
213+
return where === " WHERE " ? "" : where;
214+
}
215+
216+
appendLimit() {
217+
return ` LIMIT ${this.limit}`;
218+
}
219+
220+
appendOffset() {
221+
return ` OFFSET ${this.offSet}`;
222+
}
223+
224+
showToast(title, message, variant) {
225+
this.dispatchEvent(
226+
new ShowToastEvent({
227+
title: title,
228+
message: message,
229+
variant: variant
230+
})
231+
);
232+
}
233+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<apiVersion>48.0</apiVersion>
4+
<isExposed>true</isExposed>
5+
<targets>
6+
<target>lightning__RecordPage</target>
7+
</targets>
8+
<!-- Configuring the design attributes -->
9+
<targetConfigs>
10+
<targetConfig targets="lightning__RecordPage">
11+
<property name="iconName" type="String" label="Enter Icon Name" default="standard:account"/>
12+
<property name="title" type="String" label="Enter Title" default="LWC Table"/>
13+
<property name="objectName" type="String" label="Enter Object API Name"/>
14+
<property name="columns" type="String" label="Enter Columns JSON"/>
15+
<property name="relatedFieldAPI" type="String" default="" label="Enter Related field API Name"/>
16+
<property name="whereClause" type="String" default="" label="Enter WHERE clause"/>
17+
</targetConfig>
18+
</targetConfigs>
19+
</LightningComponentBundle>

0 commit comments

Comments
 (0)