Subscribe

Appirio RSS Feed
Subscribe with Bloglines

Add to Google
Subscribe in NewsGator Online

Community

Appirio Technology Blog

Showing posts with label Apex. Show all posts
Showing posts with label Apex. Show all posts

Friday, November 14, 2008

Learning Apex: Display Multi-Object Data in Tables Easily with Apex Dummy Classes

Will Supinski

Creating tables in Visualforce is easy. Provide a list of Objects to display and define various columns that access different items in each Object. Easy. Things become tricky when one needs to display data from more than one object in a table. To solve this problem one need only define a dummy class to hold all the relevant data. This article will detail such a process.

Let us begin by inspecting the syntax of a simple Visualforce page that displays a table:

<apex:page controller="TrainingController ">
   <apex:pageBlock title="Users">
      <apex:pageBlockTable value="{!Users}" var="item">
         <apex:column value=”item.Name”/>
      </apex:pageBlockTable>
   </apex:pageBlock>
</apex:page>

public class TrainingController
   {
      public User[] getUsers()
      {
          return [select Name, Id from User];
      }
}

The above code will print out all the names for users returned by getUsers() in a shiny new table. This is easy to do without any special technique.

Consider a slightly more complex situation. You are building a Learning Management System that associates Users with Transcripts and TrainingPaths. You create a Transcript and TrainingPath custom object that each have a reference to a User defined as Trainee__c. Now you want to display each trainee in a table with the associated TrainingPath name and Transcript percentComplete field. But, how can we display three different objects within the same table? This is the question answered through the creation and use of dummy objects.

An incorrect approach to solving this issue is to create apex methods that query the objects and then call these from individual columns. Unfortunately, life is not that easy as this solution is not scalable because the number of queries would be proportional to the number of entries in the table. As soon as the table grows the governor limits will be met and your page will fail to load.

A working solution is the creation of apex dummy classes. The idea of dummy classes is that we create an apex class with the sole purpose of providing access to more than one object. Check out the dummy class below:

public class TrainingPathDummy
{
   public Training_Path__c tp { get; set; }
   public Transcript__c transcript { get; set; }
   public User trainee { get; set; }
   public TrainingPathDummy(Training_Path__c tp1, Transcript__c trans1, User trainee1 )
   {
      tp = tp1;
      transcript = trans1;
      trainee = trainee1;
   }
}

This dummy class has a member variable for each of the data objects we want to display in our table. Notice that the constructor has a parameter for each of the class variables. These will be passed in from the controller so that no queries within the dummy class. A list of these TrainingPathDummy classes can be iterated over in the pageBlockTable and its member objects can be accessed in the table easily as seen below:

<apex:page controller="TrainingController ">
   <apex:pageBlock title="Users">
      <apex:pageBlockTable value="{!TrainingPathDummys}" var="dummy">
         <apex:column value=”dummy.trainee.Name”/>
         <apex:column value=”dummy.tp.Name”/>
         <apex:column value=”dummy.transcript.PercentComplete__c”/>
      </apex:pageBlockTable>
   </apex:pageBlock>
</apex:page>

The Controller class must do all the heavy lifting of querying the data and forming it into dummy classes. Populating the list of dummy classes only takes 3 queries regardless of the size of the table. Governor safe and mother approved!

public class TrainingController
{
   public User[] getUsers()
   {
      return [select Name, Id from User];
   }  
   public Transcript__c[] getTranscripts()
   {
      return [select Name, Id, PercentComplete__c from Transcript__c];
   }

   public TrainingPath__c[] getTrainingPaths()
   {
      return [select Name, Id from TrainingPath__c];
   }
   public TrainingPathDummy[] getTrainingPathDummys()
   {
      TrainingPathDummy[] result = new TrainingPathDummy[]();

      //query for all the data
      User[] allUsers = getUsers();
      Transcript__c allTranscripts = getTranscripts();
      TrainingPath__c allTPs = getTrainingPaths();

      //find all the related data and put into dummy class
      for(User u: allUsers)
      {

         //get the related Transcript
         Transcript__c curTrans;
         for(Transcript__c trans: allTranscripts)
         {
            if(trans.Trainee__c == u.id)
            {
               curTrans = trans;
               break;
            }
         }

         //get the related TrainingPath
         TrainingPath__c curTrainingPath;
         for(TrainingPath__c tp: allTPs)
         {
            if(tp.Trainee__c == u.id)
            {
               curTrainingPath = tp;
               break;
            }
          }

         //create the Dummy class and add to the result list
         result.add(new TrainingPathDummy(u, curTrainingPath, curTrans);
   }
   return result;
}

Using Dummy classes is a useful skill for displaying data logically while keeping the total number of queries low. Add this method to your developer toolbox today!

Wednesday, July 16, 2008

Welcome to the Appirio Tech Blog

The team here at Appirio spends a lot of time building innovative plugins, apps and even complete business solutions using Software-as-a-Service (SaaS) and Platform-as-a-Service (PaaS) technologies from Google and salesforce.com. We like how easy it is to build these solutions-- that's what makes cloud computing so different (and so disruptive). But easy isn't automatic (no matter what your boss thinks). That's why we're writing this blog.

Internally, the Appirio team talks a lot about design patterns, issues, work arounds and cool tricks to make it build on use web platforms. It fun to find a new way to solve a problem and a badge of honor to see who can do it with the "least lines of code".

We want you to be a part of our conversation. Why? So that you get as excited as we are about the power of cloud computing and can build your own cool applications. This blog is for you if want to build on the cloud, whether you are a power-admin or an apex wizard, whether you are a longtime Salesforce and Google customer or just getting started, whether you are an individual contributor or are managing an entire team of developers. We won't have code in every post, but we'll definitely be thinking about it.

Here are a few of the topics we're thinking about, feel free to suggest your own.
  • Salesforce's VisualForce allows developers to design any UI on top of the Salesforce data model. What's possible with VisualForce today, and how can you make the most it?
  • Salesforce's Apex programming language gives you a lot of flexibility and power, but using it effectively requires understanding its capabilities and limitations. Where can you find tips and tricks for developing in Apex?
  • Salesforce's Customer and Partner portal lets you share critical business data information with people outside your company. How can you develop effective portal applications?
  • Google's AppEngine lets you build the next great web app, but is still lacking basic features for enterprise use (e.g., support for HTTPS). Where does AppEngine fit for enterprises and how can you use it with that in mind?
  • Everyone wants to use their on-demand applications from mobile devices like the BlackBerry and iPhone. What's the best way to enable these capabilities and finally unchain your users from their desks (e.g. super monkey ball for the enterprise)?
  • Security is top-of-mind for any company looking to move more of their business onto the cloud. What shoudl you know when configuring roles and profiles, establishing authentication and authorization, and setting up single-sign on?
As you can tell, there's a lot of ground to cover. We'll have folks from Appirio and occassionally some guest writers help us get there.