Tuesday, 12 April 2011

Creating a Web-to-Lead Form (Part 2)

When we left off in the last post we mentioned creating an extension for our Web-to-Lead form that would direct the user to our custom Visualforce page. This extension will redirect the users to the "Thank You" page we created in the last post and will create a new lead post. We can begin this by clicking 'Setup', then 'Develop', then 'Apex Classes', and then finally 'New'. Once we are in the editor we can begin adding the following content:

01 public class myWeb2LeadExtension {
02
03     private final Lead weblead;
04
05     public myWeb2LeadExtension(ApexPages.StandardController
06                                       stdController) {
07            weblead = (Lead)stdController.getRecord();
08     }
09
10     public PageReference saveLead() {
11            try {
12            insert(weblead);
13            }
14            catch(System.DMLException e) {
15                   ApexPages.addMessages(e);
16                   return null;
17            }
18            PageReference p = Page.ThankYou;
19            p.setRedirect(true);
20            return p;
21       }
22 }

Once this is completed we need to create the "Contact Us" page. Begin by clicking 'Setup', then 'Develop', and finally 'Pages'. For the label you have the option to choose whatever you like but for simplicity we will go with 'Contact Us Page' and the name will be 'ContactUs'. The final step is to just replace the existing VF markup with the following content:

01 <apex:page standardController="Lead" extensions="myWeb2LeadExtension"
02  title="Contact Us" showHeader="false" standardStylesheets="true">
03   <apex:composition template="{!$Site.Template}">
04    <apex:define name="body">
05      <apex:form >
06        <apex:messages id="error" styleClass="errorMsg" layout="table"
07        style="margin-top:1em;"/>
08        <apex:pageBlock title="" mode="edit">
09        <apex:pageBlockButtons>
10        <apex:commandButton value="Save" action="{!saveLead}"/>
11        </apex:pageBlockButtons>
12        <apex:pageBlockSection title="Contact Us" collapsible="false"
13        columns="1">
14        <apex:inputField value="{!Lead.Salutation}"/>
15        <apex:inputField value="{!Lead.Title}"/>
16        <apex:inputField value="{!Lead.FirstName}"/>
17        <apex:inputField value="{!Lead.LastName}"/>
18        <apex:inputField value="{!Lead.Email}"/>
19        <apex:inputField value="{!Lead.Phone}"/>
20        <apex:inputField value="{!Lead.Company}"/>
21        <apex:inputField value="{!Lead.Street}"/>
22        <apex:inputField value="{!Lead.City}"/>
23        <apex:inputField value="{!Lead.State}"/>
24        <apex:inputField value="{!Lead.PostalCode}"/>
25        <apex:inputField value="{!Lead.Country}"/>
26       </apex:pageBlockSection>
27      </apex:pageBlock>
28    </apex:form>
29   </apex:define>
30  </apex:composition> 
31 </apex:page>

Now that all the content has been uploaded we need to make these pages available on our site. The first step is to enable all the Visualforce pages.  Click 'Setup', then 'Develop', then 'Sites', and finally click our site label. In the 'Site Details' page under 'Site Visualforce Pages' we will need to click 'Edit'. We have already saved our "ContactUs" and "ThankYou" pages so we need to select them both and click 'Add'. Finally click 'Save' to complete the process.

Next we need to make sure that the fields we created on our "ContactUs" page is completely visible. Go to the 'Site Details' page and click 'Public Access Settings'. Next go to the 'Field-Level Security' section and click 'View'. Finally make sure that the Address, Company, Phone, Email, and Name fields are marked as visible. If you want to change the visibility of any of the settings simply click 'Edit'.

Another step that needs to be taken is to grant the "Create" permission to our site for the lead object. Go to the 'Site Details' page and click 'Public Access Settings'. Then head to the 'Profile' page and click 'Edit". Under the 'Standard Object Permissions', select 'Create' permissions for Leads. Once again click 'Save' to complete the process.

Last step is to access our "ContactUs" page on the actual public site and see if the new lead form works! And fingers crossed it should.... :)

Monday, 28 March 2011

Creating a Web-to-Lead Form (Part 1)

For those who follow my blog you might remember that I previously mentioned that I have been tinkering with force.com sites. Someone recently asked me to how to create Web-to-lead forms so I thought it would be great idea to go over this process in the next few posts. Implementing these forms on your force.com site will allow a company to capture a prospective customers information. In order to do this we need to create a custom contact page. This will show up when prospective customers  submit their information.

Ultimately we will have to create two Visualforce pages...in these post we will go over the 1st one which is need to display the confirmation. First you need to click 'Setup', then 'Develop', and finally 'Pages'. For the Label I suggest entering 'Thank You Page' and for the Name I suggest entering 'ThankYou'....that being said you can enter whatever you feel is appropriate. The last step is to replace the existing the Visualforce markup with the following (again you can change the title and message to what you feel is appropriate):

01        <apex:page title="Information Request" 
02                              showHeader="false" standardStylesheets="true">
03       <apex:composition template="{!$Site.Template}">
04         <apex:define name="body">
05             <br/>
06             <center>
07             <apex:outputText value="Thank You For Your Inquiry!"/>
08             </center>
09             <br/>
10             <br/>
11         </apex:define>
12       </apex:composition>
13    </apex:page>

After this is done you have to extend the standard controller in place to redirect the would be users to a custom contact page when they submit information. We have to do this because as a default Salesforce.com makes it so the standard controller directs the user to the standard detail page after saving the related record. However these standard detail pages can not be made public on via regular sites.

In the next post we will go over how to direct the users to a custom Visualforce page by creating an extension for the standard controller. Please try to control your anticipation until then...        

Tuesday, 15 March 2011

Adding Pages to the Customer Portal

In the last post we went over the basic layout and structure of creating a customer portal from a standard page. Now that we have this knowledge we can go ahead and add extra pages to our site. The following code, specifically the composite component, enables the page to use or previous site template:

<apex:page showHeader="false" standardStylesheets="true">
<apex:composition template="{!$Site.Template}">
<apex:define name="body">
<-- PAGE'S CONTENT GOES HERE -->
</apex:define>
</apex:composition>
</apex:page>

All the new pages will now utilize our template! However if you want to overwrite your existing templates data you will need to add a "apex:define" component with the same name attribute as the insert component in the template.

That being said in order to overwrite the body section of the template you will need to insert the following:

<apex:define name="body">
... PAGE'S BODY...
<
apex:define>

Now you can customize the page to a certain extent if you don't want every page to follow the established template.

Monday, 28 February 2011

Building Customer Portals Via Force.com

I recently started playing around with force.com sites a lot more than usual as a means to build a customer portal for a new business I am starting with a few friends. I thought this could be a good avenue since I could create a customer portal that easily integrated with our CRM instance. And since I understand the language and given the ease of Visualforce technology the turnaround time would be rather quick.

Here is the layout of the force.com template:

(showHeader should be turned off so you won't see any Salesforce standard tabs or sidebar)
<apex:page showHeader="false" id="SiteTemplate" standardStylesheets="true">
(A section is reserved for header of the site)
<apex:insert name="header">
<c:SiteHeader />
<hr/>
</apex:insert>
(This section is where you can include the content of each page of your site)
<apex:insert name="body"/>
(A section is reserved for footer of the site)
<apex:insert name="footer">
<hr/>
<c:SiteFooter />
</apex:insert>
</apex:page>

The developers that I spoke to in my network recommended that follow the same pattern when developing my portal.

Things that should be included in the 'SiteHeader' component is the logo, log in and out links, headlines, and site navigation menu (This is done with code snippets...either extracted or some cases newly written). The same way, you can modify the 'SiteFooter' component to add your site's pages footer template. It is also recommend to include your site's shortcuts links and your company copy right message in this section.

Adding the shortcuts links  in the 'SiteFooter' section is very important...particularly if you want to utilize organic search. If you are using dynamic menus this will easily compensate for that.

Next post will demonstrate how to add new pages to the force.com site.

Monday, 14 February 2011

Logging into the Salesforce Sandbox

As I continue to learn Ruby I thought it would be prudent for me to start working on a RoR app. That being since yet to be classified as an expert in this type of development...it is definitely best to work on this app in the Salesforce sandbox. The sandbox allows you to create copies of your environments for development, testing and training, without compromising the data and apps in your production environment. In this post we will go over the multitude of problems people face in order to access the sandbox to test and develop the application.

To start you need to be aware that you won't be able to login from https://login.salesforce.com that's only for production. The correct move is to use the sandbox instance https://test.salesforce.com (or https://cs1.salesforce.com, https://cs2.salesforce.com, etc.). It should be clear that email@domain.com is your regular username, but the "sandbox" part is the actual name of your sandbox. So if you named your sandbox as "sandbox" you would login as joey@example.com.sandbox. If your user account was established after the sandbox was created then it won't be present. A simple sandbox refresh will add your account into the sandbox. This is a pretty common error.

If for some reason that does not work you may be trying to access the incorrect sandbox. Go to the production organization where you can login. Navigate to 'Setup', then 'Data Management', then 'Sandbox' and then click the 'Login' button next to the sandbox you wish you login to.

Another common problem users face is the situation when you are able to use your production password to log into the sandbox...but cannot use it to hook up to the API. As a standard Salesforce trusts users that come through the web UI. However in order to log in to the API, you will need to append an extra bit of user information to your password aka your Security Token.

You can reset this by going to 'Setup', then 'My Personal Information', then finally 'Reset MY Security Token'.

The token will get emailed to you - it will be some obscure alpha-numeric token. Copy this and paste it to the end of your password. For example if your password was 'awesome', and the token was XYZ987xyz, the credentials to pass through would be:


Password: awesomeXYZ987xyz

Now go ahead and make as many mistakes as you like...I do it all the time.

Monday, 31 January 2011

Ruby and Salesforce Integration (Part 2)

Before we begin I have to bring up the fact that the Steelers did beat the Jets. I'm not on the same level of Nostradamus yet...but I'm getting close. When we left off at our last post we created four new Ruby files in our Salesforce directory. And as I previously mentioned we will be using code from Andrew (Super-Size) Interwebdiary to generate an easy login in function.

The following is the code for the extra file we will be using for the simple login:

client_auth_header_handler.rb

 1 require 'soap/header/simplehandler'
 2
 3 class ClientAuthHeaderHandler < SOAP::Header::SimpleHandler
 4   SessionHeader = XSD::QName.new("rn:enterprise.soap.sforce.com", "SessionHeader")
 5
 6   attr_accessor :sessionid
 7   def initialize
 8     super(SessionHeader)
 9     @sessionid = nil
10   end
11
12   def on_simple_outbound
13     if @sessionid
14       {"sessionId" => @sessionid}
15     end
16   end
17
18   def on_simple_inbound(my_header, mustunderstand)
19     @sessionid = my_header["sessionid"]
20   end
21 end
22

For the final portion of code used in the login you will need to change the username, password, and security token to fit your specifications (changes needed are highlighted in red). This code will fetch records from the Account object and post raw output on the screen.

test.rb

 1 require 'rubygems'
 2 gem 'soap4r'
 3 require 'soap/soap'
 4 require 'defaultDriver'
 5 require 'client_auth_header_handler'
 6 require 'soap/wsdlDriver'
 7
 8
 9 d = Soap.new
10 d.wiredump_dev = STDOUT
11
12 h = ClientAuthHeaderHandler.new         
# Create a new handler
13
14 l = d.login(:username => "USERNAME", :password => "PASSWORD" + "SECURITY_TOKEN")
15
16 d.endpoint_url = l.result.serverUrl       
# Change the endpoint to what login tells us it should be
17 h.sessionid = l.result.sessionId            
# Tell the header handler what the session id is
18 d.headerhandler << h                         
# Add the header handler to the Array of headerhandlers
19
20 d.getUserInfo("")  
21 d.query(:queryString=> "select id,name from account")

defaultDriver and client_auth_header_handler (the code from above) are assumed to be in the current directory.
As always you are going to want to test the code. Do this by going to the Ruby console, then the 'sfdc' folder and input the following command:

ruby test.rb

If you run into errors you are going to have look at more API calls in the API docs....which kind of drives me crazy. But sometimes that what it takes when learning new languages.

Next post we will start exploring Ruby and RoR.