# Apex Data Provider

The Apex Data Provider is designed to enhance the functionality of lookup and list form elements by enabling the integration of data obtained through custom Apex classes.&#x20;

This feature is particularly beneficial when data needs to be curated or processed using specific logic tailored to your unique requirements. Additionally, it offers the flexibility to fetch data from external sources such as web services or file contents, making it an indispensable tool for dynamic data integration in your applications.

{% hint style="info" %}
Your Apex Data Provider class must implement the following interface:

`FLX_KB.KanBanInterfaces.FormBuilderApiInterface`
{% endhint %}

This code demonstrates how to dynamically load and manipulate data for a Salesforce UI component, like a list or a lookup field, using Apex.

{% code lineNumbers="true" fullWidth="false" %}

```apex
public class with sharing implementing the interface FLX_KB.KanBanInterfaces.FormBuilderApiInterface
{
    // Define List data
    public Object loadListData(Map<String, Object> parameters)
    {       
        Integer pageNumber = Integer.valueOf(parameters.get('pageNumber'));
        Integer pageSize = 10;
        Integer offset = (pageNumber - 1) * pageSize;
        Integer sizeTotal = [select count() from Opportunity];
        List<Map<String, Object>> opportunitiesList = 
            getOpportunitiesList(pageSize, offset);
        
        // Return list properties and records
        return new Map<String, Object>{
            'pageNumber' => pageNumber,
            'pageSize' => pageSize,
            'hasNext' => sizeTotal > pageSize * pageNumber,
            'total' => offset + opportunitiesList.size(),
            'records' => opportunitiesList,
            // Define List Columns
            'columns' => new List<Map<String, Object>>{
                // Column definitions
                {'name' => 'name', 'label' => 'Opportunity Name', 'sortable' => 'false'},
                {'name' => 'contractName', 'label' => 'Contract Name', 'sortable' => 'false'},
                {'name' => 'contractOwner', 'label' => 'Contract Owner', 'sortable' => 'false'},
                {'name' => 'campaignName', 'label' => 'Campaign Name', 'sortable' => 'false'},
                {'name' => 'campaignActualCost', 'label' => 'Campaign Actual Cost', 'sortable' => 'false'}
            },
            // Define actions
            'actions' => {'view' => {}} 
        };
    }

    // Collect records for the List
    private List<Map<String, Object>> getOpportunitiesList(
        Integer pageSize, Integer offset)
    {
        List<Map<String,Object>> result = new List<Map<String,Object>>();
        // Query for opportunities
        for (Opportunity opp : [
            select Id, Name, Contract.Name, Contract.Owner.Name, 
            Campaign.Name, Campaign.ActualCost 
            from Opportunity 
            order by id 
            limit :pageSize offset :offset
        ])
        {
            // Adding each opportunity to the result
            result.add({
                'id' => opp.Id, 
                'name' => opp.Name, 
                'contractName' => opp.Contract.Name, 
                'contractOwner' => opp.Contract.Owner.Name, 
                'campaignName' => opp.Campaign.Name, 
                'campaignActualCost' => 
                    String.valueOf(opp.Campaign.ActualCost == null ? 0 : opp.Campaign.ActualCost)
            });
        }
        return result;
    } 
    
    // Define Lookup data
    public Object loadLookupData(Map<String, Object> parameters)
    {
        system.debug('parameters ' + parameters);
        List<Map<String, Object>> result = new List<Map<String, Object>>();
        String defaultValue = (String)parameters.get('value'); 
        String searchString = (String)parameters.get('filter'); 
        
        // Build query based on default value
        String request;
        if (String.isBlank(defaultValue)) 
        {
            request = 'SELECT id, name, ActualCost from Campaign';
        } else {
            request = 'SELECT id, name, ActualCost from Campaign where id = \'' 
                      + defaultValue + '\'';
        }
        Map<Id, Campaign> campaignItems = new Map<Id, Campaign>(
            (List<Campaign>)Database.query(request));
        
        // Process and add campaign items to result
        for (Campaign campaignItem : campaignItems.values())
        {
            String campaignNameAndAmount = campaignItem.Name + ' - $' + 
                (campaignItem.ActualCost == null ? '0' : 
                String.valueOf(campaignItem.ActualCost));
            if (String.isBlank(searchString))
                result.add({'Id' => campaignItem.Id, 'Name' => campaignNameAndAmount});
            else if (campaignNameAndAmount.containsIgnoreCase(searchString))
                result.add({'Id' => campaignItem.Id, 'Name' => campaignNameAndAmount});
        }
        system.debug(result);
        return result;
    }
    
    // Load related list data (currently not implemented)
    public Object loadRelatedListData(Map<String, Object> parameters)
    {
        return null;
    }
}
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flexikanban.ai/references/apex-data-provider.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
