+ Start a Discussion
Denise CrosbyDenise Crosby 

visualforce event to create dynamic SOSL creating event using custom controller

Hello. I am creating a custom controller to insert an event. I understand it has to be a custom controller so it can be fired from a global action on Salesforce1. I need Visualforce to fire an event when either the Contact (whoid) or Account (whatid) is selected on the page so that I can dynamically create the SOSL to restrict the Contact or Account to those that are related to each other. Users should not be able to select a Contact unrelated to an Account. How can I do this? Thanks so much.

VisualForce:
<apex:page controller="NewEvent">
<apex:form >
<apex:pageBlock title="Event Details">

<apex:pageMessages />
<apex:pageBlockSection title="Event Information">
    <apex:inputfield value="{!ev.subject}"/>
    <apex:inputfield value="{!ev.description}"/>   
    <apex:inputfield value="{!ev.startdatetime}"/>
    <apex:inputfield value="{!ev.enddatetime}"/>
    <apex:inputfield value="{!ev.whoid}"/>
    <apex:inputfield value="{!ev.whatid}"/>  
</apex:pageBlockSection>
        
<apex:pageBlockbuttons >
   <apex:commandbutton value="Save" action="{!save}"/>    
</apex:pageBlockbuttons>    
    
</apex:pageBlock>
</apex:form>
</apex:page>

Apex:
public class NewEvent {

public event ev { get; set; }
    
public newevent (){
    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());   
}
    
public PageReference save() {
      return new ApexPages.StandardController(ev).save();
  }    
}
Best Answer chosen by Denise Crosby
Glyn Anderson 3Glyn Anderson 3
Denise,  The code below implements the functionality I described.  I turned your controller into a controller extension so that we can use the standard Event controller.  This will let you use the page as an override to the NewEvent action, if you want.  The controller uses a dummy Contact record to capture the Account for the Event, because the Event's WhatId field can be many different types, and we want to restrict it to Accounts.  Anytime the Account changes, the page rerenders a picklist of Contacts.  The picklist is not shown if there is no Account, or if the Account has no Contacts.  Whenever the Contact changes, the Event record is modified accordingly.  I also added the Cancel button to give the user a way to back out.  Let me know if you have any questions.  I'm happy to explain the implementation or help you modify it.

<pre>
<apex:page standardController="Event" extensions="NewEventController">
<apex:form >
<apex:pageBlock title="Event Details">

<apex:pageMessages />
<apex:pageBlockSection title="Event Information" id="eventInformation">
    <apex:inputfield value="{!Event.Subject}"/>
    <apex:inputfield value="{!Event.Description}"/>

    <apex:inputfield value="{!Event.StartDateTime}"/>
    <apex:inputfield value="{!Event.EndDateTime}"/>

    <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}">
        <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}"/>
   <apex:commandbutton value="Cancel" action="{!cancel}"/>
</apex:pageBlockbuttons>

</apex:pageBlock>
</apex:form>
</apex:page>


public class NewEventController
{
    private Event event;

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

    public String contactLabel
    {
        get { return Contact.sObjectType.getDescribe().getLabel(); }
    }

    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 NewEventController( ApexPages.StandardController controller )
    {
        event = (Event) controller.getRecord();
        event.CurrencyIsoCode = UserInfo.getDefaultCurrency();
        event.OwnerId = UserInfo.getUserId();

        DateTime now = Datetime.now();
        event.StartDateTime = now.addMinutes( -now.minute() ).addSeconds( -now.second() );
        event.EndDateTime = event.StartDateTime.addMinutes( 60 );

        if ( event.WhatId != null && event.WhatId.getSObjectType() == Account.sObjectType )
        {
            dummyContact.AccountId = event.WhatId;
        }
    }

    public void changeAccount()
    {
        event.WhatId = dummyContact.AccountId;
        event.WhoId = null;
        contactOptions = null;
    }

    public void changeContact()
    {
        event.WhoId =
        (   ( contactId != null && contactId != 'null' )
        ?   Id.valueOf( contactId )
        :   null
        );
    }
}
</pre>
 

All Answers

Glyn Anderson 3Glyn Anderson 3
Denise,  I can imagine a solution where you don't display the Who field until after a selection is made in the What field.  Would that work for you?

The idea is to use an actionSupport tag to call an action method in your controller when the What value changes (onchange).  It would rerender that part of the page to reveal the "Who" field, which is actually a picklist of the Contacts related to the selected Account.  On save, the controller would have to populate the actual WhoId field based on the selected Contact.  It sounds complicated, but isn't really.  Let me know if this might work for you and I'll see if I have time to write some code for you.
Denise CrosbyDenise Crosby
Hi Glyn,
Thanks for this information. Yes, that should work fine. If you could share some code snippets or examples, that would be very helpful to me. Thank you so much!
Denise
Glyn Anderson 3Glyn Anderson 3
Denise,  The code below implements the functionality I described.  I turned your controller into a controller extension so that we can use the standard Event controller.  This will let you use the page as an override to the NewEvent action, if you want.  The controller uses a dummy Contact record to capture the Account for the Event, because the Event's WhatId field can be many different types, and we want to restrict it to Accounts.  Anytime the Account changes, the page rerenders a picklist of Contacts.  The picklist is not shown if there is no Account, or if the Account has no Contacts.  Whenever the Contact changes, the Event record is modified accordingly.  I also added the Cancel button to give the user a way to back out.  Let me know if you have any questions.  I'm happy to explain the implementation or help you modify it.

<pre>
<apex:page standardController="Event" extensions="NewEventController">
<apex:form >
<apex:pageBlock title="Event Details">

<apex:pageMessages />
<apex:pageBlockSection title="Event Information" id="eventInformation">
    <apex:inputfield value="{!Event.Subject}"/>
    <apex:inputfield value="{!Event.Description}"/>

    <apex:inputfield value="{!Event.StartDateTime}"/>
    <apex:inputfield value="{!Event.EndDateTime}"/>

    <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}">
        <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}"/>
   <apex:commandbutton value="Cancel" action="{!cancel}"/>
</apex:pageBlockbuttons>

</apex:pageBlock>
</apex:form>
</apex:page>


public class NewEventController
{
    private Event event;

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

    public String contactLabel
    {
        get { return Contact.sObjectType.getDescribe().getLabel(); }
    }

    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 NewEventController( ApexPages.StandardController controller )
    {
        event = (Event) controller.getRecord();
        event.CurrencyIsoCode = UserInfo.getDefaultCurrency();
        event.OwnerId = UserInfo.getUserId();

        DateTime now = Datetime.now();
        event.StartDateTime = now.addMinutes( -now.minute() ).addSeconds( -now.second() );
        event.EndDateTime = event.StartDateTime.addMinutes( 60 );

        if ( event.WhatId != null && event.WhatId.getSObjectType() == Account.sObjectType )
        {
            dummyContact.AccountId = event.WhatId;
        }
    }

    public void changeAccount()
    {
        event.WhatId = dummyContact.AccountId;
        event.WhoId = null;
        contactOptions = null;
    }

    public void changeContact()
    {
        event.WhoId =
        (   ( contactId != null && contactId != 'null' )
        ?   Id.valueOf( contactId )
        :   null
        );
    }
}
</pre>
 
This was selected as the best answer
Denise CrosbyDenise Crosby
Thank you Glyn. I was able to get this working in my org and it looks good! Is there a simple way to convert this to a custom controller? I need to use this code for a Global Action on Salesforce1. Thank you so much for your wonderful help.
Glyn Anderson 3Glyn Anderson 3
Absolutely!  You should be able to replace my constructor with your original constructor.  Or you could just add your constructor, and then you can use the class as either a custom controller or a controller extension.  Be sure to change the name to 'NewEventController'.  Put your original 'save()' method back in.  You'll have to replace your use of 'ev' with 'event'.

On the page, replace 'Event.xxx' with '{!event.xxx}'; and in the apex:page tag, replace the 'standardController' and 'extensions' attributes with 'controller="NewEventController"', similar to what you had originally.
Denise CrosbyDenise Crosby
Hi Glyn,
I think I'm out of my league with this one. I am trying to add my constructor to your code, so I can use it as either a custom controller or a controller extension. In this case, I would need two pages? One for overriding the NewEvent action, and another for the mobile global action? I tried following your instructions, but it does not compile. There's probably something simple that I'm missing. Can you help me again? I really appreciate it.
(Also, sorry for the delay but I just got my power back after the Harvey storm).
 
<apex:page controller="NewEventController">
<apex:form >
<apex:pageBlock title="Event Details">

<apex:pageMessages />
<apex:pageBlockSection title="Event Information" id="eventInformation">
    <apex:inputfield value="{!Event.Subject}"/>
    <apex:inputfield value="{!Event.Description}"/>

    <apex:inputfield value="{!Event.StartDateTime}"/>
    <apex:inputfield value="{!Event.EndDateTime}"/>

    <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}">
        <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}"/>
   <apex:commandbutton value="Cancel" action="{!cancel}"/>
</apex:pageBlockbuttons>

</apex:pageBlock>
</apex:form>
</apex:page>

public class NewEventController
{
    private Event event;

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

    public String contactLabel
    {
        get { return Contact.sObjectType.getDescribe().getLabel(); }
    }

    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 NewEventController( ApexPages.StandardController controller )
    {
        event = (Event) controller.getRecord();
        event.CurrencyIsoCode = UserInfo.getDefaultCurrency();
        event.OwnerId = UserInfo.getUserId();

        DateTime now = Datetime.now();
        event.StartDateTime = now.addMinutes( -now.minute() ).addSeconds( -now.second() );
        event.EndDateTime = event.StartDateTime.addMinutes( 60 );

        if ( event.WhatId != null && event.WhatId.getSObjectType() == Account.sObjectType )
        {
            dummyContact.AccountId = event.WhatId;
        }
    }
        
    public NewEventController ()
    {
        event = new event();
        event.CurrencyIsoCode = UserInfo.getDefaultCurrency();
        event.OwnerId = UserInfo.getUserId();
        event.StartDateTime = Datetime.now().addMinutes(-Datetime.now().minute());
        event.EndDateTime = Datetime.now().addMinutes(60-Datetime.now().minute());   
	}
    
    public PageReference save() {
      return new ApexPages.StandardController(event).save();
  	}   

    public void changeAccount()
    {
        event.WhatId = dummyContact.AccountId;
        event.WhoId = null;
        contactOptions = null;
    }

    public void changeContact()
    {
        event.WhoId =
        (   ( contactId != null && contactId != 'null' )
        ?   Id.valueOf( contactId )
        :   null
        );
    }
}



 
Denise CrosbyDenise Crosby
Glyn,
I was able to get this working as a custom controller. Thank you!
Denise CrosbyDenise Crosby
Hi Glyn,
I was hoping you might be available to offer advice with my code. I have a lot of your code that I'm using and I've made a few modifications. The page is already in production and I'm training our executives on it next week. The page has some strange behavior in SF1 though and I'm not sure how to solve them. Would you have any availablility to assist? I would greatly appreciate it.