Category Archives: Force.com Development

Floating/Sticky Headers For Visualforce PageBlockTable

Hey everyone, it’s Dan/Kenji, Senior Developer for Redkite here with a nifty solution to an ever so annoying problem. That is of course that headers of a pageblocktable in Visualforce do not remain visible if you put the table in a scrollable area. I know there are a few approaches on how exactly to best pull this off, but they always seemed too complicated and not very reliable. So I decided to just bite the bullet and write a nice reusable jQuery plugin to take care of it for you. First off, to make sure we are talking about the same thing and what I’m proposing if what you want, check out the demo link below.

Demo of Sticky/Floating Headers

If you like what you see, you can download the plugin here.

Download jQuery Plugin

Upload it as a static resource, or just copy paste the contents into your visualforce page. Either way is fine. Also, in your visualforce page you’ll need to include the css class .floatingStyle and set it’s position to relative. Like this

<style>      
.floatingStyle 
{ 
    position:relative; 
} 
</style>

To use it, simply put your pageblocktable inside a div or apex:outputpanel (with layout set to block). Give that container a height. Invoke the plugin on the table either by class or id. So if my pageblock tables had the styleClass of ‘floatingHeaderTable’ I could invoke it this way.

    <script>
    $(document).ready(function() {
        $('.floatingHeaderTable').vfFloatingHeaders();
    });
    </script> 

and that’s it. You are good to go. Here is a full sample page.

Visualforce Page

<apex:page controller="floatingHeadersController">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
    <script src="{!URLFOR($Resource.jquery_vfFloatingHeaders)}"></script>

    <style>
        .tableContainer
        {
            height:290px; 
            width: 100%;
            overflow: auto;
        }       
        .floatingStyle 
        { 
            position:relative; 
        } 
    </style>

    <script>
    $(document).ready(function() {
        $('.floatingHeaderTable').vfFloatingHeaders();
    });
    </script>   

    <apex:pageBlock >
        <apex:outputPanel styleClass="tableContainer" layout="block">
            <apex:pageBlockTable value="{!contactList}" var="item" title="Contact List" styleclass="floatingHeaderTable" >
                <apex:column value="{!item.firstname}"/>
                <apex:column value="{!item.lastname}"/>
                <apex:column value="{!item.email}"/>
                <apex:column value="{!item.phone}"/>
            </apex:pageBlockTable>
        </apex:outputPanel>
    </apex:pageBlock>
</apex:page>

Apex Class

public class floatingHeadersController 
{
    public list<contact> contactList
    {
        get
        {
          if (contactList == null)
          {
              contactList = [select firstname, lastname, email, phone from contact];
          }  
          return contactList;
        }
        set;
    }
}

Also, I would like to give credit to a blog which helped me immensely with the technique for getting the headers to float properly.

http://rajputyh.blogspot.com/2011/12/floatingfixed-table-header-in-html-page.html

I just wrapped it up and modified it a bit to work with pageblocktables and packaged it into a plugin.

FacebookTwitterLinkedInGoogle+Email
FacebookTwitterLinkedInGoogle+Email

What’s New(s) In The Cloud? Dreamforce, Winter ’13, and the Social Enterprise behind Red Bull Stratos

What’s New(s) In The Cloud?

Here are some of Redkite’s favorite Salesforce.com and Cloud related tweets this month!

News in the Cloud takes on a new meaning this week with Felix Baumgartner’s record breaking leap.

Salesforce and Social Media: See how 5 major brands use Salesforce for Social Enterprise.

The Winter ’13 Release updates begin this month, and from enhancements in Salesforce Touch to new features like Shared Events, there’s a lot to checkout. Click through for access to demos about the recent release, or download the release notes.

We are gearing up for Cloudforce in New York City this week! To get prepared, relive the best of Dreamforce ’12 and get caught up on the materials from the Developer Zone, now available online.

FacebookTwitterLinkedInGoogle+Email
FacebookTwitterLinkedInGoogle+Email

Building Multi-Column Table Dashboard Components in Salesforce

Salesforce’s Reporting and Dashboards are extremely powerful but some things that seem like they should be easy can end up being pretty formidable challenges. One dashboard we see our clients struggling with is the elusive, but useful, multi-column Dashboard Component table.

Let’s review how to create a Dashboard Component with multiple columns, displaying your Salesperson’s Quotas, Revenue, and Percent to Quota for the Year.

Build your Report

The first step to building any Dashboard Component is to build a summary report using the object(s) and fields desired in your Dashboard Component.

Create Summary Formula Fields for your Report

Only fields that are Numeric field types can be displayed on the Multi-Column Table. For Each Column Header you want to display on the table, create a Custom Summary Formula Field displaying the Currency or Percentage as a Numeric value. Since numeric fields do not carry Dollar Signs ($) or Percentages (%), place the sign in the Field Label (see screenshot below).

In the example below, the calculation should output a percentage field, but in order to display it in the component, it must be a Numeric field. Note that the “(%)” sign is in the field label.

Create Chart on your Report

On the Report, Create a Bar Chart and plot one of the numeric formula fields on the X-Axis, and the Salesperson in the Y-Axis. Next, use the Plot Additional Values function in the Combination Charts section; select the other numeric formula fields created from the report as additional bars.

Save the Report.

Create a Dashboard Table Component

After the Report has been saved, create a New Table Dashboard Component referencing the Report. In the Formatting tab of the Component Editor you can choose the columns you want to display. The formula fields are available to be added to the table; add the column headers and Save the Dashboard.

Once you have saved the Dashboard Component, you will have a 4 column table that is easy on the eyes and brain.

Add this to your homepage and your Dashboard is complete.

FacebookTwitterLinkedInGoogle+Email
FacebookTwitterLinkedInGoogle+Email

Salesforce Field Sets – a limitation and a workaround

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.

FacebookTwitterLinkedInGoogle+Email
FacebookTwitterLinkedInGoogle+Email

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

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;&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.

FacebookTwitterLinkedInGoogle+Email
FacebookTwitterLinkedInGoogle+Email