Skip to content

Salesforce Sites page as a form endpoint

by Dave Manelski on October 21st, 2009

I’m working on a project right now that requires collecting contact information through a number of web forms into Salesforce.  The standard web-to-lead form simply won’t work for this particular client, because they’re anticipating a big media pop from their outreach campaign, which would easily overwhelm the 500 sign-ups per day limit. A Salesforce Sites form seemed to hold the solution, but here’s where it gets tricky.  The client’s website is highly stylized, which makes embedding a Sites page using an <iframe> fairly difficult and styling the whole Visualforce page downright out of the question.  Moreover, different forms from the website have different lead sources and should associate with different campaigns in the database.

The solution was to create a Salesforce Sites form that will serve as an endpoint for an HTTP POST.  In my custom controller, I can easily retrieve parameters from the post, write them to the lead fields that I wish and create the lead, all contained within one controller method.  For each different web form, I can pass in different values for lead source, campaign, you name it!  Voilá, I am able to repurpose one custom web-to-lead form to POST to it from any form on my website.  The form does dual-purpose actually, not only can I POST to it, but it also acts a real web-to-lead form that could also be iframed into a web page.

First, let’s take a look at the Visualforce page:

<apex:page controller="ONEN_CTRL_WebToLead" action="{!insertLead}" showheader="false" sidebar="false" >
    <div style="display:none;"> 
    In addition to embedding this form directly into a page, you may also pass an HTTP POST directly into this form.
    The following labels map to POST parameters:
    * EXAMPLE Field Label - POST_Parameter_Name
    * Last Name (required) - Last_Name
    * First Name - First_Name
    * Organization - Organization
    * Email - Email
    * Mobile Phone - Mobile
    * Home Phone - Home_Phone
    * Lead Source - Lead_Source
    * Email Opt Out - Email_Opt_Out (must pass a string of 'true' to set this boolean)
    * Campaign Id - Campaign_Id
    * Campaign Member Status - Campaign_Member_Status
    * Home Street - Home_Street
    * Home City - Home_City
    * Home State - Home_State
    * Home Postal Code - Home_PostalCode
    </div>
    
    <apex:form >  
        <table>
                       
            <tr>
                <td align="right">
                    <apex:outputLabel value="First Name *" for="txtFirstName" style="font-weight:bold" />               
                </td>
                <td>
                    <apex:inputField value="{!lead.FirstName}" id="txtFirstName" required="true" />
                </td>
            </tr>
            <tr>
                <td align="right">
                    <apex:outputLabel value="Last Name *" for="txtLastName" style="font-weight:bold" />             
                </td>
                <td>
                    <apex:inputField value="{!lead.LastName}" id="txtLastName" required="true" />
                </td>
            </tr>
            <tr>
                <td align="right">
                    <apex:outputLabel value="E-Mail *" for="txtEmail" style="font-weight:bold" />              
                </td>
                <td>
                    <apex:inputField value="{!lead.Email}" id="txtEmail" required="true" />
                </td>
            </tr>
            <tr>
                <td align="right">
                    <apex:outputLabel value="Mobile" for="txtPostalCode" style="font-weight:bold" />               
                </td>
                <td>
                    <apex:inputField value="{!lead.MobilePhone}" id="txtMobilePhone" />
                </td>
            </tr>
            <tr>
                <td align="right">
                    <apex:outputLabel value="Home Street" for="txtStreet" style="font-weight:bold" />                
                </td>
                <td>
                    <apex:inputField value="{!lead.Home_Street__c}" id="txtStreet" />
                </td>
            </tr>           
            <tr>
                <td align="right">
                    <apex:outputLabel value="Home City" for="txtCity" style="font-weight:bold" />                
                </td>
                <td>
                    <apex:inputField value="{!lead.Home_City__c}" id="txtCity" />
                </td>
            </tr>
            <tr>
                <td align="right">
                    <apex:outputLabel value="Home State/Province" for="txtState" style="font-weight:bold" />             
                </td>
                <td>
                    <apex:inputField value="{!lead.Home_State__c}" id="txtState" />
                </td>
            </tr>
            <tr>
                <td align="right">
                    <apex:outputLabel value="Home Zip/Postal Code" for="txtPostalCode" style="font-weight:bold" />               
                </td>
                <td>
                    <apex:inputField value="{!lead.Home_PostalCode__c}" id="txtPostalCode" />
                </td>
            </tr>
            <tr>
                <td>
                <div style="display:none;">
                <apex:inputField value="{!lead.Campaign_Id__c}" id="txtCampaignId" />
                <apex:inputField value="{!lead.Campaign_Member_Status__c}" id="txtCampaignMemberStatus" />
                <apex:inputField value="{!lead.LeadSource}" id="txtLeadSource" />
                </div>
                </td>
                
                <td>
                    <apex:commandButton action="{!save}" value="Submit"/>&nbsp;&nbsp;&nbsp;<apex:outputLabel value="{!StrSaveResult}" />        
                </td>
            </tr>
        </table>
    </apex:form>
</apex:page>

And the controller. Notice how easy it is to just grab a parameter using the getParamters() method:

public class ONEN_CTRL_WebToLead {

	public Lead lead { 
		get {
			if (lead == null) lead = new Lead();
			return lead;
		}
		
		set; 
	}
	
	public PageReference Save() {
		if (lead.Company == null) lead.Company = '[not provided]'; 
		insert lead;
		StrSaveResult = 'Your information has been saved.  Thank you.';
		lead = null;	// so fields get reset to null.
		return null;
	}
	
	public String StrSaveResult { get; set; }
	
	public PageReference insertLead() {
		Map<string,string> postParameters = ApexPages.currentPage().getParameters();
		
		if (!postParameters.isEmpty()) {
			Lead newLead = new Lead();
			newLead.FirstName = ApexPages.currentPage().getParameters().get('First_Name');
			
			//hard code [not provided] for people without last names or company
			if (ApexPages.currentPage().getParameters().get('Last_Name')==null || ApexPages.currentPage().getParameters().get('Last_Name')=='') {
				newLead.LastName = '[not provided]';
			} else {
				newLead.LastName = ApexPages.currentPage().getParameters().get('Last_Name');
			}
			
			if (ApexPages.currentPage().getParameters().get('Organization')==null || ApexPages.currentPage().getParameters().get('Organization')=='') {
				newLead.LastName = '[not provided]';
			} else {
				newLead.Company = ApexPages.currentPage().getParameters().get('Organization');
			}
	
			newLead.Email = ApexPages.currentPage().getParameters().get('Email');
			newLead.Home_Phone__c = ApexPages.currentPage().getParameters().get('Home_Phone');
			newLead.MobilePhone = ApexPages.currentPage().getParameters().get('Mobile');
			newLead.LeadSource = ApexPages.currentPage().getParameters().get('Lead_Source');
			newLead.HasOptedOutOfEmail = ApexPages.currentPage().getParameters().get('Email_Opt_Out').contains('true');
			newLead.Campaign_Id__c = ApexPages.currentPage().getParameters().get('Campaign_Id');
			newLead.Campaign_Member_Status__c = ApexPages.currentPage().getParameters().get('Campaign_Member_Status');
			newLead.Home_Street__c = ApexPages.currentPage().getParameters().get('Home_Street');
			newLead.Home_City__c = ApexPages.currentPage().getParameters().get('Home_City');
			newLead.Home_State__c = ApexPages.currentPage().getParameters().get('Home_State');
			newLead.Home_PostalCode__c = ApexPages.currentPage().getParameters().get('Home_PostalCode');
			
			insert newLead;
		}
		
		return null;
	}
	
	//==================== TEST METHOD(s) ======================================
	static testmethod void CodeCoverageTests() {
		//instantiate the controller 
		ONEN_CTRL_WebToLead ctrl = new ONEN_CTRL_WebToLead();
		
		Lead lead = ctrl.lead;
		System.Assert(lead != null);
		lead.FirstName = 'TestFirstName';
		lead.LastName = 'TestLastName';
		ctrl.Save();
		System.AssertEquals('Your information has been saved.  Thank you.', ctrl.StrSaveResult);
	}	
}

From → Sites, Visualforce

7 Comments
  1. Thanks for the example and congrats on the new blog!

  2. Evan Callahan permalink

    Brilliant strategy, Dave. Do you have a plan for requiring fields or error handling for entries you don’t like? You could write Javascript on the original form, or this Visualforce could call back the original form with an error message.

  3. Very nice. Thanks for sharing.

    Mike

  4. Twinkle permalink

    I have tried this code, working fine till i submit the form.

    But, after submission , it says “Authorization Required…”.

    Please suggest what to do here.

    I am very new to Salesforce. Please help.

    Thanks in advance.

  5. Twinkle permalink

    Here is my link for this particular page, http://rcmp-developer-edition.ap1.force.com/testtwin.

    Controller Code:

    public class ONEN_CTRL_WebToLead {

    public Lead lead {
    get {
    if (lead == null) lead = new Lead();
    return lead;
    }

    set;
    }

    public PageReference Save() {
    insert lead;
    StrSaveResult = ‘Your information has been saved. Thank you.’;
    lead = null; // so fields get reset to null.
    return null;
    }

    public String StrSaveResult { get; set; }

    public PageReference insertLead() {
    Map postParameters = ApexPages.currentPage().getParameters();

    if (!postParameters.isEmpty()) {
    Lead newLead = new Lead();

    newLead.Title__c = ApexPages.currentPage().getParameters().get(‘Title’);
    newLead.First_Name__c = ApexPages.currentPage().getParameters().get(‘First_Name’);
    newLead.Last_Name__c = ApexPages.currentPage().getParameters().get(‘Last_Name’);
    newLead.Email__c = ApexPages.currentPage().getParameters().get(‘Email’);
    newLead.Company_Name__c = ApexPages.currentPage().getParameters().get(‘Company_Name’);
    newLead.Preferred_Contact_Number__c = ApexPages.currentPage().getParameters().get(‘Preferred_Contact_Number’);
    insert newLead;
    }

    return null;
    }

    //==================== TEST METHOD(s) ======================================
    static testmethod void CodeCoverageTests() {
    //instantiate the controller
    ONEN_CTRL_WebToLead ctrl = new ONEN_CTRL_WebToLead();

    Lead lead = ctrl.lead;
    System.Assert(lead != null);
    lead.FirstName = ‘TestFirstName’;
    lead.LastName = ‘TestLastName’;
    ctrl.Save();
    System.AssertEquals(‘Your information has been saved. Thank you.’, ctrl.StrSaveResult);
    }
    }

  6. Twinkle permalink

    Apex Code:

    In addition to embedding this form directly into a page, you may also pass an HTTP POST directly into this form.
    The following labels map to POST parameters:
    * EXAMPLE Field Label – POST_Parameter_Name
    * Last Name (required) – Last_Name
    * First Name – First_Name
    * Organization – Organization
    * Email – Email
    * Mobile Phone – Mobile
    * Home Phone – Home_Phone
    * Lead Source – Lead_Source
    * Email Opt Out – Email_Opt_Out (must pass a string of ‘true’ to set this boolean)
    * Campaign Id – Campaign_Id
    * Campaign Member Status – Campaign_Member_Status
    * Home Street – Home_Street
    * Home City – Home_City
    * Home State – Home_State
    * Home Postal Code – Home_PostalCode

       

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS