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.
Salesforce CRM “Locale” Field
Most of the people reading this are probably in the United States, so on our User record, we have Locale set to “English (US).” This has a few effects on how we see Salesforce data, including the Calendar.
I wanted to change the first day of my week to Monday, and to see my weekends on the right-side of the 7-day view. I’ve started doing this on my Google and Outlook calendars, so why not be consistent? To do this, I changed my Locale to “English (United Kingdom).”
There’s a catch (there always is!): My dates are now reversed. D’Oh!
Time will tell if I have any other major changes to the org. I don’t mind British spellings (colour vs. color) — though I’ve found the word “color” three times since I switched. The org currency will remain US Dollars, as that is set elsewhere, in the Company Profile.
So what will I do, on the whole? I need to decide if the date format is more or less important than the week format. I’ll try out this UK thing… and will decide later.
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.
Winter 09 Full Training Orgs
Sure, prerelease orgs are nice, but something’s always lacking. We have to go in and enable all the cool features, which is nice in that we learn them better, but it’s also nice to get to play in a full-featured org. Salesforce CRM (the new name) has had Exercises to teach us what to do, and I’m sure they will again this time…
Meanwhile, I stumbled upon an even better treat: Winter 09 TRAINING orgs. Yes, orgs with tons of data and all the add-ons you could ever want:
Salesforce Content
Customer Portal
Partner Portal
Advanced Currency Management
Custom Fiscal Year
Translation Workbench (and international Apex features)
Outlook Connect 3.2.501 (new version)
Cool orange highlighting of fields I’m editing in the setup area
Recruiting App
QuotePDF App
Bug Tracking
Time Card (??)
A/R Invoice
…AND all the new stuff from Winter09
Where is this? I’ll tell you:
Standard Prerelease org: https://prerelwww.pre.salesforce.com/form/trial/prerelease_winter09.jsp
Premium Training org: https://prerelwww.pre.salesforce.com/form/trial/training_winter09.jsp
Winter 09 (156) - New And Updated Documentation
More Winter 09 documentation has been released. Scott Hemmeter wrote a post listing some of the pages containing new content, but I wanted to go a bit in-depth on those and some other parts of developer.force.com.
Documentation
This should be your first stop whenever you have any questions about ANYTHING on the Platform. It has sections on Web Services API (formerly just called API, to distinguish it from Metadata API), Metadata API, Apex, Visualforce, AJAX, Office Toolkit, Force.com Migration Tool, IDE, and the Library.
Core Resources
In addition to a super Documentation page, force.com has a new section which contains, well, resources sectioned by the Platform’s service categories: Logic (Apex), User Interface (Visualforce), Database (Objects, formulas, triggers, etc.), Integration (API, REST), Services –What? We now have Services as a Service?–(Workflow), Packaging and Distribution (AppExchange), Development (Metadata), and Tools (IDE, Force.com Builder, Data Loader).
Now that we’ve seen my two favorite pages, let’s look at the content on the Documentation page:
- Web Services API - No longer in Prerelease, the 14.0 documentation is finalized for 156. Version 13.0 is still online.
- Metadata API - Also no longer in Prerelease, version 14.0 is available. Don’t worry; version 13.0 is still available!
- Visualforce - Also no longer in Prerelease. View Online or PDF.
- Question: Why “release” the prerelease version when it has things we can’t use in Summer 08 orgs? Seems premature.
- Apex - Same story: Version 14.0 is ready, but I can’t find 13.0 online. I guess it doesn’t matter much, except to those of us coding in 154 orgs who might use 156 features.
- AJAX - This one is available in 14.0 and 13.0 flavors.
Note: For those of you wondering about all the 13.0/14.0 and 154/156 references, here’s a guide:
With each release, Salesforce CRM (the new name for the application) increments two numbers.
Releases are generally three times a year, and increment the release number by TWO. Yes, we have only even numbers. So Winter 09 is 156, Winter 08 was 150, Summer 06 was 142, etc. Releases are in Winter, Spring, and Summer of each year, named according to the season in San Francisco, the site of salesforce.com’s corporate headquarters. Counting backwards, some say that the original release was 62. I have no idea why that number was chosen. Of note, salesforce.com refers to its org as 62; maybe that has something to do with it. My bet is that salesforce.com has Unlimited Edition, by the way. Just a hunch.
API versions are incremented by 1 each release. There have been some smaller releases, which is why you might find references to #.1 here and there. As you can see, Summer 08 was version 13, and Winter 09 is version 14.
This is my question: Why do we call the release Winter 09 when it is clearly coming out in 2008? I don’t have an answer to that; does anyone?
Winter 09 Main Page
This is my starting point for all things 156, though I wish the links worked. For more information on specific features, download the PDF files in the sidebar of this page.
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




