The Ultimate Visualforce Events Tab - Almost
Check old blog posts, and you’ll see that I’ve been working on custom Events and Task tabs for a while now. A Task Visualforce tab (that mimics the Task box on the Home Page) is almost ready to come out, but the Events Enhanced List tab is (pretty much) here!
This bears emphasizing: Enhanced Lists were initially not fully released for Activity/Event/Task objects, but are available now.
The code is ridiculously simple, thanks to the apex:EnhancedList Visualforce tag:
<apex:page standardController="Task" > <apex:enhancedList type="Activity" height="800" rowsPerPage="50" /> </apex:page>
See? Nothing to it! Or so we thought. There are some catches (there always are):
- The original use-case required displaying all upcoming events without the header or sidebar. We still cannot do this. Quoting from the Winter ‘09 Release Notes: The enhancedList component is not allowed on pages that have the attribute showHeader set to false.
- We’d like to create a custom tab for this page. We create a Visualforce Tab, pick a custom icon, and show the page… and when I click on the tab, the enhanced list is displayed, but the tab is not highlighted. Also, the custom icon I chose is not displayed. How do we highlight our tab?
After making the page, we make the tab as desribed above. Then we RETURN to the page and add a tabstyle modifier to the apex:page tag, like so:<apex:page standardController="Task" tabstyle="enhanced_activities__tab"> <apex:enhancedList type="Activity" height="800" rowsPerPage="50" /> </apex:page>
[Of course, change the tab name to whatever you choose.]
Success? Not quite. There’s another catch:
- The tab is highlighted (brown in our case), but the color and icon for the enhanced list are standard green/home.
Sadly, I have no workaround for this one. Sorry.
To repeat: Enhanced lists were not initially fully available for Events and Tasks, but now do support them.
Moving forward, consider if you want to create a particular enhanced list view instead of calling the standard enhanced Activity list as I have done here. If you would prefer to make a custom enhanced list view, then you will need to add more code, but that is beyond the scope of this post.
Enjoy!
Force.com Sites Guest User Profile Permissions
I’m working on an event registration application for the Sites Developer Challenge, and it involves a validation that the registrant’s email exists in a Contact record. Remembering that Steve Andersen had run into some obstacles with Contact.Email visibility, I decided to check the guest profile for Contact Field Level Security. Here’s what I found:

Guest profile Contact Field Level Security
If you squint a bit, you can see that the Opt-Out and Email fields are hidden to the guest user. I have no idea why these, in particular, are hidden. Likewise, I couldn’t find a pattern in which fields were shown on the custom objects I had created, nor which were visible on standard objects.
In any event, I don’t have any pearls of wisdom on this topic; this is more of an informative note to all that are using Sites (especially if you plan to do any communication-subscriptions) to check out the Field-Level Security.
For those wondering how to get to this Profile (since it is not visible in the usual Profile section), go to the Sites page > Site Name or URL > Public Access Settings (a button).
Inline Visualforce Page Layouts!
We’re all used to using inline S-Controls, dragging and dropping them into page layouts. And the entire Salesforce community has been spending tons of time recreating page layouts in Visualforce, just to edit one small piece of a page.
As an example, how would you implement the example at developer.force.com: Visualforce Dynamic Edit Page? You would do it the way it was explained in the blog post!
Well the rules of the game have changed.
As long as you use a Standard Controller, you can now place Visualforce pages IN regular page layouts!
Inline Visualforce Page Layout screenshot
The article was written by Sati Hillyear, who is also an expert on the License Manager Application. Check it out!
Project: Change Owner Button in Visualforce
Salesforce Labs has put out a series of Mass Action packages on the AppExchange. There is Mass Transfer Opportunity Owner (uses AJAX), Mass Update Contact Addresses (AJAX), Mass Update Opportunity Owner, Mass Update Opportunity Close Dates, etc. All of these are “thick client” tools, meaning that data must be loaded onto your computer, altered, and then uploaded back to Salesforce.
Ron Hess released a super bit of code, found in the Visualforce documentation and elsewhere, to Mass Update Opportunity Stage and Close Date. It could, theoretically, be expanded to other fields as well. This got me thinking about doing so with other objects.
A while ago, I took the code for the Mass Delete button and altered it to change the owner of the selected records to the User clicking the button. It was like an Accept button, but I could use it for any object. Actually, it wasn’t as easy as that. I had to make one button for each object, and maintenance was a pain–whenever I created a new object, I needed to clone my code.
Drawing upon some code I found in the Developers Guide, I have written a Visualforce page to mass-change the owner of all selected records to any active User in Salesforce. Yes, it only works with Contacts for now, but my next step will be to use Dynamic Apex to pass the sObject name to the page and its extension/controller, allowing me to reuse one bit of code for multiple objects. We’ll see how it goes. But in the meantime, enjoy this page that lets you perform a search, check which records you want to transfer, and then input a User. I’ve tested it with 50 records at once, so that should suffice for most uses.
VF Page:
<apex:page standardController="Contact" recordSetVar="Contacts" id="updateOwnerPage">
<apex:form>
<apex:sectionHeader title="Change Owner for Contacts"/>
<apex:pageBlock mode="edit">
<apex:pageMessages />
<apex:pageblockSection title="Change" columns="1">
<apex:pageblockSectionItem >
<apex:outputLabel for="owner">New Owner</apex:outputLabel>
<apex:inputField id="owner" value="{!Contact.OwnerId}"/>
</apex:pageblockSectionItem>
</apex:pageBlockSection>
<apex:pageBlockSection title="Selected Contacts" columns="1">
<apex:pageBlockTable value="{!selected}" var="j" bgcolor="#F3F3EC" width="100%"
styleClass="list" rowClasses="dataRow" onRowMouseOver="hiOn(this);" onRowMouseOut="hiOff(this);">
<apex:column >
<apex:facet name="header">Contact Name</apex:facet>
<apex:outputLink value="{!URLFOR($Action.Contact.View, j.id)}">
{!j.FirstName} {!j.LastName}</apex:outputLink>
</apex:column>
<apex:column >
<apex:facet name="header">Account Name</apex:facet>
<apex:outputLink value="{!URLFOR($Action.Account.View, j.Account.id)}">
{!j.Account.Name}</apex:outputLink>
</apex:column>
<apex:column>
<apex:facet name="header">Current Owner</apex:facet>
{!j.Owner.Name}
</apex:column>
</apex:pageBlockTable>
</apex:pageblockSection>
<apex:pageBlockButtons location="bottom">
<apex:commandButton value="Save" action="{!save}"/>
<apex:commandButton value="Cancel" action="{!cancel}"/>
</apex:pageBlockButtons>
</apex:pageBlock>
</apex:form>
</apex:page>
Button:
Go to Setup -> Contact -> Buttons and Links
Create a new button, set it to execute in the current window with sidebar and header, and set it to call a Visualforce page. Select the page you just created. Then add the button to Contact Search Layout and to any Contact related lists you like.
Voila!
Salesforce Order of Execution
I came across this page in the Apex documentation and wanted to share it with everyone. So many people have asked about this in the past, so it seems a good idea to publicize it:
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_order_of_execution.htm
Triggers and Order of Execution
When a record is saved with an insert, update, or upsert statement, the following events occur in order:
1. The original record is loaded from the database (or initialized for an insert statement)
2. The new record field values are loaded from the request and overwrite the old values
3. All before triggers execute
4. System validation occurs, such as verifying that all required fields have a non-null value, and running any user-defined validation rules
5. The record is saved to the database, but not yet committed
6. All after triggers execute
7. Assignment rules execute
8. Auto-response rules execute
9. Workflow rules execute
10. If there are workflow field updates, the record is updated again
11. If the record was updated with workflow field updates, before and after triggers fire one more time (and only one more time)
12. Escalation rules execute
13. All DML operations are committed to the database
14. Post-commit logic executes, such as sending email
Additional Considerations
Please note the following when working with triggers:
* When Enable Validation and Triggers from Lead Convert is selected, if the lead conversion creates an opportunity and the opportunity has Apex before triggers associated with it, the triggers run immediately after the opportunity is created, before the opportunity contact role is created. For more information, see “Customizing Lead Settings” in the Salesforce online help.
* If you are using before triggers to set Stage and Forecast Category for an opportunity record, the behavior is as follows:
o If you set Stage and Forecast Category, the opportunity record contains those exact values.
o If you set Stage but not Forecast Category, the Forecast Category value on the opportunity record defaults to the one associated with trigger Stage.
o If you reset Stage to a value specified in an API call or incoming from the user interface, the Forecast Category value should also come from the API call or user interface. If no value for Forecast Category is specified and the incoming Stage is different than the trigger Stage, the Forecast Category defaults to the one associated with trigger Stage. If the trigger Stage and incoming Stage are the same, the Forecast Category is not defaulted.
Apex - The Basics
Jon Mountjoy has written another super post over at developer.force.com. This one is titled An Introduction to Apex. It goes through some of the basics of the language and provides some examples.
Everyone should read this; beginners will get a better orientation than otherwise available, and experienced Apex developers will probably also learn a thing or two.
How to Deploy QUICKLY Between Orgs
I just came across one of the most useful posts on developer.force.com that I have ever seen:
Jesse Lorenz provides full instructions (along with a best-practice) on deploying quickly from one org to another using the Eclipse IDE.
Read it at http://wiki.apexdevnet.com/index.php/Deploy_Force.com_Applications_Faster. You’ll be glad you did.
[Update: Jesper Joergensen just wrote a super follow-up on deployments in the upcoming Winter 09 release at http://blog.sforce.com/sforce/2008/09/set-up-orgs-4-t.html
Convert between Business and Person Accounts (B2B <-> B2C)
I’m a huge fan of Person Accounts (Salesforce’s phenomenal combination of Account and Contact that allows selling B2C–the best example I use is Land’s End, which sells to people). Orgs can use a hybrid model, allowing a company to track its, e.g. partner companies (B2B) and individual customers (B2C).
There is an interesting limitation to Person Accounts: They cannot be converted to B2B via the Salesforce front-end. The record type can only be changed via the API, using a tool like Data Loader or the Excel Connector. Additionally, a B2B can only be converted to a B2C if it has:
- One Contact
- No Parent Account
- Nothing in Reports To on the Contact record
I set out to create a tool that would use the API to convert the record type of a B2B to B2C and back.
And there was a hitch. (There always is.) I wrote javascript buttons to be included on B2B or B2C page layouts, and it worked perfectly in my org. However, I could not upload it to the AppExchange because one cannot create a package that references B2C:
Note: You cannot upload packages that contain any of the following:
• References to person accounts, such as an s-control or custom field referencing person accounts.
• Workflow rules or workflow actions (such as field updates or outbound messages) that reference record types.
(Side note: Why not just require an org to have Person Accounts enabled, and then allow references to B2C?)
Anyway, I can’t upload the package, but I can show the code here.
- Create a custom button or link on the Account object. Set it to execute javascript.
- Paste the following code into the body and copy the appropriate RecordTypeId where indicated.
- Place the button or link on page layouts, and go for it! Remember to put the button to convert to B2C only on B2B page layouts, and vice versa.
{!REQUIRESCRIPT("/soap/ajax/13.0/connection.js")}
var AccountObj = new sforce.SObject("Account");
AccountObj.Id = '{!Account.Id}';
AccountObj.RecordTypeId = '0120000000000000'; // Paste B2B/C RecordTypeID
sforce.connection.update([AccountObj]);
location.reload(true);

Screenshot of code in org.
Activities Tabs - Enhanced View and One Set of Tabs
What was I thinking? Using something as complicated as a hijacked (from the Console) Task view was bound to have problems when creating an Activities tab.
Let’s restate our goals:
- Create a tab that will show Activities, using the Enhanced Lists view.
- Don’t have two rows of tabs at the top of the page.
Question: Is there any way to make a view and to specify that we don’t want to see the Sidebar AND the Tabs?
Answer: YES. The answer is Visualforce!
We will use Visualforce’s iframe tag to fool the UI into thinking that it’s displaying a URL other than the one it thinks it’s displaying.
Step 1: Enable Developer mode. Then create a Visualforce page. I called mine Activities, so the URL is [instance]/apex/Activities
<apex:page standardController="Event" tabStyle="Event" sidebar="false" showHeader="false" name="Activities" label="Activities">
<apex:stylesheet value="/dCSS/Theme2/default/common.css"/>
<apex:panelGrid width="100%" columns="1" id="exitLink" bgcolor="#EFEFEF">
<apex:outputLink value="/home/home.jsp" id="homeLink">Exit this view</apex:outputLink>
</apex:panelGrid>
<apex:iframe src="/007" height="900px" scrolling="true" id="theIframe"/>
</apex:page>
Notes on the code:
- If you remove the height tag, it defaults to 100%, but that’s in relation to the number of rows in your list. So the Sidebar may be cut off if you have too few rows. Stick with a standard height. I chose 900 because I assume that most screens are 1280×1024 resolution, minimum.
- I used 007 (the object ID for Activities), but I could have used 00T (Tasks).
- If you click on anything in the page, the URL will remain /apex/Activities. This is because you are technically working within an IFrame. This is the reason for the Exit link.
- The code calls the standard stylesheet so that it comes up in Salesforce’s preferred Arial font instead of Times New Roman.
- I created a table with one column for the Exit link so that I could color the background of the link the same as the top of a Salesforce page; this is purely for cosmetic reasons.
Now we’ll create a Visualforce Tab:
Setup -> Create -> Tab
Scroll to the bottom of the page
New Visualforce Tab
Select the Activities page from the picklist
Name: Activities
Label: Activities
Choose an icon (I liked the whistle) but keep in mind that it doesn’t matter because we’re using the Events controller, so the page will have the Events green color.
Finish the wizard, and you’re done!
Here are my favorite parts of the setup:
- It uses Visualforce.
- A standard controller means no Apex classes are required.
- The code can be used in any org as-is.
- We use a full-sized IFrame to fool the Visualforce page into thinking that it’s displaying something other than a fully customized VF view!
Google Docs Now Has Templates for Google Apps
I use templates for most of my documentation–it’s just easier to write a ROF or a configuration plan when all the standard information is already there. Up to this point, short of using Salesforce Content or DreamTeam, I haven’t seen many options for version control through Salesforce. Until now.
Google Docs has templates, and those of us using Google Apps with our Salesforce org (which should be almost everyone, since it’s free and easy to use) can design company-wide templates. This, combined with Google Docs’ super collaborative features, should make things much easier for consultants.
Here’s my wishlist for this feature: Use the Google-Salesforce Toolkit to create a spreadsheet with each worksheet representing an object and each row a field. (It would probably use a Describe function, etc.) Include columns for things like label, name, length, type, picklist values, etc. I don’t know how to code it myself, but it would be awesome to use. If we had one for a fresh, pristine org as a template, then we could use that for requirements-gathering with clients, creating the template in Google Docs and then doing the configuration based upon that spreadsheet.




