Category Archives: APEX

How to Dynamically Populate Fields in Salesforce Data Entry Screens Using Apex Classes

I recently had to solve this use case for a work project and I thought I would share as it could be very useful across a number of scenarios within  Salesforce. Why this is really useful and powerful is that it works on a New Object screen BEFORE the save occurs. So you can see results while the screen is still in edit mode.

The application has two custom objects, Proposal and Project, that are related with a lookup from Project to Proposal. While the relationship  is not Master-Detail, the Proposal lookup field is required on the Project screen so that a Proposal is required before a Project can be created.  Both Proposal and Project have fields in common of Title, Account, Contact, and Scope of Work. Title, Account, and Contact are required on both objects.

The Use Case is that when creating a new Project all four of these fields should copy over from the related Proposal so the user doesn’t have to reenter them,  while remaining editable on the Project data entry screen, all before saving the Project. So when the New Project button is clicked, and the related Proposal is selected, all of the related common field values from the Proposal should immediately copy over into matching fields on the Project screen prior to clicking the Project save button.  Workflow field updates and triggers don’t work for this scenario because (1) we don’t want to first have to click save and then go back into edit before making changes and finish filling out other fields on the New Project screen. And (2) since these fields are required on the Project screen the record won’t save in the first place unless all of the required fields contain values.

proposalexample

 

The solution has to work in two different cases when creating a new Project. One is clicking the Project tab and then selecting the New Project button. In this scenario the user will need to first select the related Proposal after which the related fields should be copied over from Proposal to Project. The other case occurs when starting from the Proposal screen and clicking the New Project button in the related project list. In this case the Proposal__c.Name is automatically copied over to the related Proposal__c field on new Project screen and so is unnecessary for the user to select. Our solution has to work correctly for both of these cases.

The solution for this problem is to create a Visualforce page with an extended controller class that replaces the standard New Project page. Three files have to be created to make this work, a Visualforce page,  an Apex class, and a unit test. Salesforce requires you to run a unit test on all code before you are able to deploy from sandbox into production.

The VisualForce Page

I won’t go into how to create a VisualForce page here, but I will mention a free tool I use which makes turning a standard or custom object page into a VisualForce page a snap.  It’s called Layout Page and can be found in the App Store. It converts any Salesforce Page Layout (Standard OR Custom) into a Standard Visualforce Page instantly.

Once you have created the VisualForce page the following changes should be made.

The first line of the VisualForce page shown below sets the controller and extension for the page. The main controller is the Project__c object and the Apex extension class is named RelatedController1.

<apex:page standardController="Project__c" extensions="RelatedController1">

This next line of code calls the Apex function PopulateProject() whenever a user selects the related Proposal. The PopulateProject() method will locate the selected Proposal record in Proposal__c and copy the fields, Title, Contact, Account, and Scope_of_Work from the selected Proposal record into the appropriate fields on the new Project screen. This line handles the scenario where the user selects the New Project button from the Projects tab and so on the New Project screen the related Proposal is blank and needs to be manually selected.

<apex:inputField value="{!Project__c.Proposal__c}">
            <apex:actionSupport event="onchange" action="{!PopulateProject}" rerender="accinfo, msgs"/> 
         </apex:inputField>

The following line handles the scenario where the user selects New Project button from the Project related list on the Proposal screen where the Proposal Name will already be filled in and so not necessary to select. This line calls an inline Ajax function located at the bottom of the VisualForce page that checks to see if the  Project__c.Proposal__c field is NOT null, in which case it calls the Apex method PopulateProject to copy in all of the Proposal field values.

<apex:actionFunction name="CallApexMethod" action="{!PopulateProject}" reRender="accinfo, msgs"/>

The Ajax code below should be located at the bottom of the VisualForce page just above the </apex:page> tag. This script executes on every page load, which is what we need in order to check if the related Proposal has already been selected.

<script>
    function addLoadEvent(func) 
{ 
  var oldonload = window.onload; 
  if (typeof window.onload != 'function') 
  { 
     window.onload = func; 
  } 
  else
  { 
      window.onload = function()  
      { 
        if (oldonload) 
        { 
           oldonload(); 
        } 
        func(); 
      } 
   } 
} 
   
addLoadEvent(function()  
{ 
var controllervariable='{!Project__c.Proposal__c}';
if(controllervariable==null){return false;}
else {
  CallApexMethod(); }
});
</script>

The Apex Class

The Apex class, RelatedController1, is shown below. This where all the work happens to locate the selected Proposal record and set fields in the new Project record equal to fields from the selected Proposal record.

public with sharing class RelatedController1
{
public Proposal__c prop {get;set;}

private ApexPages.StandardController stdCtrl;

public RelatedController1(ApexPages.StandardController std)
{
stdCtrl=std;
}

public void PopulateProject()
{
Project__c proj=(Project__c) stdCtrl.getRecord();
if(proj.Proposal__c == null){return;}
else{
prop=[select Name,  Account__c, Scope_of_Work__c, Contact__c from Proposal__c where Id=:proj.Proposal__c];

proj.Name=prop.Name;
proj.Account__c=prop.Account__c;
proj.Scope_of_Work__c=prop.Scope_of_Work__c;
proj.Project_Contact__c=prop.Contact__c;}
}
}

All of the work described so far has to be completed in a Salesforce sandbox or developer account. I used a  partial sandbox under my Production org which copies a subset of data into the sandbox along with all of the Production org metadata.

The Unit Test

Once everything is working correctly in sandbox, you will have to create a unit test that when run exercises at least 80% of the code in the Apex class without error. Only then will Salesforce allow you to create an outbound change set and deploy it into your Production org.

The code for the test class is shown below.

@isTest(SeeAllData=true)

public class RelatedController1Test {

static testMethod void testRelatedController1() {
// Select an actual proposal record from Proposal__c
Proposal__c p = [SELECT Id, Name FROM Proposal__c WHERE       Name=’Test Proposal Dekra’ LIMIT 1];
// Clone the selected proposal record and set some of the fields
Proposal__c testProposal = p.clone();

testProposal.Name = ‘Acme Test’;
testProposal.Scope_of_Work__c = ‘test’;
// Create the test proposal record
insert testProposal;

// Create the test project record and set the related Proposal__c field equal to the Id of the newly created test Proposal__c.Id.
Project__c prj = new Project__c();
prj.Name = ‘test’;
prj.Proposal__c = p.Id;

insert prj;
// Now run the test by instantiating the RelatedController1 class and calling the PopulateProject() method. This test gives 100% coverage.
Test.startTest();
ApexPages.Standardcontroller std = new ApexPages.Standardcontroller(prj);
RelatedController1 clsObj = new RelatedController1(std);
clsObj.PopulateProject();
Test.stopTest();
}
}

When the test has run successfully you are ready to create an outbound Change Set containing  two files, the RelatedController1 Apex class file and the Visualforce page, and deploy them into your Production org.

Force.com Dev 501 Class

The week of October 10th I was fortunate to have the opportunity to attend Force.com’s Dev 501 class in Atlanta. This class went beyond the declarative capabilities of Force.com covered in Dev 401 and expanded into APEX and Visualforce controllers.

Apex is an object oriented  programming language,  similar to Java and C#,  for building software as a service (SaaS) applications on top of Salesforce.com’s customer relationship management (CRM) functionality.  Apex gives developers access to Salesforce.com’s back-end database and metadata objects to create third-party SaaS applications. These 3rd party applications are offered for sale or free of charge in the Salesforce AppExchange marketplace, similar to the Apple and Android app stores.

Visualforce is a framework that includes a tag-based markup language,  similar to HTML or ASP.Net.

In the Visualforce markup language, each Visualforce tag corresponds to a user interface component, such as a section of a page or a field. The behavior of Visualforce components can be controlled by the same logic used in standard Salesforce pages, or developers can create  their own logic with controller classes written in Apex.

The Dev 501 class covers an amazing array of topics…just a few of which are APEX triggers, Force.com IDE Eclipse plugin, development sandboxes, SOQL queries, DML (data modeling language), deployment from sandbox to production organizations, consuming web services, and unit testing Apex classes.

Format of the class was lecture mixed with hands on exercises reinforced by formal questions answered out loud by attendees at the end of every lecture and exercise.  This was actually the most challenging formal training class I have attended since college…and also one of the best.

 

 

Salesforce.com Rocks

Yesterday (Thursday April 5th) I attended a nicely done seminar/reception at the Westin Buckhead by Salesforce.com. There must have been several hundred attendees at the 1:30pm keynote which provided a good overview of Salesforce, APEX, and AppExchange. After the keynote there were several breakout sessions; one for beginning/potential customers, one for experienced customers, and another for developers focused on the new on-demand (SaaS) APEX language. I attended the APEX seminar for 2.5 hours where I received a good introduction to Salesforce customization and programming techniques. Salesforce is like many of the new Web 2.0 companies offering a unique and innovative value proposition to customers and partners. It is more of a platform where many types of applications can be created by development partners and then offered to customers via AppExchange, an “eBay like” space for selling/exchanging applications. Of course most of the applications are functional extensions of Salesforce CRM or are complimentary to CRM in some fashion. But they don’t have to be. Since Salesforce offers a free developer account I have signed up and plan on trying my hand at creating an APEX application. I predict Salesforce could potentially dominate the CRM market, and apparently so do many large corporations such as DuPont, Cisco, Panasonic, Avis, and United Way just to name a few Salesforce customers.

All attendees received two books, “Salesforce for Dummies” and “AppExchange for Dummies.” And the reception with open bar and lots of munchies (butterfly shrimp, crab cakes, steak on a stick, etc.) was super nice.

Thanks Salesforce!