Field Sets – a limitation and a workaround

April 24, 2011

This has been cross posted on the redkitetechonologies.com news blog.

Field sets make so much sense, and I was really looking forward to being able to set up some very easy to maintain code. Unfortunately field sets do have one limitation that I recently ran into. You can’t access them from Apex Code.

To be fair, before Field Sets, you really had no options of displaying a dynamic set of fields on a Visualforce page. Field sets give you some great flexibility which wasn’t there before, so Field Sets should certinly be a part of all your future Visualforce dev design. I only wish it was a one stop shop for my field definitions for both my Visualforce pages and their supporting Apex code.

An example a typical scenario where Field Sets come in handy, is the following. Let’s say you’re creating a Visualforce page that displays some results from an Apex query. In order to change the fields that are shown on the page, or even the order of the fields, you had to get your developer to change both the Visualforce page and/or the Apex query that goes along with it.

So with Field Sets, the fields that are shown on the Visualforce page can now be dynamically configured by a Salesforce Administrator. But what about the Apex query code? From Apex, we can’t access the field set, so we can’t directly know what fields the Visualforce page is now expecting. Is there anyway that we can return the correct fields for the objects that will be displayed by the Field Set?

Yes, there is. The Apex side of the equation already has a load of options for storing configuration data. One approach is to store the field list data in a Custom Setting. The fields that you list should correspond to the field used in the Field Set. The only downside of this approach is the double maintainence that needs to occur. Now when you modify the field set, you also have to remember to change the Custom Setting data too.

So until you can access Field Sets from Apex code, this workaround should allow your Aministrators to add and remove fields from those custom Visualforce pages without having to get developers involved.


Javascript Remoting – A quicker (but different) way to get there

April 11, 2011

This has been cross posted on the redkitetechonologies.com news blog.

Update: I’ve recently recieved a very informative email from Salesforce. In this email, Salesforce explained some of the ideas that went into their design. It made a ton of sense, and I’ll talk about it at the end of this post. And thanks for the info Salesforce!

I recently got Javascript Remoting enabled in my developer org and it’s certainly a good feature to have in your bag of tricks. If you’ve used Visualforce and included a lot of Javascript bell’s and whistle’s, then you undoubtedly came across some situation where you wanted to have the javascript portion of the code kick off something in the Controller.

Traditionally this was done through actionFunctions. One thing I always hated about actionFunctions was what you needed to do to support parameters to these functions. You had to set up parameters in the action function which were bound to some assignable property of the controller. This made the code somewhat harder to read, and you were forced to pollute the controller level namespace with these variables whether or not they belonged there. Javascript remoting does help address this, somewhat, but it does impose some restrictions which may not fit within your code framework.

The following code are two different implementations of the same code. One using an actionFunction and some controller level properties to pass parameter data, and the second is using Javascript remoting. We’ll have javascript pass to the controller a name to search.

actionFunction Version

public with sharing class VFComparisonController {
 public List<account> listOfAccounts{get;set;}
  public String name {get;set;}
        
  public PageReference getAccountsByName(){
   listOfAccounts=[select id, name from Account where Name = :name];
   return null;
  } 
}

<apex:page controller="VFComparisonController" >
 <script type="text/javascript" src="{!$Resource.js_jQueryLib}"/>

 <apex:form >
  <apex:actionfunction name="getAccountsByName" action="{!getAccountsByName}" rerender="resultArea">
   <apex:param name="name" value="" assignTo="{!name}"/>
  </apex:actionfunction>
                
  <script type="text/javascript">
   j$=jQuery.noConflict();
   j$(document).ready(function(){
    getAccountsByName("IBM");
   });
  </script>
                
  <apex:outputPanel id="resultArea" >
   <apex:repeat var="a" value="{!listOfAccounts}" >
    <apex:outputLabel value="{!a.id}, {!a.name}" /> <br/>
   </apex:repeat>
  </apex:outputPanel>
                
 </apex:form>
</apex:page>

Javascript Remoting Version

global with sharing class JSRemotingController {
        
 @RemoteAction
 global static List<account> getAccountsByName(String name){
  List<account> account = [select id, Name from Account where name = :name];
  return account;
 }
}

<apex:page controller="JSRemotingController">
 <script type="text/javascript" src="{!$Resource.js_jQueryLib}"/>
    
 <script type="text/javascript">
  j$=jQuery.noConflict();
  JSRemotingController.getAccountsByName("IBM", function(result, event){
   if (event.status &amp;amp;&amp;amp; result){
    j$.each(result, function(){
     j$("#targetId").append(this.Id+", "+this.Name+"<br/>");
    })
   }
  }, {escape:true});
 </script>
        
 <div id="targetId"></div>
</apex:page>

So, first comparing the two classes, the Javascript Remoting version is much more cleaner. The Javascript Remoting version has the name variable and the List<Account> return as a part of its method signature as opposed to having to be decalred at the class level. It’s much easier to understand that name and List<Account> are limited to the scope of the method.

However, note that the Javascript remoting method must be declared both global and static. Static is a bit of a bummer, as it means you won’t have access to any class instance variables. In contrast, the actionFunction version directly modified the state of the Controller instance, and the invoked method has access to all instance variables.

Update: So, why did Salesforce do this? well, if you’ve ever created a complex Visualforce page, one of the things you probably ran into is the “viewstate” (for more info on the viewstate, look here.). If you’ve heard about the viewstate, then you probably know that in general, the larger your viewstate, the slower your performance when it comes to acting on commandButtons, commandLinks, and actionFunctions. So to keep the Javascript Remoting call light and VERY quick, the viewstate is not transmitted.

From this perspective, it makes sense that the Javascript Remoting call is connected to a static function, as static functions are typically considered stateless. Since the viewstate is not transmitted, I doubt that the Javscript Remoting function would be even able to access controller static variables, but that’s just a guess for now and I’ll come back and update this when I get to trying it out for myself. But, even if this is a limitation, you could try to pass any variables you need in on the Javscript Remoting call. One note on this approach though, you will need to express your state in primitive data types, as you can only pass in primitive data types (You can return primitives, sObjects, or arrays of either of those types).

So when deciding which method to use, you’ll have to consider a few things: 1) Performance, 2) What state you’ll need to push to make the call you want, and one more point which we should mention, 3) How you will modify your Visualforce view? When using actionFunctions, you have a rerender tag you can use and it’s so simple to use in conjunction with other VF components. When using Javascript Remoting, just remember that you’ll have to roll your own here, but if you’re using something like jQuery, this may not be much code at all.


Writing Salesforce Test Cases – Tips and Best Practices

March 20, 2011

CodeTesting

Writing test code in Salesforce.com is a necessary step in deploying code. Yes it’s a bit annoying and it sucks when someone else’s test code breaks and prevents you from deploying your code. I saw an email in my inbox from Salesforce about a free webinar on testing and Coverage best proactices, and I’ve always wanted to document some advice that I’m often passing on to other Salesforce Apex Developers when writing test cases, so here I am. I was suprised to not find many blog posts out there when i searched for “Salesforce Apex Testing Best Practices” (I did find one really good blog post at gokubi.com). Hopefully I can add to what’s out there.

Write Portable Tests

I can’t stress this point enough. It’s the top item in that gokubi article too, and YES it’s that important! When writing you should never depend on certain records being there. Even if you think, “No, i’ll make sure no one deletes this record.” One day, when someone else is going to deploy code, it’ll turn up missing.

There’s also a flip side to this. You should also not depend on tables being empty. This can happen when you’re creating code that is supporting a brand new custom object. Usually, I’ll see the test code insert records, then run it’s test case, where the new code will query records from that table and maniplate them in some fashion. This will probably work great, in Sandbox and even deploying into production, but… a month or 2 down the line where there’s more data accumulated in that table and the query no longer behaves as the test expects. No more deployments until this problem is resolved (and of course these are usually discovered when someone is deploying code).

TIP: Sometimes, you need to cheat a bit

This second point in the previous section, about not depending on empty tables, is not always a straight forward change in the test code. Lets take an example of a batch process which queries the entire table and updates a field. When testing batch code, Apex only runs one batch of the process. If you’re creating sample records in your test code, how do you ensure that the batch process will pick up your test records?

You can put in a “sort by” clause in the query to ensure the records can get picked up, but… you really don’t want to affect performance just for the sake of writing test code. I think in this case, it’s ok to cheat a little. Check the Test.isRunningTest flag and modify the query if it’s true. The code below shows an example of an implementation. The class implements a Database.Batchable interface and has a conditional test code in the start method.

global MyClass implements Database.Batchable{
    ...
    global Database.QueryLocator start(Database,BatchableContext bc){
        String soqlQuery = "Select Id, Name, MyFlag__c from Account";
        if (Test.isRunningTest()) soqlQuery += " Sort By LastModifiedDate Desc";
        return Database.query(soqlQuery);
    }
    ...
}

Don’t just write coverage code. Make asserts!

When I see test code without asserts, I always just shake my head. You really should ensure that the code you write is doing what you expect. Writing a proper test case includes creating appropriate test records, then running some code for your test, and then finally putting in place the appropriate asserts will ensure that your code is doing what you expect. It also helps you from making future changes which would break your use case. This is expecially true if you’re writing trigger code, since triggers can affect lots of other apex code and their tests.

Code Structure

ImageFor the most part, most of my test code has the following structure (see diagram to the left). This structure may be a bit obvious to most, but I like to explain it to those new to writing test code. It makes code reviews of test code go by much quicker.

A comment should be placed between test code sections. Comments are always helpful, but in the test code, a little mention of the actual use case you are testing for helps enormously!

The asterisk after the “Setup runAs User” is there because this is not always needed. Only if your code is dependant on a specific role / profile or there’s some other User attribute which you need to test your code, would you need this.

A note about using the System.runAs() block. The User object that you pass into the runAs() method does not need to be a inserted into the database. I found this out when some of my test code was deployed into an org with 0 licences free. In my test code I had inserted the user record that I was using in the runAs() block. While fixing my test code, i noticed that inserting the User record is not needed.

Write test code for your most imporant Use Cases

If you can code for all possible Use Cases for your code, that’s great, but sometimes that’s an open ended problem. At the very least you should try to write test code for the most often used Use Cases. You should also code for error cases that could potentially occur a lot. The good thing about coding for both positive and negative use cases, is that it may make you think of more odd use cases, and thus more robust code. Hopefully that will put you very close to 100% code coverage. You may need to code a few more less likey Use Cases, or even directly call some functions and properties to get to that 100% mark. It’s not always necessary to get to the 100% mark, but get as close as you can.


Editing SFDC Zipped Static Resources in Eclipse – Zip Editor

March 1, 2011

One of the reasons people don’t create a zipped static resource in Salesforce.com is that it’s a bit of a pain in the neck to edit their contents.

You typically have to download the file from Salesforce (if you don’t already have a current version locally), unzip, perform your edits, zip them back up and then upload back again through the UI. Or. if you were a bit more clever, you could have tried to leverage the static resource is a Force.com project in Eclipse, and tried to get the Force.com IDE to push changes up to Salesforce.

Both options are a pain in the neck if all you want to do is play with some css class definition, as you’d probably be doing those same steps over and over again.

Now, I’m sure I’m not the first one to figure this out, but getting a zip editor plugin for eclipse comes in extremely handy for this situation. I recently installed one called “Zip Editor” into my Force.com IDE (Eclipse Helios). This looks very promising, as I’m now able to view the contents of zipped resource files within Eclipse itself and even make edits directly into the zip file. Now there is a little bit of a weird workflow that I have to follow to get zipeditor to save my updates to the zip resource, but it’s not so bad and WAY better than what I was doing before!

So here’s a link to the Sourceforce project for the Eclipse Zip Editor. Let me know if you run into a better solution for editing SFDC zipped resources!


Dynamic Visualforce Bindings – ooOOOoo

February 18, 2011

This blog post is mainly a summary of what i just read in the SFDC Dynamic VF Bindings section of the documentation for version 21.0. Pretty cool stuff. This will allow programmers to make VF pages even more Administrator friendly (as opposed to be Developer only territory).

So Dynamic Visualforce Bindings allow VF pages to be more flexible when it comes to displaying fields of sObjects and even public properties of Custom Apex Classes. Previously when working with <apex:outputField> tags and <apex:column>, you would always have to define the field name somewhere in the VF code to present it on screen. Now there’s syntax that allows you to dynamically get fields at runtime. It’s about time!

So the following are example code snippets (borrowed from the documentation). which uses the new features:

Using a List of field names on an Account object

Here “fieldList” is a List<String> which contains ‘Industry’, ‘BillingCity’, ‘AnnualRevenue’.

<apex:page standardController="Account" extensions="DynRefAccFieldLister" >
 <apex:form>
  <apex:pageBlock title="Account Fields" mode="edit">
   <apex:pageBlockSection columns="1">
    <apex:inputField value="{!Account.Name}" />
    <apex:repeat value="{!fieldList}" var="fld" >
     <apex:inputField value="{!Account[fld]}" />
    </apex:repeat>
   </apex:pageBlockSection>
  </apex:pageBlock>
 </apex:form>
</apex:page>

Extending this example a little, we can retrieve the label and value separately

<apex:page standardController="Account" extensions="DynRefAccFieldLister" >
 <apex:form>
  <apex:pageBlock title="Account Fields" mode="edit">
   <apex:pageBlockSection columns="1">
    <apex:inputField value="{!Account.Name}" />
    <apex:repeat value="{!fieldList}" var="fld" >
     <apex:outputText 
      value="{!$ObjectType.Account.Fields[fld].label}" />
     <apex:inputField value="{!Account[fld]}" />
    </apex:repeat>
   </apex:pageBlockSection>
  </apex:pageBlock>
 </apex:form>
</apex:page>

Using a List of indexes against a List of Strings

This example is mostly a copy from the documentation. Controller class contains the following properties:

public List<String> people {
 get { 
  return new List<String>{'Winston', 'Julia', 'Brien'};
 }
 set;
}
public List<Integer> iter{
 get { 
  return new List<Integer>{0, 2, 1};
 }
 set;
}

The following VF code can display the list in the 0, 2, 1 order.

<apex:repeat value="{!iter}" var="pos">
 <apex:outputText value="{!people[pos]}" /><br/>
</apex:repeat>

Using a List of keys against a Map

Similar to the one above, but using a map. Here the map is of type <string, string>, but something like a <string, Account> can also work and you would use it just like you would expect!

Sample Controller code:

public Map<String,String> directorsToCountry {
 get { 
  return new Map<String, String>{'Kieslowski' => 'Poland', 
   'del Toro' => 'Mexico', 'Gondry' => 'France'};
  }
  set;
}
public List<String> keys {
 get { 
  return new List<String>{'Kieslowski', 'del Toro', 'Gondry'};
 }
 set;
}

The following VF code can display the map.

<apex:repeat value="{!keys}" var="director">
 <apex:outputText value="{!directorsToCountry [director]}" /><br/>
</apex:repeat>

Using a FieldSet against an Account object

Finally, you can use a FieldSet to define… well… a set of Fields. This FieldSet can then be iterated through in a VF page and then applied to an sObject.

Here’s the example from the documentation. Here properNames is a Contact FieldSet which contains fields holding First Name, Middle, Name, Last Name ,and a Job Title field. The following VF could be used to view those fields for a specific record

<apex:page standardController="Contact">
 <apex:repeat value="{!$ObjectType.Contact.FieldSets.properNames}" 
  var="f">
  
  {!$ObjectType.Contact.Fields[f].label} 
  ({!$ObjectType.Contact.Fields[f].type}): 
  <apex:outputField value="{!Contact[f]}"/>
  <br/>
 </apex:repeat>
</apex:page>

Cool! This makes me want to create FieldSets for every ding-dang custom list i’ve ever had to write.


Performing Comparisons on Custom Labels in VF pages

February 2, 2011

Ran into a strange “bug” today while developing a VF page.

This VF receives parameters through the URL which the VF Controller class parses out and stores in a class variable.  The VF page also has an <apex:outputPanel> section which is rendered if the URL parameter equals a specified Custom Label. The code looks like the following:

Example URL:

https://na#.salesforce.com/apex/MyPage?param1=paramValue

Example Custom Label Definition:
Custom Label Name : MyLabel
Custom Label Value : paramValue1

Example Visualforce Page:

<apex:page controller="MyController">
    <apex:outputPanel rendered="{!ctrlParam1=='$Label.MyLabel'}">
        <apex:outputText value="Hello, World!"/>
    </apex:outputPanel>
</apex:page>

Example Controller Class:

public class MyClass{
    public String ctrlParam1{get; private set;}

    public MyClass(){
        map<string, string> params = ApexPages.currentPage().getParameters();
        ctrlParam1= params.get('param1');
    }
}

With the configuration details setup as above, the <apex:outputPanel> is not rendered. More specifically, the code rendered="{!ctrlParam1=='$Label.MyLabel'}" evaluates to false.

Playing around a bit with this code, and a lot of head scratching, netted me the following code that does work:

rendered="{!ctrlParam1==$Label.MyLabel}"

(No quotes around the Custom Label). I guess $Label.MyLabel is a variable in and of itself, and not a replacement string as I assumed that it was. Wish Salesforce.com Help and Training had more sample code. Grrr..


Apex Scheduled Classes and their Constructor Code

February 1, 2011

Just a little lesson learned as to how Scheduled Classes are treated in Salesforce.com.

When a class is scheduled for execution using the “Schedule Apex” button, the class is instantiated immediately and then held in memory until the time it should run.  This means that the constructor code of the scheduled class is run when the Admin creates the schedule for the class and not at the time the code is meant to execute.

This is an important distinction and can cause some issues if you’re not careful.  Let’s take an example:

global class MyClass implements Schedulable, Database.Stateful{
    MyCustomSetting__c settings;
    public MyClass(){
        settings = MyCustomSetting__c.getInstance();
    }

    global void execute(ScheduableContext ctx){
        String localCopyOfSettingsField = settings.mySettingsField__c;

        ...
    }
}

So in the above code, the MyCustomSettings__c object is loaded at the time the scheduled job is created.  So if, for example you have scheduled this class as a weekly job, and you decided to change the value of the mySettingsField__c field after you created this scheduled job, then the Class would not pick up the value for the next scheduled run, as the class has already been instantiated and already taken a reference to it’s copy of the Custom Settings object.  You can see how this can be annoying.

If you do find yourself in this situation, you can always delete the scheduled job and re-create it, which would force the code to re-instantiate the class.

The proper long term fix would be to move code that you want to execute at run time into the execute method, since that code has to run at the time of execution.

global class MyClass implements Schedulable, Database.Stateful{
    MyCustomSetting__c settings;
    public MyClass(){
    }

    global void execute(ScheduableContext ctx){
        settings = MyCustomSetting__c.getInstance();
        String localCopy = settings.mySettingsField__c;

        ...
    }
}


Opinion – Hierarchical vs. List Custom Settings in SFDC Apex Code

January 26, 2011

Salesforce.com’s inclusion of the Custom Settings feature was a much welcomed addition to the Visualforce / Apex feature set.  I’ve been using it fairly regularly in my day to day development for close to a year now and I just wanted to share some thoughts on “Best Practices” in how to use these two types.

I have been using Custom Settings, as I’m sure most of you would, as substitute a configuration file.  Placing “hardcoded” values into this object and changing out values when needed.  Before Custom Settings came out for Apex, we’d use a variety of methods including a “config class”, custom objects, and even custom labels.

Initially, I had used List style custom settings almost exclusively, as it seemed much simpler since it behaved very much like any other Custom Object in Salesforce.com.  Also, it was a  was fairly similar to my Java experiences where we would create separate config files per environment.  So I imagined that I would create a separate config for our production Salesforce.com instance vs. our sandbox instance.  But in practice, what would happen more often than not since most of our development was purely native Salesforce.com apps (i.e. Visual force pages which work on data within Salesforce, and are not connected externally to any servers), was once the code was deployed into production, there was very little need for any other configuration other than the production version.

Also, there were times where I wanted to reference these config values outside of Apex code, for example in a formula field or an email template.  This is where the Hierarchical Custom Settings has an advantage.  Hierarchical can be accessed in other parts of Salesforce.com which may work in conjunction with an Apex package.  Formula fields, Workflow Criteria, and Email Templates are examples of things that can access Hierarchical Custom Settings and not List Custom Settings.

Hierarchical Custom settings also have the added benefit of being able to handle those one-off “corner case” users that always seem to come up in large organizations.  If you have a user who could benefit from a slightly different app configuration, the Hierarchical Custom Settings is built specifically to handle different config settings for different users.

Update: One really good scenario for using List custom settings are when you have a common reusable piece of code, like for example a custom list view, that you use in many places throughout Salesforce. This list view can be supported by a custom list config where the name signifies where in the app the list appears, e.g. ContactDetail, AccountDetail, AccountListView, etc.

Summary

So just to summarize what I feel is the right way to use these different types of Custom settings:

Hierarchical Custom Settings

  • Use this for your most of your VF/Apex config settings for stand alone apps
    • Don’t put in settings which are environment dependent (e.g. if you have separate test server URLs that should be used in Sandbox vs. Production)
  • Definitely, if you are storing User Preferences, Hierarchical is the way to go.

List Custom Settings

  • Use this if you creating config for a common piece of code that appears in different areas of Salesforce
  • Use this when there are environmental differences such as Test server URLs vs. Production server URLs
  • Also can be used as a simple table for frequently used data

Of course you can us a combination of Hierarchical and List settings in your application and use each to its strengths.


Invalid Property Error in IE6 for style.color = “grey”

December 23, 2010

Just hit a small error in IE 6 with some javascript that was trying to change the color of some text to “grey”.  The offending line of code was the following:


if(document.getElementById(labelID)!=null)

document.getElementById(labelID).style.color = "grey";

Here labelID was the id of the <code>&lt;span&gt;</code>  that surrounded the text I wanted to grey out.

So the fix here is to change the color value “grey” to “gray”.   Damn you alternate spelling!


Unknown Exception Error while trying to send out a Visualforce Email Template

December 2, 2010

Today i’ve spent the better part of the day trying to figure out why I cannot send out automated emails based on a Visualforce Email template. When I tried to send out the Email Template from some Scheduled Batch code, I’d recieve the following error message:

System.EmailException: SendEmail failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, java.lang.NullPointerException: Argument Error: Parameter value is null: []

After viewing a few forum posts and doing some of my own experimentation, I’ve found out at least 2 things that can give you this error.

<apex:image> tag

These tags must be replaced with the standard HTML <img> tags. This is pretty straight forward, as most <apex:image> attributes correlate directly to an <img> attribute and don’t need to be touched. The <apex:image> attributes value and styleClass can be replaced with src and class attributes, respectively.

The only tricky attribute is probably the rendered attribute. You could try to map this style and put in a clever VF formula which could evaluate to display:none or display:inline, but that CSS may not be supported by your email client. (Outlook 2007/2010 doesn’t. *sigh* Look here for more info on the differences between email client CSS support.)

A solution that works is to wrap the <img> tag in a <apex:outputPanel> tag and apply the rendered expression to this tag.

<apex:outputLink> tag

This tag also needs to be replaced with the HTML <a> anchor tag. Again, the conversion is fairly straight forward. The tricky attributes are rendered and disabled. Again, I think <apex:outputPanel> tags and some CSS styling can be used to do the same things.

Hopefully this saves someone the grief and hair-pulling I went through.


Follow

Get every new post delivered to your Inbox.