1

Happy Datetime.now().format('EEEE')! I'm working on an LWC that has a few configuration properties exposed. What I would like to do is have a picklist of values that lists all the lookup fields on the object, e.g. for any given object Lightning Page Layout we can have something like:

enter image description here

I love the idea that I can set the picklist values dynamically (https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/components_config_for_app_builder_dynamic_picklists.htm) but what I really need here is awareness of what object I'm working with. I might put this component on a Contact page layout or an Opportunity page layout and I would need to know that so I can build the correct list of lookup-type field names.

Is there any way to do this or do I need to figure out some other kind of workaround, or does anyone have any great ideas? I did find this doc that talks about using objectApiName, https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.use_object_context, but it only looks like I can use an expression like this in Expression Builder and not Lightning App Builder (I've tried, it fails telling you as much). Also, I found this answer to a similar question which confirmed that behavior, How to set attribute in the designer to a string-value which contains expression-tokens like "{!...}"?.

Thanks!

1

Ok, I figured it out. All I needed was 10 minutes more. Here's my solution in case it can help anyone else.

It turns out the VisualEditor.DesignTimePageContext class is exactly what I needed, https://developer.salesforce.com/docs/atlas.en-us.230.0.apexcode.meta/apexcode/apex_class_VisualEditor_DesignTimePageContext.htm. Using this I know exactly what object I'm working with. Here's the code I ended up with:

public inherited sharing class LookupFieldsPickList extends VisualEditor.DynamicPickList {

    VisualEditor.DesignTimePageContext context;

    public LookupFieldsPicklist(VisualEditor.DesignTimePageContext context) {
        this.context = context;
    }

    public override VisualEditor.DataRow getDefaultValue() {
        VisualEditor.DynamicPickListRows rows = new VisualEditor.DynamicPickListRows();

        List<String> keys = new List<String>();
        Map<String,String> fields = getLookupFields();
        for (String key : fields.keySet()) {
            keys.add(key);
        }

        VisualEditor.DataRow row = new VisualEditor.DataRow(fields.get(keys[0]), keys[0]);
        
        return row;
    }

    public override VisualEditor.DynamicPickListRows getValues() {

        VisualEditor.DynamicPickListRows rows = new VisualEditor.DynamicPickListRows();

        Map<String,String> fields = getLookupFields();
        for (String key : fields.keySet()) {
            VisualEditor.DataRow row = new VisualEditor.DataRow(fields.get(key), key);
            rows.addRow(row);
        }

        return rows;
    }

    private Map<String, String> getLookupFields() {

        Map<String,String> fieldMap = new Map<String,String>();

        Map<String, Schema.SObjectField> describeResult = Schema.getGlobalDescribe().get(context.entityName).getDescribe().fields.getMap();

        for (String key : describeResult.keySet()) {
            DescribeFieldResult dfr = describeResult.get(key).getDescribe();
            String label = dfr.getLabel();
            Schema.DisplayType typeName = dfr.getType();
            
            if (Schema.DisplayType.REFERENCE == typeName) {
                List<SObjectType> oType = dfr.getReferenceTo();
                String oTypeName = oType[0].getDescribe().getName();
                System.debug('API name: ' + key + ';; label: ' + label + ';; type: ' + typeName + ' (' + oTypeName + ')');

                String fullName = label + ' (' + oTypeName + ')';
                fieldMap.put(oTypeName, fullName);
            }
        }

        return fieldMap;
    }


}

It needs to be cleaned up. The getDefaultValue method is a bit brute-forceish, the values should be sorted alphabetically, etc. But it gets me what I need to continue on.

Thanks for playing!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.