As you guys know the wrapper class concept in visualforce pages , we generally use it to create a data-table which fetches data from different objects or if we want to redirect user to some other page on click of a link as one of the column of data-table.
For example we want a column "Account Name" on the data-table which is a link and once user clicks it should redirect respective account record. Or , suppose we want to display a column with some images or icons as a visual indicator Or what not. These requirements require us to use a wrapper on the lighting data-table (lightning:datatable)
I am going to use my previous account search example (Account Search Lightning Component) and explain the use of wrapper.
AccountSearchWrapper.app
AccountSearchWrapper.cmp
<aura:component controller="AccountSearchController" implements="force:appHostable,lightning:actionOverride,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction,lightning:isUrlAddressable" access="global">
<aura:attribute name="data" type="Object"/>
<aura:attribute name="columns" type="List"/>
<aura:attribute name="selectedRows" type="List" />
<aura:attribute name="maxRowSelection" type="Integer" default="1"/>
<aura:attribute name="selectedRowsList" type="List" />
<aura:attribute name="searchString" type="String" default=""/>
<aura:attribute name="AccountObj" type="Account" default="{ 'sobjectType': 'Account' }" />
<aura:attribute name="recordSaveError" type="String" default=""/>
<!-- HEADER START-->
<!-- Header with details about the account -->
<div class="slds-modal__header">
<lightning:layout >
<lightning:layoutItem >
<lightning:icon iconName="standard:account" size="small" alternativeText="Account Search"/>
</lightning:layoutItem>
<lightning:layoutItem padding="horizontal-small">
<div >
<h2 class="slds-text-heading--medium">Account Search</h2>
</div>
</lightning:layoutItem>
</lightning:layout>
</div>
<!--HEADER END-->
<!--CONTENT START-->
<div class="slds-modal__content slds-p-around_medium" id="modalid">
<div class=" slds-box slds-theme_default" >
<aura:if isTrue="{!not(empty(v.recordSaveError))}">
<div class="slds-notify slds-notify_alert slds-theme_alert-texture slds-theme_error" role="alert">
<span class="slds-assistive-text">error</span>
<h2>{!v.recordSaveError}
</h2><span class="slds-p-horizontal_small">
<lightning:icon iconName="utility:close" alternativeText="Error!" variant="inverse" size="x-small"/>
</span>
</div>
</aura:if>
<lightning:messages />
<div class="slds-section slds-is-open" >
<h3 class="slds-section__title slds-theme--shade">
<button class="slds-button slds-section__title-action">
<span>
Account Name
</span>
</button>
</h3>
</div>
</div>
<lightning:layout >
<lightning:layoutItem size="6" padding="around-small" >
<div class="slds-form-element slds-lookup" data-select="single">
<label class="slds-form-element__label" for="form-element-03">
<abbr class="slds-required" title="required">*</abbr>Account Name</label>
<div class="slds-form-element__control">
<div class="slds-input-has-icon slds-input-has-icon--right">
<lightning:buttonIcon iconName="utility:down" variant="bare" onclick="{! c.Search }" alternativeText="Search" class="slds-input__icon leftPaddingClass" />
<ui:inputText updateOn="keyup" keyup="{!c.Search}" value="{!v.AccountObj.Name}" class="slds-lookup__search-input slds-input " placeholder="Search" />
</div>
</div>
</div>
</lightning:layoutItem>
</lightning:layout>
<lightning:layout class="slds-border_bottom" >
<lightning:layoutItem size="12" padding="around-small" >
<div class="slds-hide" aura:id="dataTable">
<div class="slds-box">
<lightning:layout >
<lightning:layoutItem>
<lightning:icon iconName="standard:account" size="small" alternativeText="Account Search"/>
</lightning:layoutItem>
<lightning:layoutItem padding="horizontal-small">
<div >
<h2 class="slds-text-heading--medium">Account Search</h2>
</div>
</lightning:layoutItem>
</lightning:layout>
<div class="slds-p-top_small">
<lightning:datatable aura:id="accountDataTable"
keyField="Id"
data="{!v.data }"
columns="{!v.columns }"
hideCheckboxColumn="true"
showRowNumberColumn="true"
/>
</div>
</div>
</div>
</lightning:layoutItem>
</lightning:layout>
</div>
<!--CONTENT END-->
<!--FOOTER START-->
<div class="slds-modal__footer">
<div class="slds-m-top_medium slds-align_absolute-center">
<lightning:button name="Cancel" label="Cancel" onclick="{!c.Cancel}"/>
<lightning:button variant="brand" type="submit" name="save" label="Save" />
</div>
</div>
<!--FOOTER END-->
</aura:component>
AccountSearchWrapperController.js
({
Search : function(component, event, helper) {
component.find("accountDataTable").set("v.selectedRows", []);
var selectedRows = event.getParam('selectedRows');
var dataTable = component.find('dataTable');
var searchStr = component.get('v.AccountObj.Name');
var action = component.get('c.SearchAccount');
$A.util.addClass(dataTable, 'slds-show');
$A.util.removeClass(dataTable,'slds-hide');
action.setParams({
searchString: searchStr
});
action.setCallback(this, $A.getCallback(function (response) {
var state = response.getState();
if (state === 'SUCCESS') {
component.set("v.columns", response.getReturnValue().columns);
component.set("v.data", response.getReturnValue().accounts);
}else{
component.set("v.recordSaveError", response.getError());
}
}));
$A.enqueueAction(action);
},
Cancel : function(component, event, helper){
$A.get("e.force:closeQuickAction").fire();
},
})
AccountSearchController.apxcFor example we want a column "Account Name" on the data-table which is a link and once user clicks it should redirect respective account record. Or , suppose we want to display a column with some images or icons as a visual indicator Or what not. These requirements require us to use a wrapper on the lighting data-table (lightning:datatable)
I am going to use my previous account search example (Account Search Lightning Component) and explain the use of wrapper.
AccountSearchWrapper.app
<aura:application extends="force:slds" access="global" >
<c:AccountSearchWrapper />
</aura:application>
<c:AccountSearchWrapper />
</aura:application>
AccountSearchWrapper.cmp
<aura:component controller="AccountSearchController" implements="force:appHostable,lightning:actionOverride,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction,lightning:isUrlAddressable" access="global">
<aura:attribute name="data" type="Object"/>
<aura:attribute name="columns" type="List"/>
<aura:attribute name="selectedRows" type="List" />
<aura:attribute name="maxRowSelection" type="Integer" default="1"/>
<aura:attribute name="selectedRowsList" type="List" />
<aura:attribute name="searchString" type="String" default=""/>
<aura:attribute name="AccountObj" type="Account" default="{ 'sobjectType': 'Account' }" />
<aura:attribute name="recordSaveError" type="String" default=""/>
<!-- HEADER START-->
<!-- Header with details about the account -->
<div class="slds-modal__header">
<lightning:layout >
<lightning:layoutItem >
<lightning:icon iconName="standard:account" size="small" alternativeText="Account Search"/>
</lightning:layoutItem>
<lightning:layoutItem padding="horizontal-small">
<div >
<h2 class="slds-text-heading--medium">Account Search</h2>
</div>
</lightning:layoutItem>
</lightning:layout>
</div>
<!--HEADER END-->
<!--CONTENT START-->
<div class="slds-modal__content slds-p-around_medium" id="modalid">
<div class=" slds-box slds-theme_default" >
<aura:if isTrue="{!not(empty(v.recordSaveError))}">
<div class="slds-notify slds-notify_alert slds-theme_alert-texture slds-theme_error" role="alert">
<span class="slds-assistive-text">error</span>
<h2>{!v.recordSaveError}
</h2><span class="slds-p-horizontal_small">
<lightning:icon iconName="utility:close" alternativeText="Error!" variant="inverse" size="x-small"/>
</span>
</div>
</aura:if>
<lightning:messages />
<div class="slds-section slds-is-open" >
<h3 class="slds-section__title slds-theme--shade">
<button class="slds-button slds-section__title-action">
<span>
Account Name
</span>
</button>
</h3>
</div>
</div>
<lightning:layout >
<lightning:layoutItem size="6" padding="around-small" >
<div class="slds-form-element slds-lookup" data-select="single">
<label class="slds-form-element__label" for="form-element-03">
<abbr class="slds-required" title="required">*</abbr>Account Name</label>
<div class="slds-form-element__control">
<div class="slds-input-has-icon slds-input-has-icon--right">
<lightning:buttonIcon iconName="utility:down" variant="bare" onclick="{! c.Search }" alternativeText="Search" class="slds-input__icon leftPaddingClass" />
<ui:inputText updateOn="keyup" keyup="{!c.Search}" value="{!v.AccountObj.Name}" class="slds-lookup__search-input slds-input " placeholder="Search" />
</div>
</div>
</div>
</lightning:layoutItem>
</lightning:layout>
<lightning:layout class="slds-border_bottom" >
<lightning:layoutItem size="12" padding="around-small" >
<div class="slds-hide" aura:id="dataTable">
<div class="slds-box">
<lightning:layout >
<lightning:layoutItem>
<lightning:icon iconName="standard:account" size="small" alternativeText="Account Search"/>
</lightning:layoutItem>
<lightning:layoutItem padding="horizontal-small">
<div >
<h2 class="slds-text-heading--medium">Account Search</h2>
</div>
</lightning:layoutItem>
</lightning:layout>
<div class="slds-p-top_small">
<lightning:datatable aura:id="accountDataTable"
keyField="Id"
data="{!v.data }"
columns="{!v.columns }"
hideCheckboxColumn="true"
showRowNumberColumn="true"
/>
</div>
</div>
</div>
</lightning:layoutItem>
</lightning:layout>
</div>
<!--CONTENT END-->
<!--FOOTER START-->
<div class="slds-modal__footer">
<div class="slds-m-top_medium slds-align_absolute-center">
<lightning:button name="Cancel" label="Cancel" onclick="{!c.Cancel}"/>
<lightning:button variant="brand" type="submit" name="save" label="Save" />
</div>
</div>
<!--FOOTER END-->
</aura:component>
AccountSearchWrapperController.js
({
Search : function(component, event, helper) {
component.find("accountDataTable").set("v.selectedRows", []);
var selectedRows = event.getParam('selectedRows');
var dataTable = component.find('dataTable');
var searchStr = component.get('v.AccountObj.Name');
var action = component.get('c.SearchAccount');
$A.util.addClass(dataTable, 'slds-show');
$A.util.removeClass(dataTable,'slds-hide');
action.setParams({
searchString: searchStr
});
action.setCallback(this, $A.getCallback(function (response) {
var state = response.getState();
if (state === 'SUCCESS') {
component.set("v.columns", response.getReturnValue().columns);
component.set("v.data", response.getReturnValue().accounts);
}else{
component.set("v.recordSaveError", response.getError());
}
}));
$A.enqueueAction(action);
},
Cancel : function(component, event, helper){
$A.get("e.force:closeQuickAction").fire();
},
})
public class AccountSearchController {
@AuraEnabled(cacheable=true)
public static AccountWrapper SearchAccount(String searchString) {
String query;
List<AccountDataWrapper> accs= new List<AccountDataWrapper>();
List<AccountColumnWrapper> cols = new List<AccountColumnWrapper>();
List<Account> accountRecords = new List<Account>();
if(searchString !='' && searchString !=null){
query= 'SELECT Id,Name,Phone,Type,Website FROM Account where Name LIKE \'%' +searchString+'%\' LIMIT 10';
accountRecords = database.query(query);
}
for(Account acct : accountRecords){
accs.add(new AccountDataWrapper(acct.Name , acct.Website , acct.Phone));
}
// Add the column paramentes like type , fieldname as mentioned in this JSON format
// {label: 'Name', fieldName: 'Name', type: 'text'},
cols.add(new AccountColumnWrapper('Name' , 'Name' , 'text' , null , null));
cols.add(new AccountColumnWrapper('Website' , 'Website' , 'text' , null,null));
cols.add(new AccountColumnWrapper('Phone' , 'Phone' , 'phone' , null,null));
System.debug('cols JSON >>>>>'+JSON.serialize(cols));
AccountWrapper accountWarpper = new AccountWrapper(accs, cols);
system.debug('Accs ::'+accountWarpper);
return accountWarpper;
}
public class AccountWrapper {
@AuraEnabled
public List<AccountDataWrapper> accounts;
@AuraEnabled
public List<AccountColumnWrapper> columns;
public AccountWrapper(List<AccountDataWrapper> accounts_x ,List<AccountColumnWrapper> columns_x ){
accounts = accounts_x ;
columns = columns_x ;
}
}
public class AccountDataWrapper {
@AuraEnabled
public String Name;
@AuraEnabled
public String Website;
@AuraEnabled
public String Phone;
public AccountDataWrapper(String Name_x , String Website_x ,String Phone_x ){
Name = Name_x ;
Website = Website_x;
Phone = Phone_x;
}
}
public class AccountColumnWrapper {
@AuraEnabled
public String label;
@AuraEnabled
public String fieldName;
@AuraEnabled
public String type;
@AuraEnabled
public TypeAttribute typeAttributes ;
@AuraEnabled
public CellAttribute cellAttributes;
public AccountColumnWrapper(String label_x, String fieldName_x, String type_x , TypeAttribute typeAttributes_x,
CellAttribute cellAttributes_x) {
label = label_x;
fieldName = fieldName_x;
type = type_x;
typeAttributes = typeAttributes_x;
cellAttributes = cellAttributes_x;
}
}
public class TypeAttribute {
@AuraEnabled
public String label;
public TypeAttribute (String label_x) {
label = label_x;
}
}
public class CellAttribute{
@AuraEnabled
public String iconPosition;
@AuraEnabled
public Icon iconName;
public CellAttribute (String iconPosition_x ,Icon iconName_x) {
iconPosition = iconPosition_x;
iconName = iconName_x;
}
}
public class Icon{
@AuraEnabled
public String fieldName;
public Icon (String fieldName_x) {
fieldName = fieldName_x;
}
}
}
@AuraEnabled(cacheable=true)
public static AccountWrapper SearchAccount(String searchString) {
String query;
List<AccountDataWrapper> accs= new List<AccountDataWrapper>();
List<AccountColumnWrapper> cols = new List<AccountColumnWrapper>();
List<Account> accountRecords = new List<Account>();
if(searchString !='' && searchString !=null){
query= 'SELECT Id,Name,Phone,Type,Website FROM Account where Name LIKE \'%' +searchString+'%\' LIMIT 10';
accountRecords = database.query(query);
}
for(Account acct : accountRecords){
accs.add(new AccountDataWrapper(acct.Name , acct.Website , acct.Phone));
}
// Add the column paramentes like type , fieldname as mentioned in this JSON format
// {label: 'Name', fieldName: 'Name', type: 'text'},
cols.add(new AccountColumnWrapper('Name' , 'Name' , 'text' , null , null));
cols.add(new AccountColumnWrapper('Website' , 'Website' , 'text' , null,null));
cols.add(new AccountColumnWrapper('Phone' , 'Phone' , 'phone' , null,null));
System.debug('cols JSON >>>>>'+JSON.serialize(cols));
AccountWrapper accountWarpper = new AccountWrapper(accs, cols);
system.debug('Accs ::'+accountWarpper);
return accountWarpper;
}
public class AccountWrapper {
@AuraEnabled
public List<AccountDataWrapper> accounts;
@AuraEnabled
public List<AccountColumnWrapper> columns;
public AccountWrapper(List<AccountDataWrapper> accounts_x ,List<AccountColumnWrapper> columns_x ){
accounts = accounts_x ;
columns = columns_x ;
}
}
public class AccountDataWrapper {
@AuraEnabled
public String Name;
@AuraEnabled
public String Website;
@AuraEnabled
public String Phone;
public AccountDataWrapper(String Name_x , String Website_x ,String Phone_x ){
Name = Name_x ;
Website = Website_x;
Phone = Phone_x;
}
}
public class AccountColumnWrapper {
@AuraEnabled
public String label;
@AuraEnabled
public String fieldName;
@AuraEnabled
public String type;
@AuraEnabled
public TypeAttribute typeAttributes ;
@AuraEnabled
public CellAttribute cellAttributes;
public AccountColumnWrapper(String label_x, String fieldName_x, String type_x , TypeAttribute typeAttributes_x,
CellAttribute cellAttributes_x) {
label = label_x;
fieldName = fieldName_x;
type = type_x;
typeAttributes = typeAttributes_x;
cellAttributes = cellAttributes_x;
}
}
public class TypeAttribute {
@AuraEnabled
public String label;
public TypeAttribute (String label_x) {
label = label_x;
}
}
public class CellAttribute{
@AuraEnabled
public String iconPosition;
@AuraEnabled
public Icon iconName;
public CellAttribute (String iconPosition_x ,Icon iconName_x) {
iconPosition = iconPosition_x;
iconName = iconName_x;
}
}
public class Icon{
@AuraEnabled
public String fieldName;
public Icon (String fieldName_x) {
fieldName = fieldName_x;
}
}
}
Comments
Post a Comment