Creating a Custom List View in Salesforce Using LWC and Apex In this blog post, we’ll guide you through the process of creating a custom list view in Salesforce using Lightning Web Components (LWC) and Apex. This will enable you to fetch, display, and print Task records based on specific filters. We’ll cover the step-by-step development of the Apex controller, LWC component, and the creation of a list layout button to enhance your Salesforce interface. Prerequisites Step 1: Create a Visualforce Page Start by creating a Visualforce page that connects to the LWC, named ListviewPage. htmlCopy code<apex:page standardController=”Task” recordSetVar=”tasks” extensions=”CustomListViewInLwcCtrl”> <apex:includeLightning /> <style> #lightning { height: 100vh; } @media print { #lightning { height: auto; overflow: visible; } .print-section { height: auto; overflow: visible; } } </style> <div id=”lightning”></div> <script> console.log(‘work6’); var filterId = ‘{!filterId}’; console.log(‘Filter ID:’, filterId); $Lightning.use( “c:ExampleLWCApp”, function() { $Lightning.createComponent( “c:listviewpage”, { ‘filterId’: filterId }, “lightning” ); } ); </script> </apex:page> Step 2: Create an Aura Component htmlCopy code<aura:application extends=”ltng:outApp”> <aura:dependency resource=”listviewpage” /> </aura:application> Step 3: Create an Apex Controller Next, you’ll need an Apex controller to manage the fetching of list views and their associated records. apexCopy codepublic with sharing class CustomListViewInLwcCtrl { private String filterId; public CustomListViewInLwcCtrl(ApexPages.StandardSetController controller) { filterId = controller.getFilterId(); System.debug(‘FilterId–> ‘ + filterId); } public String getFilterId() { return filterId; } @AuraEnabled(cacheable = true) public static List<ListView> fetchTaskListView(String objectApiName) { try { return [ SELECT Id, Name, DeveloperName FROM ListView WHERE SObjectType = :objectApiName ORDER BY DeveloperName ASC ]; } catch (Exception e) { System.debug(‘Error fetching list views: ‘ + e.getMessage()); return new List<ListView>(); } } @AuraEnabled(cacheable = true) public static List<sObject> getTaskListviewRecord(String objectName, String listViewId, String limitsize, String offsize) { // Logic to fetch Task records } @AuraEnabled(cacheable = true) public static List<Map<String, String>> getTaskListviewLabel(String objectName, String listViewId) { // Logic to fetch Task record labels } } Step 4: Create a Lightning Web Component Create the LWC listviewPage that will interact with the Apex controller. HTML Template htmlCopy code<template> <div class=”slds-grid slds-wrap” style=”width: 280px;”> <div class=”slds-m-around_medium”> <lightning-combobox name=”listViewSelect” label=”Select List View” value={selectedListView} placeholder=”Select a List View” options={listViewOptions} onchange={handleListViewChange}> </lightning-combobox> </div> </div> <br> <div class=”slds-grid slds-wrap”> <div class=”slds-col slds-size_1-of-4″></div> <div class=”slds-col slds-size_3-of-4 slds-text-align_right”> <lightning-button variant=”brand” label=”Print” onclick={handlePrint}></lightning-button> </div> </div> <br> <div if:true={isLoading}> <lightning-spinner alternative-text=”Loading”></lightning-spinner> </div> <template if:false={isLoading}> <div class=”print-section”> <template if:true={records.length}> <lightning-datatable key-field=”Id” data={records} columns={columns} hide-checkbox-column></lightning-datatable> <div class=”slds-m-top_medium slds-text-align_center”> <lightning-button-group> <lightning-button class=”previous” label=”Previous” onclick={handlePrevious} disabled={disablePrevious}></lightning-button> <lightning-button class=”next” label=”Next” onclick={handleNext} disabled={disableNext}></lightning-button> </lightning-button-group> </div> </template> <template if:false={records.length}> <div class=”slds-text-align_center”> No records to display </div> </template> </div> </template> </template> JavaScript Controller javascriptCopy codeimport { LightningElement, track, wire, api } from ‘lwc’; import fetchListView from ‘@salesforce/apex/CustomListViewInLwcCtrl.fetchTaskListView’; import getTaskListviewRecord from ‘@salesforce/apex/CustomListViewInLwcCtrl.getTaskListviewRecord’; import getTaskListviewLabel from ‘@salesforce/apex/CustomListViewInLwcCtrl.getTaskListviewLabel’; const PAGE_SIZE = 100; export default class ListviewPage extends LightningElement { @api filterId; @track listViewOptions = []; @track selectedListView = ”; @track records = []; @track columns = []; @track isLoading = true; @track limitsize = PAGE_SIZE; @track offset = 0; connectedCallback() { console.log(‘Filter ID:’, this.filterId); } @wire(fetchListView, { objectApiName: ‘Task’ }) fetchListViewHandler({ data, error }) { if (data) { this.listViewOptions = data.map(listView => ({ label: listView.Name, value: listView.Id })); this.selectedListView = this.filterId || this.listViewOptions[0].value; this.fetchRecords(); } else if (error) { console.error(‘Error fetching list views:’, error); } } fetchRecords() { this.isLoading = true; getTaskListviewRecord({ objectName: ‘Task’, listViewId: this.selectedListView, limitsize: this.limitsize.toString(), offsize: this.offset.toString() }) .then(result => { console.log(`${result.length} records`, result); this.records = this.formatRecords(result); this.fetchLabels(); }) .catch(error => { console.error(‘Error fetching records:’, error); this.records = []; this.isLoading = false; }); } formatRecords(records) { return records.map((record, index) => ({ …record, Count: this.offset + index + 1, // Additional field mappings })); } fetchLabels() { getTaskListviewLabel({ objectName: ‘Task’, listViewId: this.selectedListView }) .then(labels => { this.columns = [ { label: ‘ ‘, fieldName: ‘Count’, type: ‘number’ }, …labels.map(labelInfo => ({ label: labelInfo.label, fieldName: labelInfo.fieldApiName, type: ‘text’ })) ]; this.isLoading = false; }) .catch(error => { console.error(‘Error fetching labels:’, error); this.isLoading = false; }); } handleListViewChange(event) { this.selectedListView = event.detail.value; this.offset = 0; this.fetchRecords(); } handlePrint() { if (confirm(‘Are you sure you want to print?’)) { window.print(); } } handlePrevious() { if (this.offset >= PAGE_SIZE) { this.offset -= PAGE_SIZE; this.fetchRecords(); } } handleNext() { this.offset += PAGE_SIZE; this.fetchRecords(); } get disablePrevious() { return this.offset === 0; } get disableNext() { return this.records.length < PAGE_SIZE; } } Step 5: Handle Remote Site Settings To allow your Apex class to make callouts, add your Salesforce org’s URL to the Remote Site Settings: Step 6: Create a List Layout Button To create a button that opens your custom list view Visualforce page: Conclusion This custom list view component in Salesforce allows for enhanced record handling, display, and printing, offering greater flexibility than the standard list views. By leveraging LWC and Apex, you can create a tailored experience for your users, improving their efficiency and overall satisfaction. If this was tl;dr, contact Tectonic for assistance today. Like1 Related Posts Salesforce OEM AppExchange Expanding its reach beyond CRM, Salesforce.com has launched a new service called AppExchange OEM Edition, aimed at non-CRM service providers. Read more The Salesforce Story In Marc Benioff’s own words How did salesforce.com grow from a start up in a rented apartment into the world’s Read more Salesforce Jigsaw Salesforce.com, a prominent figure in cloud computing, has finalized a deal to acquire Jigsaw, a wiki-style business contact database, for Read more Health Cloud Brings Healthcare Transformation Following swiftly after last week’s successful launch of Financial Services Cloud, Salesforce has announced the second installment in its series Read more