Ask Search:
Denise CrosbyDenise Crosby 

vf custom controller create event navigate to create contact

Hi Salesforce experts,
I am fairly new to Salesforce development. I created a NewEvent VF page with a custom controller to create an event as a global action. I had to do this because of a requirement that the contact for the event had to be associated with the account for the event. Everything was working fine, but now I have a new requirement to allow creation of a new contact from my VF page if the contact does not exist. I don't know which direction to go with some of these questions:
1. How do I save the information entered on my VF NewEvent page if the user presses the New Contact button?
2. After saving or cancelling out of the New Contact screen, how do I get my user back to my NewEvent VF page? I've tried the saveURL on the commandbutton action with no success.
3. I'm hoping I don't have to create a new VF page to create a contact. There has to be an easier way.

Thanks for helping. 
Best Answer chosen by Denise Crosby
Arpit JainArpit Jain
Hi Denise,

You need to customize your VF page as per you requirements as below : 
You should create a new section, which will be rendered only if the New Contact button is clicked.
The below code is a sample code to create a new contact record only, other duplication check logic and rendering things needs to be handled

1. On your VF page, create a new button, whose code would look something  like this : 
<apex:page controller="ContactCreateController">  
  <apex:sectionHeader title="Visualforce Example" subtitle="Create a Contact"/>
  <apex:form >
    <apex:pageMessages /> <!-- this is where the error messages will appear -->
    <apex:pageBlock title="Contact Info">
      <apex:pageBlockButtons >
        <apex:commandButton action="{!save}" value="Save"/>
      </apex:pageBlockButtons>
      <apex:pageBlockSection showHeader="false" columns="2">
        <apex:inputField value="{!contact.firstName}" />
        <apex:inputField value="{!contact.lastName}" />
        <apex:inputField value="{!contact.email}" />
      </apex:pageBlockSection>
    </apex:pageBlock>
  </apex:form>
</apex:page>

And your custom controller code would look something like this: 
public with sharing class ContactCreateController {
    // the contact record you are adding values to
    public Contact contact {
        get {
        if (contact == null)
        contact = new Contact();
        return contact;
        }
        set; }

    public ContactCreateController() {//Blank constructor}

    // save button is clicked
    public PageReference save() {
        try {
            insert contact; // inserts the new record into the database
        }
        catch (DMLException e) {
            ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error creating new contact.'));
            return null;
        }
        // if successfully inserted new contact, then displays the thank you page.
        return Page.Contact_Create_Thankyou;
    }
}



2. Once the user clicks on Save or cancel, you can render the section again. Also when you are taking the input values from user, you can then query the database based on the Email entered (or name), and if that contact already exist, return the existing contact details or else return the newly created contact details .(The above code only creates a new contact record)

3. As discussed above, you dont create a new VF page, but just a section below in the same VF page, which will only be rendered on the particular conditions.

Let me know in case of any issues.
Hope this Helps!!
 

All Answers

Arpit JainArpit Jain
Hi Denise,

You need to customize your VF page as per you requirements as below : 
You should create a new section, which will be rendered only if the New Contact button is clicked.
The below code is a sample code to create a new contact record only, other duplication check logic and rendering things needs to be handled

1. On your VF page, create a new button, whose code would look something  like this : 
<apex:page controller="ContactCreateController">  
  <apex:sectionHeader title="Visualforce Example" subtitle="Create a Contact"/>
  <apex:form >
    <apex:pageMessages /> <!-- this is where the error messages will appear -->
    <apex:pageBlock title="Contact Info">
      <apex:pageBlockButtons >
        <apex:commandButton action="{!save}" value="Save"/>
      </apex:pageBlockButtons>
      <apex:pageBlockSection showHeader="false" columns="2">
        <apex:inputField value="{!contact.firstName}" />
        <apex:inputField value="{!contact.lastName}" />
        <apex:inputField value="{!contact.email}" />
      </apex:pageBlockSection>
    </apex:pageBlock>
  </apex:form>
</apex:page>

And your custom controller code would look something like this: 
public with sharing class ContactCreateController {
    // the contact record you are adding values to
    public Contact contact {
        get {
        if (contact == null)
        contact = new Contact();
        return contact;
        }
        set; }

    public ContactCreateController() {//Blank constructor}

    // save button is clicked
    public PageReference save() {
        try {
            insert contact; // inserts the new record into the database
        }
        catch (DMLException e) {
            ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error creating new contact.'));
            return null;
        }
        // if successfully inserted new contact, then displays the thank you page.
        return Page.Contact_Create_Thankyou;
    }
}



2. Once the user clicks on Save or cancel, you can render the section again. Also when you are taking the input values from user, you can then query the database based on the Email entered (or name), and if that contact already exist, return the existing contact details or else return the newly created contact details .(The above code only creates a new contact record)

3. As discussed above, you dont create a new VF page, but just a section below in the same VF page, which will only be rendered on the particular conditions.

Let me know in case of any issues.
Hope this Helps!!
 
This was selected as the best answer
Denise CrosbyDenise Crosby
Hi Arpit,
Thanks for this really great idea and code. I have implemented it and it's working. I am just stuck on one minor thing...and I'm new to VF/Apex development. After saving the contact with the Insert commandbutton, the contact select list should refresh, ideally with the new contact already selected. Hopefully, this is something simple that I just don't know how to do yet. Would you be so kind as to assist? I would be very grateful.
<apex:page controller="NewEventController1" showHeader="true" sidebar="true" standardStylesheets="true">
<apex:form >
<apex:slds >
        
<div class="slds-scope"> 
<apex:pageBlock title="New Meeting">
<apex:pageMessages />
<apex:pageBlockSection columns="1" id="eventInformation">
    <apex:inputfield value="{!ev.subject}"/> 
    <apex:inputfield value="{!ev.startdatetime}" />     
    <apex:inputfield value="{!ev.description}"/> 
    <apex:inputfield label="{!accountLabel}" value="{!dummyContact.AccountId}" >
        <apex:actionSupport action="{!changeAccount}" event="onchange" rerender="eventInformation" />
    </apex:inputField>
    <apex:selectList label="{!contactLabel}" value="{!contactId}" size="1" rendered="{!showContactOptions}" id="contactselectlist">
        <apex:selectOptions value="{!contactOptions}" />
        <apex:actionSupport action="{!changeContact}" event="onchange" rerender="eventInformation" />
    </apex:selectList>
    <apex:pageBlockSectionItem rendered="{!!showContactOptions}"/>
</apex:pageBlockSection>
        
<apex:pageBlockbuttons >
   <apex:commandbutton value="Save" action="{!save}" immediate="true"/>  
   <apex:commandbutton value="Cancel" action="{!cancel}"/>  
   <apex:commandbutton value="New Contact" action="{!newcontact}"/>      
<!--  <apex:commandButton value="New Contact" action="{!URLFOR($Action.Contact.NewContact)}" /> -->
</apex:pageBlockbuttons>    
    
</apex:pageBlock>
<apex:pageBlock title="Contact Info" rendered="{!RenderContact}" id="contactinformation">
      <apex:pageBlockButtons >
          <apex:commandButton action="{!insertContact}" value="Insert" />
      </apex:pageBlockButtons>
      <apex:pageBlockSection showHeader="false" columns="1">
        <apex:inputField value="{!Newcontact.firstName}" />
        <apex:inputField value="{!Newcontact.lastName}" />
        <apex:inputField value="{!Newcontact.email}" />
      </apex:pageBlockSection>
    </apex:pageBlock>
    
</div>
</apex:slds>       
</apex:form>
</apex:page>


public with sharing class NewEventController1 {

public event ev { get; set; }

public Contact Newcontact {
        get {
        if (Newcontact == null)
        Newcontact = new Contact();
        return Newcontact;
        }
        set; }

public boolean RenderContact { get; set; }
    
public NewEventController1 (){
    RenderContact = false;
    ev = new event();
    ev.CurrencyIsoCode = UserInfo.getDefaultCurrency();
    ev.OwnerId = UserInfo.getUserId();
    ev.StartDateTime = Datetime.now().addMinutes(-Datetime.now().minute());
    ev.EndDateTime = Datetime.now().addMinutes(60-Datetime.now().minute());  
    ev.Subject = 'New Meeting';
    
    if ( ev.WhatId != null && ev.WhatId.getSObjectType() == Account.sObjectType )
        {
            dummyContact.AccountId = ev.WhatId;
        }
}

public Contact dummyContact
    {
        get
        {
            if ( dummyContact == null ) dummyContact = new Contact();
            return dummyContact;
        }
        private set;
    }

    public List<SelectOption> contactOptions
    {
        get
        {
            if ( contactOptions == null && dummyContact.AccountId != null )
            {
                contactOptions = new List<SelectOption>();
                contactOptions.add( new SelectOption( 'null', '--None--' ) );
                for ( Contact contact :
                    [   SELECT  Id, Name
                        FROM    Contact
                        WHERE   AccountId = :dummyContact.AccountId
                    ]
                    )
                {
                    contactOptions.add( new SelectOption( contact.Id, contact.Name ) );
                }
            }
            return contactOptions;
        }
        private set;
    }

    public Boolean showContactOptions
    {
        get { return contactOptions != null && contactOptions.size() > 1; }
    }

    public String contactId { get; set; }
    
	public String accountLabel
    {
        get { return Account.sObjectType.getDescribe().getLabel(); }
    }

    public String contactLabel
    {
        get { return Contact.sObjectType.getDescribe().getLabel(); }
    }
    
	public void changeAccount()
    {
        ev.WhatId = dummyContact.AccountId;
        ev.WhoId = null;
        contactOptions = null;
    }

    public void changeContact()
    {
                
        ev.WhoId =
        (   ( contactId != null && contactId != 'null' )
        ?   Id.valueOf( contactId )
       :   null
        ); 
    }    
    
public PageReference save() {
    
    return new ApexPages.StandardController(ev).save();
  }  
    
public PageReference newcontact() {
      RenderContact = true;
      return null;
  } 
    
public PageReference insertContact() {
      if (dummyContact.AccountId != null)
      	{ NewContact.AccountId = dummyContact.AccountId; }
      insert NewContact;
      ev.WhoId = NewContact.Id;
      return null;
  }      
    
public PageReference cancel() {
      return new ApexPages.StandardController(ev).cancel();
  }     
}