• Follow us on Twitter
  • Join our Facebook Group
  • Join me on Google Plus
  • Add me on Linkedin
  • RSS
Welcome to the Delivered Innovation blog! close

  • Home
  • Cloud Computing
  • Salesforce
  • DI News & Events
  • Force.com Tips

Archive for category: Force.com Platform Tips

Create a Custom Web Form Handler With Force.com Sites

0 Comments/ in Force.com Platform Tips / by Michael Topalovich
December 2, 2011

No doubt you’ve run into this also…we needed a form handler that captured data for sObjects other than Cases or Leads (e.g. custom objects), we did not want to redirect visitors to a new page upon form submission, and our functional requirements were more complex than what the standard Salesforce form handlers could support. The standard Salesforce Web-to-Lead and Web-to-Case form handlers were not an option, so we had to create our own custom web form handler. And because we wanted to keep everything on Force.com, we decided to build this solution using VisualForce pages and an Apex controller served by Force.com Sites. We developed an alternative solution and wanted to share it with the community in the event it could help others.

Use case

You want to capture form data directly in Salesforce from either a VisualForce page served Force.com Sites or from an externally hosted page, but the standard Web-to-Lead or Web-to-Case web handlers do not meet your exact requirements. You may also be using custom JavaScript forms that post data using AJAX, and do not want to blindly pass data to a form handler that will not provide a return to indicate success or exceptions.

Ultimately, we wanted to expose our form handler so it could also be accessed by any of our forms on the web (Force.com Sites as well as others such as our WordPress blog, which uses an HTML / PHP-based form to collect data).

So, here’s what we did

To begin, you need to ensure that Force.com Sites is setup correctly if it is not already.  You can find information on creating and maintaining Force.com Sites here or here.  In our case, we created a “utility” Force.com Site so that we could keep the pages separate from our main Force.com Sites web pages.  We also concealed the Force.com Sites utility subdomain in our custom Site.URLRewriter implementation to avoid AJAX cross-domain issues, but that is a discussion for a future post.

You will need to code up a VisualForce Page and an Apex class to serve as a custom controller to capture the form data and cast values to specific fields in the target sObject.  The VisualForce page itself is very simple in its construct…essentially it will serve two purposes:

  1. Perform a specific Action that calls a PageReference method in the custom controller when the page is invoked.
  2. Return a value in a format that the process calling the form handler is expecting.  In our case, our AJAX method is expecting a JSON object with the result of the form submission (success or otherwise).

This is what the VisualForce page for the form handler that we use for www.deliveredinnovation.com looks like:

<apex:page cache="false" controller="formHandlerSample" action="{!processForm}"  showheader="false" contentType="application/jsonrequest" >
 { success: {!success} }
 </apex:page>

The elements of this page to take note of:
  1. The ‘controller’ attribute is the custom Apex class that contains the logic that will process the contents of the web form
  2. The ‘action’ attribute is the PageReference method contained in the Apex class that will process the form data and generate the required return string
  3. Because our AJAX script is looking for a JSON object to be returned, we declared the contentType of ”application/jsonrequest.” You may find that you need to return XML, HTML, or other text, so update this attribute to suit your specific requirements.

The form handler code:

public class formHandlerSample {
public Map<String, String> urlParams;
public String Error {get; set;}
public Lead formLead = new Lead();
   
public formHandlerSample() {
urlParams = ApexPages.currentPage().getParameters();
}
public Boolean Success {
get { 
if(Success == null) { 
Success = false;
}
return Success; 
} 
set;
}
public void processLead(Map<String, String> formFields) {
if(formFields.size() > 0) {
try {
for(String fieldKey : formFields.keySet()){
if(fieldKey != null && fieldKey != 'null'){
if(fieldKey == 'FirstName'){
formLead.FirstName = formFields.get(fieldKey);
}
if(fieldKey == 'LastName'){
formLead.LastName = formFields.get(fieldKey);
}
if(fieldKey == 'Title'){
formLead.Title = formFields.get(fieldKey);
}
if(fieldKey == 'Company'){
formLead.Company = formFields.get(fieldKey);
}
if(fieldKey == 'Phone'){
formLead.Phone = formFields.get(fieldKey);
}
if(fieldKey == 'Email'){
formLead.Email = formFields.get(fieldKey);
}
if(fieldKey == 'Description'){
formLead.Description = formFields.get(fieldKey);
}
}
}
upsert formLead;
Success = true;
}
catch(System.Exception e) {
System.debug('Houston, you have a problem: ' + e);
Success = false;
Error = String.ValueOf(e);
}
}
else {
Success = false;
Error = 'No form fields received';
}
}
public PageReference processForm(){
processLead(urlParams);
return null;
}
}

Questions?  Suggestions?  Leave us a comment or email us directly at Blog [at] DeliveredInnovation.com.


Salesforce Excel Connector Tool Reference and Lookup Formula Examples

0 Comments/ in Force.com Platform Tips / by Michael Topalovich
March 30, 2011

The Salesforce Excel Connector is a powerful tool for quickly importing data into Salesforce and Force.com objects. You can also use the Excel Connector to mass edit records, which helps with data quality and data management initiatives. Delivered Innovation has utilized Excel Connector many times to facilitate data migrations involving data models with complex lookup relationships, and we have developed some useful Excel formulas to aid in creating reference tables to lookup record IDs in other objects when there is no apparent foreign key or when we need to find things like non-blank values.

We have put together an Excel spreadsheet with a number of use cases and examples with supporting sample data to demonstrate the functionality of commonly used formulas, from simple lookups to complex array formulas.  The use cases include:

  • Return record ID based on first row returned in a search for values in a specified index given search criteria in a specific cell. This works well when you have a unique or 1:1 value that you want to return.
  • Return the row numbers for any records that match the search criteria (specified in either a cell or by giving an explicit string value). Use the row number to then retrieve a value such as the record ID.
  • Return the row numbers for any records with non-blank values in a specified column. Use the row number to then retrieve a value such as the record ID.

One of the things that we found early on is that the VLOOKUP function was difficult to use and was not returning the results we expected, so we standardized on the use of the INDEX function with an inline MATCH function. The array functions that we have outlined required a significant amount of experimentation and testing, but we have found that these yield consistently high quality results in our migrations and data cleanup projects. We welcome your feedback, please let us know how these work for you and if you have any suggestions or improvements.

Download Salesforce Excel Connector Formulas

Render VisualForce Components Dynamically Based on Object Level Security

1 Comment/ in Force.com Platform Tips / by Michael Topalovich
February 5, 2011

We recently came across an interesting situation that I’m sure many Force.com developers have faced at one point or another:  While using VisualForce with standard controllers in the context of a single object gives you access to a fair number of useful standard components exposed by the platform, when you venture beyond the single object or require functionality beyond what the platform gives you “out-of-the-box,” the custom code can pile up fast.

The specific use case that we had to address dealt with dynamically exposing components on the VisualForce page based on the object level security of the logged in user’s profile – in this case, it was buttons (apex:commandButton) and links (apex:commandLink). Because we were displaying input fields (apex:inputField) and output fields (apex:outputField) from a number of different custom objects, and because the actions corresponding to these buttons and links were custom PageReference methods that did a lot of data manipulation, we couldn’t simply reference standard actions such as {!save}.  And because not every user had access to the CRUD function associated with a given custom button or link, we wanted to only show them buttons and links that corresponded to an action that they could actually perform, rather than leading the user down a path that would ultimately throw an exception and frustrate them.

We knew we could write a fairly complex set of sObject describe methods that would populate boolean variables which we could then reference in the redered=”xxxx” attribute of the button and link definitions, but there had to be a better solution – we weren’t looking for a shortcut, but we didn’t want to leave the client with a ton of code that would be difficult to maintain and update over time. The solution ended up being elegant and straightforward, and leveraged a VisualForce global variable called $ObjectType that we didn’t realize was as powerful as it turned out to be.

The VisualForce documentation doesn’t do $ObjectType justice:

A global merge field type to use when referencing standard or custom objects such as accounts, cases, or opportunities as well as the value of a field on that object.

What salesforce.com should state in the documentation is that the $ObjectType is essentially a way to perform sObject describes natively in the context of the VisualForce page, without having to write a single line of custom controller or controller extension code.  It’s a pretty powerful function, and the only reason we went down the path of using it as a replacement for complex sObject describe methods is that we came across this page in the VisualForce Developer’s Guide, and thought to ourselves that if we could check object accessibility using $ObjectType.accessible, which looks a lot like the ‘isAccessible‘ sObject describe result method, then we might be able to use the similar nomenclature to check for object editability, deletability, etc.  This turned out to be the case, and we had our solution.

So let’s say you want to have a ‘New’ button on your VisualForce page that corresponded to a custom PageReference method called ‘newRecord’, and you only wanted that button to be visible to users that had ‘Create’ access on the corresponding standard or custom object.  What you want to do is something like this:

<apex:commandButton action="{!newRecord}" value="New" rendered="{!$ObjectType.myCustomObject__c.createable}" />

Using $ObjectType.objectName.createable returns a boolean (true/false) value that tells you whether the logged in user has the ability to create (the ‘C’ in CRUD) new records for the ‘myCustomObject__c’ custom object.  If the user does not have the necessary object level security, the expression will return ‘False’ and the component will not render.  If the user does have Create access, then the button will render because the expression will return ‘True.’

While we did not test this method with every possible sObject describe method, we did use it to create an ‘Action’ column to mimic the standard ‘Edit  |  Del’ pattern that you see on standard Salesforce list views, so we know for sure that you can check the ability to access, create, edit, and delete records for a given object.  The VisualForce code looks something like this:


<apex:pageBlockTable value="{!getSomeRecords}" var="r" cellpadding="8">
<apex:column width="10%" >
<apex:facet name="header"><b>Action</b></apex:facet>
<apex:commandLink action="{!myCustomEditLink}" rendered="{!$ObjectType.myCustomObject__c.updateable}">
<apex:outputText value="Edit"/>
<apex:param name="editId" value="{!r.id}"/>
</apex:commandLink>
<apex:outputText value=" | " rendered="{!$ObjectType.myCustomObject__c.updateable && $ObjectType.myCustomObject__c.deletable}"/>
<apex:commandLink action="{!deploymentDelete}" onclick="return confirm('Are you sure?');" rendered="{!$ObjectType.Deployments__c.deletable}">
<apex:outputText value="Del" />
<apex:param name="deleteId" value="{!r.id}"/>
</apex:commandLink>
</apex:column>

and so on...

As you can see, we were able to dynamically render the ‘Edit’ and ‘Del’ links, as well as the ‘ | ‘ spacing character all based on the CRUD / object level access of the user accessing the VisualForce page.  This saved us a lot of time, and will be fairly straightforward to maintain and update over time.

Here’s a little cheat sheet:

Show a component only if the user has ‘Create‘ access to an object:

<apex:commandButton action=”{!newRecord}” value=”New” rendered=”{!$ObjectType.myCustomObject__c.createable}” />

Show a component only if the user has ‘Edit‘ access to an object:

<apex:commandButton action=”{!editRecord}” value=”Edit” rendered=”{!$ObjectType.myCustomObject__c.updateable}” />

Show a component only if the user has ‘Delete‘ access to an object:

<apex:commandButton action=”{!deleteRecord}” value=”Delete” rendered=”{!$ObjectType.myCustomObject__c.deletable}” />

Note: An alternative solution can be found here.

Trigger to Automatically Submit Record for Approval

1 Comment/ in Force.com Platform Tips / by Michael Topalovich
June 6, 2010

Use Case:

You want all new records for an object to be submitted to an Approval Process, but you do not want to rely on users to manually click the ‘Submit for Approval’ button after creating the record.

Solution:

After creating and testing a new Approval Process (Setup / App Setup / Create / Workflow & Approvals / Approval Processes), implement this simple Apex Trigger (the following example is for the Account object). You will also need to create a test method to ensure code coverage if your current production Apex Classes do not provide adequate coverage. Developers may also want to add try / catch statements to ensure that exceptions are caught and handled properly.

The Apex Trigger code:


trigger accountApprovalSubmit on Account (after insert) {

for (Account a : trigger.new) {

Approval.ProcessSubmitRequest app = new Approval.ProcessSubmitRequest();
app.setObjectId(a.id);

Approval.ProcessResult result = Approval.process(app);

}

}

Tip submitted by:

Michael Topalovich
Delivered Innovation

Create VisualForce Tab to Display Static List View for Standard or Custom Object

5 Comments/ in Force.com Platform Tips / by Michael Topalovich
June 1, 2010

Use Case:

You would like to create a custom tab to display a specific list view for a standard or custom object rather than use the standard tab view that only displays recently viewed records.

Solution:

  1. From the standard or custom object tab, Edit an existing view or ‘Create New View.’
  2. Ensure that you give the view a Name, that you specify filter criteria, that you select the fields to display, and that you restrict visibility as necessary.
  3. When the view has been saved and you are returned to the tab, select the view from the dropdown.
  4. Copy the 15-character view ID in the URL and paste it to Notepad, or write it down.
  5. Create a new VisualForce page (Setup / App Setup / Develop / Pages) using the sample code provided below.
  6. Create a new VisualForce tab (Setup / App Setup / Create / Tabs) and select the VisualForce Page created in Step #5, provide a Tab Label, Tab Name, and Tab Style, and then apply the desired profile visibility for the new tab.
  7. Optional – hide the tab for the standard or custom object if your new tab is a replacement for the default tab.
  8. If you want to change the View that is displayed in the tab at any time, simply navigate back to the standard tab for the object and Edit the view to meet requirements.

The VisualForce Page code:

Note: Replace “xxxxxxxxxxxxxxx” with the 15-character ID of the View that you captured in Step #4 above.  You can adjust the ‘height’, ‘customizable’, and ‘rowsPerPage’ values as desired.

<apex:page >
<apex:enhancedList listId="xxxxxxxxxxxxxxx" height="600" customizable="false" rowsPerPage="25"/>
</apex:page>

Tip submitted by:

Michael Topalovich
Delivered Innovation

Force.com Tip: ‘New’ Button Override to Assign VisualForce Page to Specific Record Type Using Native Apex Code

16 Comments/ in Force.com Platform Tips / by Michael Topalovich
August 9, 2009

* Updated 8.14.09 with a link to a similar post by Jeff Douglas and refactored code that is more applicable to a broader audience using Apex PageReference methods rather than the original string concatenation that was used for human (non-Salesforce developer) readability

You’ve probably come across this before…you need to create a custom VisualForce page for a specific Record Type, but overriding the ‘New’ or ‘Edit’ button seems to be an all-or-nothing proposition (i.e. you can do a single VisualForce page and embed the Page Layout using Apex:Detail, but you can’t mix custom pages with standard Page Layouts). We came across this recently at Delivered Innovation, and we want to share our solution with the community. This specific example involves the Salesforce Case object, but can be applied to any Standard or Custom Object.

Use Case: Client has multiple call centers supporting various product lines; support team ‘A’ requires a custom Wizard to rapidly search for and collect details for the Case record that the standard Salesforce search interface cannot provide.

Solution: While you can assign a specific Page Layout to a specific Record Type and embed VisualForce pages in the object Detail view, currently salesforce.com does not support embedded VisualForce Pages in the Edit view of a Page Layout; likewise, salesforce.com does not support custom VisualForce pages for specific Record Types.  The solution is to “intercept” the command to create a new record in an Object before Salesforce processes it, and this is accomplished with a 1-line VisualForce page and a StandardController extension that pulls and analyzes certain URL parameters to enhance the out-of-the-box process routing capabilities of Salesforce.

Read more →

Salesforce CRM, Force.com, Cloud Computing: Application and System Design

Latest Posts

  • Doing Business in the CloudApril 10, 2012, 12:22 pm
  • Delivered Innovation Co-Hosts ITA “State of the Cloud” EventFebruary 22, 2012, 1:30 pm
  • Force Feed 2-20-2012February 20, 2012, 1:21 pm
  • Cloudup 2-17-2012February 17, 2012, 9:45 am
  • State of the Cloud Event RecapFebruary 16, 2012, 4:37 pm

Topics

  • Cloud Architecture (173)
  • Delivered Innovation News & Events (30)
  • Force.com Platform Tips (6)
  • Salesforce Architecture (32)

Follow us on Twitter

Follow @twitter

Latest Tweets

  • Up 38% from a year ago, http://t.co/JEY1hGq5 continues to grow. http://t.co/e7q7MztA
    May 17, 2012 - 3:24 PM
  • RT @Benioff: Congrats salesforce on an amazing quarter. The fastest growing software company of our size! 38%! $3B guide! http://t.co/L ...
    May 17, 2012 - 3:05 PM
  • We have a couple new Apps coming; look forward to giving you a peek soon.
    May 17, 2012 - 12:44 PM
  • Cloud is a corporate strategy, not a tactical solution http://t.co/QltTfDFz
    May 10, 2012 - 7:45 AM
  • Chicago #cloudforce - how fast the day goes... http://t.co/YjRI1vp3
    May 4, 2012 - 9:47 AM

Force.com VAR: Value Added Reseller Partner

Salesforce.com Consultant: Registered Consulting Partner

Salesforce.com ISV: Independent Software Vendor Partner

Tags

#df11 Amazon Apex AppExchange Appirio Chatter cloud Cloud Computing Cloudforce cloud security Coghead Delivered Innovation News Dreamforce ExtJS facebook Force.com Gartner Google heroku IaaS IBM Interop ITA IT service delivery Jonathan Sapir Marc Benioff Michael Topalovich Microsoft Oracle PaaS Platform as a Service public cloud SaaS Salesforce Salesforce.com Sencha SOA Social Media Software as a Service Spring '12 the cloud twitter VisualForce Vmware Winter '12

Salesforce CRM, Force.com, Cloud Computing: Application and System Design


View Larger Map

Delivered Innovation
688 N. Milwaukee Ave #202
Chicago, IL 60642
888.645.2604

Delivered Innovation

  • Delivered Innovation Home
  • DI on AppExchange
  • DI on Facebook
  • DI on Google+
  • DI on LinkedIn
  • DI on Tumblr
  • DI on Twitter
© Copyright - Delivered Innovation Blog - Wordpress Theme by Kriesi.at