Adding Labels to Lightning Datatable
In Part 1 I described a way to make any SOQL result fit for use in a Datatable. The next step is to provide column labels. While it would be easy to just hardcode them, Abhishek suggested to use the original field names. The beauty of that approach: The admin can adjust and/or translate field labels without touching the code.
Going Meta
APEX has a rich API that allow querying an object's properties in the Schema name space. Getting the information for a collection of objects can be done using Schema.describeSObjects(sObjectTypes)
or Schema.getGlobalDescribe()
(see details here).
The interesting challenge is to find the object names of the relationships, the default field list will only tell you the name you gave it, but not the object you relate to. So some more code is required (see below).
Relationship fields can be identified by the part before the .
either ending in __r
or id
. So we break a query apart and extract a List<String>
for the field name and a String
for the start object name. Our scenario doesn't cater to subqueries. These two parameters get fed into a utility function.
public without sharing class AuraLabelHelper {
private static Map<String, Schema.SObjectType> globalDescribe = Schema.getGlobalDescribe();
public static Map<String, String> retrieveFieldLablesFromFieldList(List<String> fieldList, String objName) {
Map<String, String> result = new Map<String, String> ();
Map<String, Schema.SObjectField> fieldDefinitions = internalFieldLablesFromFieldList(fieldList, objName, '');
for (String key : fieldDefinitions.keySet()) {
DescribeFieldResult dfr = fieldDefinitions.get(key).getDescribe();
result.put(key, dfr.getLabel());
}
return result;
}
private static Map<String, Schema.SObjectField> internalFieldLablesFromFieldList(List<String> fieldList, String objName, String prefix) {
Map<String, Schema.SObjectField> result = new Map<String, Schema.SObjectField> ();
Schema.SObjectType objectType = AuraLabelHelper.globalDescribe.get(objName);
Schema.DescribeSObjectResult describeResult = objectType.getDescribe();
// Labels for the top level object - needs to be lowercased
Map<String, Schema.SObjectField> fieldMap = describeResult.fields.getMap();
Map<String, Schema.SObjectField> fieldMapLower = new Map<String, Schema.SObjectField> ();
for (String key : fieldMap.keySet()) {
fieldMapLower.put(key.toLowerCase(), fieldMap.get(key));
}
for (String fieldName : fieldList) {
String fieldNameLower = fieldName.toLowerCase();
if (fieldMapLower.containsKey(fieldNameLower)) {
result.put(prefix + fieldNameLower, fieldMapLower.get(fieldNameLower));
} else if (fieldNameLower.contains('__r.')) {
// We have a potential relationship field at hand
String relationFieldName = fieldNameLower.left(fieldNameLower.indexOf('__r.')) + '__c';
Schema.DescribeFieldResult relationDescribe = fieldMapLower.get(relationFieldName).getDescribe();
Schema.SObjectType reference = relationDescribe.getReferenceTo().get(0);
String objApiName = reference.getDescribe().getName();
List<String> subFieldList = new List<String> ();
String newPrefix = prefix + fieldNameLower.left(fieldNameLower.indexOf('.'))+'_';
subFieldList.add(fieldNameLower.substring(fieldNameLower.indexOf('__r.') + 4));
result.putAll(internalFieldLablesFromFieldList(subFieldList, objApiName, newPrefix));
}
}
return result;
}
}
Good boys and girls create a test class:
@IsTest
public class AuraLabelHelperTest {
@IsTest
public static void simpleAccountTest() {
List<String> fieldNames = new List<String> ();
fieldNames.add('Id');
fieldNames.add('Name');
fieldNames.add('Customer__c');
fieldNames.add('Customer__r.Name');
Map<String, String> result = AuraLabelHelper.retrieveFieldLablesFromFieldList(fieldNames, 'Address__c');
System.debug(result);
System.assert(result.containsKey('id'));
System.assert(result.containsKey('customer__r_name'));
}
}
Next stop is putting it all together. As usual YMMV.
Posted by Stephan H Wissel on 31 August 2018 | Comments (0) | categories: JavaScript Lightning Salesforce