+ Start a Discussion
Evan DonovanEvan Donovan 

how to create a pair of lead forms so that prospects can update their own information

My organization is using the Salesforce Nonprofit Starter Pack, Enterprise Edition, and needs to develop web forms to support the following use case:

 

1) An individual goes to a page and fills out an inquiry form on which they provide their basic information (name, email, how they heard about us, and a few custom fields).

 

2) The individual is then redirected back to our site, so they can download more information about the internships we offer.

 

3) An email is sent out thanking them for their interest, and inviting them to fill out our pre-interview questionnaire.

 

At first, I considered the Web-to-Lead form, plus a triggered workflow action, but I have determined that the Web-to-Lead is too limited, since we need the form in step #3 to be pre-populated with the information from step #1. Web-to-Lead forms don't allow for pre-population of data as far as I can tell, since the forms are POSTed cross-domain, and there's no kind of session or query string identifier available.

 

Following that, I considered using the API in conjunction with our CMS (Drupal), but I couldn't get those webforms to successfully generate new objects in the Salesforce database. It seemed like a connection was being made via SOAP, but no object mappings were found.

 

So I have settled upon using Salesforce's Sites feature, unless you all would recommend something else (such as an AppExchange add-on like Zoomerang or FormExchange).

 

I have followed the instructions for creating a Web-to-Lead form given in http://wiki.developerforce.com/index.php/Web2Lead_with_Force.com_Sites. However, I have the following problems/questions:

 

1) The page that I have created goes to a page that is not accessible after form submission (it says "Login Required"). This happens both on the developer and the live Site.

 

    a) I don't know how to get the "thankyou" page that I created for the custom controller to be accessible to the Guest User.

 

    b) I don't know how to deploy the custom controller Apex code from developer to live.

 

    c) Ideally, I would not like a thank-you page at all, but rather a redirection back to a page on my site, as with a regular web-to-lead form.

 

2) "Company" is a required field. However, our organization is non-profit, and the candidates for our positions don't have a company with which they should be associated. Is there a way to pre-populate (or, ideally, hide) this field, and have it always say "Individual" so that the bucket account from the Nonprofit Starter Pack works?

 

3) I don't know how to write the code, to be triggered by a successful form submission, that would send an email to a user with a link to the 2nd form, the one with the pre-interview questionnaire fields on it, and their initial lead fields pre-populated.

 

4) So far if I go to my page, and append ?id=[LeadObjectID] onto the end of it, then I will only be able to see the values for the lead object, not edit them. Furthermore, if one of the non-required fields was not filled out the first time, then it will not show at all.

Is there a way to make it possible for users to update the lead object (so they can fill out the interview information), or would I have to create a custom object in order to do this?

 

I hope all that is clear. If you have questions, I'll try to clarify what I want.

dbuschhodbuschho

Hello,

 

Based on your description, I think you might want to consider our App ( sorry of the commercial pitch ) FormAssembly.com:

http://sites.force.com/appexchange/apex/listingDetail?listingId=a0N300000016ac6EAA

 

Steps 1-3 can be accomplished relatively easy inside our App, including what I think is a simpler autoresponder setup than what Salesforce offers.  In a nut shell, you design a custom form, tell it how to map the fields from the custom form into Salesforce objects ( of any type, including custom objects ) and you're good to go.  You can also grab the html generated for your form and place it in most any CMS system that allows form tags.  You can configure the form to fire off autoresponder emails to those who complete the form, and place data from the response into the email...for your workflow I'd recommend including a link to the second form like:

http://endpoint?tfa_F2FirstName=%%tfa_F1FirstName%%&tfa_F2LastName=%%tfa_F1LastName%%

which would be populated when the email gets sent, with:

http://endpoint?tfa_F2FirstName=John&tfa_F2LastName=Smith

 

Our SF specific documentation is here:

http://www3.formassembly.com/blog/support-documentation/connectors-documentation/salesforce-documentation/

 

We offer a test-drive, and a 30-day no-questions refund.  I notice you're a not-for-profit, at this time we exploring discount options for you all, so if price is a sticking point let us know and we'll see what we can do.

 

Sorry again to give you a sales speech, but I figured since this was a few hours old, it was fair game.

 

Hope you find something that works for you,

Drew.

FA Support.

Evan DonovanEvan Donovan

I don't mind you recommending your app at all - I actually was considering FormAssembly, but wasn't sure if it would meet my needs. I'll talk to my boss, and probably give it a trial, and we'll see if it is a good fit.

 

That said, if anyone else wants to reply with information on how this could be accomplished in Salesforce via code, I would appreciate that too - just so I know what all the alternatives are.

krishnagkrishnag

this can be achieved thru sites we have done the similar task but not exactly the same.Prepopulating the page can be done using the controllers with some apex.

 

our scenario is our client dont want much info to be filled by user during registration.So we are kind shorted the form.after he registers.If he is interested he can log back to my site and edit his profile where we provide additional fileds.with already populated fileds which are given by user during initial registration. so that all the info we need can be achieved.

 

hope this is kind of similar i used sites for logging in and editing the profiles.

Evan DonovanEvan Donovan

@kristnag: Prepopulating with Apex sounds like what I want - do you have any pointers as to how to do it, or links to resources on what I would need to learn to get started? I am completely new to Salesforce development, having only done PHP development up until now.

krishnagkrishnag

i can share u a small example of mine but its all controllers .and it is linked with  3 pages.i will paste each seperately here.

 

page 1 :  login page 

<apex:page showHeader="false" controller="prefersignon" standardStylesheets="false">
<apex:stylesheet id="sheet" value="{!URLFOR($Resource.stylesheet)}"/>
<center>
<div class="logo" style="top:100px;">
<img src="{!URLFOR($Resource.preferimages,'images/zurich-logo.gif')}" width="150" height="93" alt=""/>
<p style="font-style: normal;font-size:medium;"> 
        To view and discuss about offers, you need a Zurich account.</p></div>
<div class="logo" style="top:100px;right:35px">
<apex:form >

<table border="0" cellspacing="0" cellpadding="0" style="Top:200px;" >   
              
              <tr>
                <td class="cell1" align="right">Email *</td> 
                <td class="cell2" style="width:227px;">
                    <apex:inputText value="{!email}" title="Email" required="true" id="email" style="width:200px;" />
                </td>
              </tr>
              <tr>
                <td></td>
                <td class="cell_error1">
                <apex:outputLabel id="emailerror" value="Invalid Email" style="color:Red;" rendered="{!emailerr}"/>
              </td>
              </tr>
              <tr>
                <td class="cell1" align="right">Password *</td> 
                <td class="cell2" style="width:227px;">
                    <apex:inputSecret value="{!pwd}" title="Password" required="true" id="pwd" style="width:200px;" />
                </td>
              </tr>
              <tr>
                <td></td>
                <td class="cell_error1">
                <apex:outputLabel id="passerror" value="Invalid Password" style="color:Red;" rendered="{!passerr}"/>
              </td>

              </tr>
              <tr>
              <td></td></tr>

              <tr>
              
              <td class="cell1"></td>
                <td class ="cell2" align="center">
                        <apex:commandButton id="cbtneditlogin" action="{!editprofile}" style="bgcolor:white;background-image:url({!URLFOR($Resource.preferimages,'images/login.jpg')});height:35px;width:155px;border-width:0px;background-repeat:no-repeat;cursor:pointer;"/>
                </td>
                </tr>
                <tr>
              <td></td></tr>
              <tr>
              <td></td></tr>
              
              
              
              
</table>
</apex:form></div>
</center>
</apex:page>

 controller for page1

 

 

public with sharing class prefersignon {

    public Boolean passerr { get; set; }

    public String pwd { get; set; }

    public Boolean emailerr { get; set; }

    public String email { get; set; }
    
     public prefersignon()    
    {                
    emailerr=false; 
    passerr=false; 
    
    }
    
    public PageReference editprofile() {
    List<guestuser__c> checkvals=[select Id,Email__c,Password__c from guestuser__c where Email__c=:email];
        if(checkvals.size()>0)
        {
                if(checkvals[0].Password__c == pwd)
                {
                PageReference tosecondpage = Page.profileedit;
                tosecondpage.getParameters().put('paramID',checkvals[0].ID);
                tosecondpage.setRedirect(true);
                return tosecondpage;
                }  
                else
                {
                   emailerr=false;
                   passerr=true;
                }          
            }
          else
          {
          //email not exist
            
                emailerr=true;
                passerr=false;
          }    
          
        return null;
    }


  static testMethod void testprefersignon()
  {
     
    guestuser__c gu = new guestuser__c(Email__c = 'aa@aa.com',Password__c = 'abcd',First_Name__c='abc',Last_Name__c ='xyz',Title__c='developer',Street__c='golf',City__c='okc',State__c='ok',Country__c='usa',Company__c='zurich',Zipcode__c='48326',Phone__c='4056138499');
    insert gu;
     prefersignon controller = new prefersignon();
     
     controller.email = 'aa@aa.com';
     controller.pwd = 'abcd';
     controller.editprofile();
     
     controller.email='aa@aa.com';
     controller.pwd='abc';
     controller.editprofile();
     
      controller.email = 'xx@xx.com';
     controller.pwd = 'abcd';
     controller.editprofile();
  }  
    
    
}

 

 

page 2:  opens up with populated data in a mode editable.The data is related to the login details given in page1

 

 

<apex:page showHeader="false" standardStylesheets="false" controller="preferenc">
<!--<apex:pageBlock mode="edit" title="My Preferences">-->
<html>
<body bgcolor="#F5F5F5">
<center>
<h2>Personal Information</h2>
<apex:form >
<table border="0" cellspacing="5" cellpadding="5" columns="2">
<tr>
<td>
<apex:outputText >Email</apex:outputText> </td>
<td>
  <apex:inputText value="{!gus.Email__c}" title="email"/></td>
  
  <td>
<apex:outputText >Tilte</apex:outputText></td>
<td>
  <apex:inputText value="{!gus.Title__c}" title="title"/></td>
  </tr>
 
  <tr>
<td>
<apex:outputText >Phone</apex:outputText></td>
<td>
  <apex:inputText value="{!gus.Phone__c}" title="phone"/></td>
  <td>
<apex:outputText >Email Optout</apex:outputText></td>
<td>
  <apex:inputCheckbox value="{!gus.Email_Optout__c}" title="Emailoptout"/></td>
  </tr>
  
</table>

<h2>My Interestes</h2>

<table border="0" cellspacing="5" cellpadding="5">

<tr>
<td>
<apex:inputCheckbox value="{!gus.After_Markets_interests__c}"/>
</td>
<td>
<apex:outputText >After Markets Interests</apex:outputText>
</td>
<td>
<apex:inputCheckbox value="{!gus.Manufacturing_interests__c}"/>
</td>
<td>
<apex:outputText >Manufacturing Interests</apex:outputText>
</td>
</tr>

<tr>
<td>
<apex:inputCheckbox value="{!gus.D_O_interests__c}"/>
</td>
<td>
<apex:outputText >D&amp;O Interests</apex:outputText>
</td>
<td>
<apex:inputCheckbox value="{!gus.RealEstate_interests__c}"/>
</td>
<td>
<apex:outputText >Real Estate Interests</apex:outputText>
</td>
</tr>

</table>
<apex:commandButton value="Submitt"  action="{!save}" title="submitt"/>&nbsp;&nbsp;
<apex:commandButton value="Cancel" action="{!cancel}" title="cancel"/>
</apex:form>
</center>
 </body>
 </html>
<!--</apex:pageblock>-->
 </apex:page>

 

 

controller for page 2 : this will handle the populating the data using get methods.

 

 

global with sharing class preferenc 
{

    public String cancel { get; set; }

    public String save { get; set; }

    public PageReference cancel() {
        PageReference p = Page.user_preference;
         p.setRedirect(true);
          return p;
    }


    

 public string guestid;
    public guestuser__c gus{get;set;}

    public preferenc() 
    {
    this.guestid=ApexPages.currentPage().getParameters().get('paramID');   
        if(guestid!=null||guestid!='')
        {
            getdetails(guestid); 
        }   

    }

    
    
    public void getdetails(string guestid)
    {
        List<guestuser__c> guests=[select id,Email__c,Phone__c,Title__c,Email_Optout__c,A_H_interests__c,After_Markets_interests__c,Construction_interests__c,D_O_interests__c,Energy_interests__c,Environmental_interests__c,Financial_Enterprises_interests__c,Healthcare_interests__c,Manufacturing_interests__c,Property_interests__c,RealEstate_interests__c,Technology_interests__c,Windstorm_notification_interests__c from guestuser__c where id=:guestid];
        if(guests.size()>0)
        {
            gus=guests[0];
        }
        else
        {
            
        }
    }
    public PageReference save()
    {
        
          update gus;
          PageReference t = Page.thanks;
          t.setRedirect(true);
          return t;  
    } 
    
    static testMethod void testpreferenc()
    {
       guestuser__c gu = new guestuser__c(Last_Name__c = 'john',Email__c = 'abc@abc.com',Company__c = 'test',Title__c = 'developer',First_Name__c='abc',Street__c='golf',City__c='okc',State__c='ok',Country__c='usa',Zipcode__c='48326',Phone__c='4056138499',Password__c = 'abcd');
       insert gu;
       
       lead testld = new lead(LastName = 'dog',Email = 'abc@abc.com',Company = 'zurich',Status =  'open');
       insert testld;
       
       Account testAccount1 = new Account(RecordTypeId ='01280000000Pxf7',Name ='Test Accounts1');
       insert testAccount1;
       
       
       Contact testCon = new Contact(RecordTypeId = '01280000000Pxex',AccountId = testAccount1.id,LastName ='abcd',Email = 'abc@abc.com',Last_Email_Opened_Date__c = System.today(),HelpPoint_Delivered__c = False);
       insert testCon;
       
       xtma_Individual_Email_Result__c xtma1= new xtma_Individual_Email_Result__c(Date_Time_Sent__c = System.today(), Contact__c = testCon.Id);
        insert xtma1;
        
        xtma_Individual_Email_Result__c xtma2= new xtma_Individual_Email_Result__c(Date_Time_Opened__c = System.today(), Contact__c = testCon.Id);
        insert xtma2;
        
        xtma_Individual_Email_Result__c xtma3= new xtma_Individual_Email_Result__c(Date_Unsubscribed__c = System.today(), Contact__c = testCon.Id);
        insert xtma3;
        
        xtma_Individual_Email_Result__c xtma4= new xtma_Individual_Email_Result__c(Date_Bounced__c = System.today(), Contact__c = testCon.Id);
        insert xtma4;
       
       ApexPages.currentPage().getParameters().put('paramID',gu.id);
       preferenc controller = new preferenc();
       controller.save(); 
          
       controller.cancel();
      delete testld;
      
      
       controller.save(); 
          
       controller.cancel();
      
      
       }
    
}

 in this controller getdetails() takes care of populating the data part. 

 

 

Evan DonovanEvan Donovan

Thanks for sharing - so if I understand correctly, you are creating a custom object that stores the data temporarily, and then it is saved as a contact when the user submits the second form?

 

There are two more general questions that I have:

 

1) Is it possible to open up your Salesforce install so that users from your external site can log in with privileges only to update their own record?

 

If that is not possible, then...

 

2) Is it possible to change the preferences on the Lead object so that a site Guest User can update an existing Lead (?id=[LeadID]), not just create a new Lead, or view an existing one?

Evan DonovanEvan Donovan

OK, I looked at your code in a little more detail - so is GuestUser a custom object that you created? And that is the object in which the data is stored until the user logs in again to populate with more data, at which time a contact record is saved?

 

If I were to create code that was similar to this, how would I deploy it onto my production site? This is my first week using Salesforce, so I don't yet know how to get Apex code onto production.

 

Thanks for all your help.

krishnagkrishnag

using sites you cannot update a standard object record. So what i did is i created a guest object to store the records.i wrote a trigger for updating the records of leads or contacts depending on their existence based on email id. Actually the scenario is pretty big to explain.:smileywink:

krishnagkrishnag

deploying a code to production can be done in two ways using eclipse and using deployment  functionality in salesforce instance,

Evan DonovanEvan Donovan

Thanks, krishnag for your information. We have decided to go with the FormAssembly app since it doesn't require custom code.