Category Archives: visualforce

Visualforce – jQuery pattern – enforce only single checkbox in a list

Over the last few months, I’ve dabbled in adding some client-side improvements to Visualforce pages. But, I’ve resisted doing much with Javascript and jQuery in order to keep the development models limited to just Visualforce, Apex, and There was something about a blend of Javascript and VF markup on a page that I always found jarring and hard to read and understand – too much syntactic dissonance

But, jQuery and jQuery Mobile are highly recommended for developing Salesforce1 apps. After reading jQuery Mobile Web Development Essentials, Second Edition by Camden and Matthews, I discovered a nice organizing pattern for jQuery that was a good place to add in all of a page’s jQuery event handlers (see chapter 8). So, I decided to apply it to a commonly-occurring problem – display a list with checkboxes next to each row, but allow only one box to be checked before submission to the server. This avoids writing controller code to enforce a single selection (as radiobuttons can’t easily be applied to table rows).

So, here it is where the table displays a list of Quotes on an Opportunity and only one can be specified for the action

<apex:page standardController="Opportunity" extensions="OppoControllerExtension">

	<apex:includescript value="" />
		$j = jQuery.noConflict();		//	reassign $ to $j to avoid conflict with VF
		$j(function() {				// 	jQuery shorthand for $(document).ready(function() ..  Wait until page loads 
			//	define the application
			var	OppoToSvcContract	= {};
			(function(app) {		//	Define anon function
				//	--------------------------
				//	variable definitions
				//	--------------------------
				//	--------------------------
				//	init:	do initializations
				//	--------------------------
				app.init	= function() {
					app.bindings();		//	establish bindings	
				//	-----------------------------------
				//	bindings:  events to event handlers
				//	-----------------------------------
				app.bindings = function() {
					// set up binding for onclick checkbox: Unchecks other checkboxes
					$j('input[id*="qCheckbox"]').click(function(e) {		// attach anonymous fn as event handler to click event for all DOM checkbox whose id attr contains qCheckbox, $j(this) available
						var clickedElmId	= $j(this).attr('id');			// DOM elm that was clicked
						$j('input[id*="qCheckbox"]').each(function() {		// Go thru all checkboxes
							if ($j(this).attr('id') != clickedElmId) {		// if id diff than clicked elm id, uncheck	
					});													// end binding
				};														// end all bindings
				app.init();				// Anon function invokes its own init function
			}) (OppoToSvcContract);		// Execute anon function passing in an object representing our application

	<apex:sectionHeader title="Create a Service Contract from this Opportunity's Quotes:" subTitle="{!}"/>
	<apex:form id="theForm">
		<apex:pageBlock >
			<apex:pageBlockButtons location="top">
		 		<apex:commandbutton value="Create Service Contract from Oppo+Quote" 
		 		<apex:commandbutton value="Cancel" immediate="true" action="{!cancel}"/>      
		<apex:pageBlock title="Quotes (to use as source for Service Contract line items)">
			<apex:pageBlockTable id="quotesTbl" value="{!availQuotes}" var="aq" style="width:90%; border-color: rgb(248,248,248);" headerClass="quoteTblHdr">
                <apex:column headerValue="Select One" style="width: 5%;">
                	<apex:inputCheckbox id="qCheckbox" value="{!aq.isSelected}"/>  <!--  jQuery event handler takes care of only one box checkable -->
                <apex:column headerValue="Name" style="width: 10%">
					<apex:outputLink value="{!URLFOR($Action.Quote__c.View,}">{!} {!aq.forecastMsg}</apex:outputLink> 

Aligning labels with selectRadio within a pageBlockSection

Here was the issue:

I had a pageBlockSection with a mix of VF components bound to SObject fields and components bound to controller properties. In the latter case, I was using selectRadio.

The label on the selectRadio did not vertically align with the top radio button. You can see an aligned and misaligned example in the picture below.
Aligning label and selectRadio
Here is the VF markup for the aligned and misaligned example:
Solution: Use style="margin-top: -10px;".

<apex:pageBlockSection title="New Quote Wizard Parameters" columns="1" collapsible="false" id="quoteWizParams">
	<apex:selectRadio label="Type" value="{!quoteWiz.selectedQuoteWizType}" 
                          layout="pageDirection" id="quoteWizTypeRadios" 
                          style="margin-top: -10px;">
  		<apex:selectOptions value="{!quoteWiz.quoteWizTypeOptionList}"/>
	<apex:pageBlockSectionItem >
		<apex:outputText value="Service term (in months)"/>
		<apex:inputText value="{!quoteWiz.initServiceTermMos}"/>
	<apex:selectRadio label="SnS Level" value="{!quoteWiz.selectedSnsLevel}" 
                          layout="pageDirection" id="snsLevelRadios">
	        <apex:selectOptions value="{!quoteWiz.snsLevelOptionList}"/>

Side note: The use of the VF attribute label avoids the need for pageBlockSectionItem markup – SFDC automatically puts the label into the proper cell as if you were using apex:outputLabel.

Visualforce performance tuning – lessons learned – Part I

I was optimizing a complex VF page the other day and learned a couple of tips that I did not otherwise know beforehand

Lesson I – Use apex:variable to avoid repetitive getters that always return the same value
The page used apex:repeat to create a dataTable. Each dataTable had five rows. In the edge case I was tuning, there were sixty (60) repeats – thus sixty datatables.

<!--  snip -->
<apex:repeat value="{!tableList}" var="t">
  <apex:dataTable value="{!tableRows}" var="r">
     <apex:column headerValue="column00">
       <apex:inputText value="{!r.field00}" rendered="{!isEditable}"/>
       <apex:outputText value="{!r.field00}" rendered="{!NOT(isEditable)}"/>
<!-- snip -->

Note that the decision to render the field in column00 as input or output is based on a controller variable isEditable. This controller variable was actually a getter and had some complex logic within:

public Boolean isEditable {
      if (isEditable == null)      
         // complex logic here to set isEditable - 
         // do only once as nothing the page can do will change the decision
      return isEditable;
  private set;

Looking at the debug log, when the page is constructed, this controller getter was invoked 60 * 5 * 2 times = 600 invocations! Holy moly. Even though the getter only calculates its value once, it still gets invoked for every rendered= reference on the page.

The solution is to add an apex:variable outside of the repeat to cache the value for Visualforce and thus save on all those getter invocations. Here is the new page:

<!--  snip -->
<!-- Define an apex:variable to hold the controller's getter value. 
     Use naming convention of avXXX to clue developer
     where used that it is a reference to an apex:variable -->
<apex:variable value="{!isEditable}" var="avIsEditable"/> 
<apex:repeat value="{!tableList}" var="t">
  <apex:dataTable value="{!tableRows}" var="r">
     <apex:column headerValue="column00">
       <apex:inputText value="{!r.field00}" rendered="{!avIisEditable}"/>
       <apex:outputText value="{!r.field00}" rendered="{!NOT(avIsEditable)}"/>
<!-- snip -->

Result was a couple of tenths of seconds shaved off the page render time

Lesson 2 — Multiple controller extensions and constructor time

I had a different page with several commandButtons. Some of the buttons invoked action methods in extension00, the others invoked action methods in extension01. There was no page action.

<apex:page standardController="Opportunity" extensions="OppoExtension00,OppoExtension01">
      <apex:commandButton value="Invoke 00" action="{!extension00Action}"/>
      <apex:commandButton value="Invoke 01" action="{!extension01Action}"/>

When the page is initially rendered, both controllerExtensions’ constructors are invoked. If the constructors do heavy lifting in terms of initializations (such as SOQL calls), then all of that work must finish before the page can render. If the user is only going to click on one commandButton, then the constructor time for any other commandButton using a different extension is wasted. Now, I should have known that but I was misdirected by thinking that the constructor time only applied when the commandButton was clicked and the work had to be done.

The solution was to optimize the extension’s constructors. Two techniques were applied:

  • Move SOQL out of the constructors into getters
  • Using static variables to hold common data that would be the same for both constructors

Good APEX Naming Conventions

To inaugurate the blog, I’ll start with something prosaic but one where I saved myself a lot of grief over time as I built up large APEX systems. Naming conventions are of course a matter of personal preference. I’ve seen a lot of posts asking for help on the SFDC Apex Forum and many times the poster’s naming conventions get in the way of those trying to assist. Professional programmers will already know all this stuff, so this might be more appropriate for Apex newbies and ‘toddlers’.

Class and method names

  • Follow the SFDC conventions. Your code is a mix of SFDC classes and methods so follow the idiom. Class names are initialcaps.
  • Method names are initial lowercase. Don’t use underscores. If the method returns a Boolean, make the method name an assertion statement
public class Foo{
  public Boolean isClosed() {
   // some condition that returns true if something is true, else false

Consistency in abbreviations

I use a consistent shorthand for my APEX variables (and by extension Visualforce var= attributes).

  • Variables that reference Accounts start with ‘a’, Opportunities with ‘o’, Contracts with ‘c’, Quotes with ‘q’, QuoteItems with ‘qi’ and so on.
  • Where there is a first letter conflict, I stick to something clear and easily remembered such as ‘cs’ for Case or ‘attach’ for Attachments
  • Custom Objects would use a shorthand made up the first letters of each word (or maybe syllable) such as ‘pcr’ for Product_Config_Rule__c

Consistency in references to IDs

  • IDs are your friend as they can be used to reference maps, query for SObjects, and are globally unique.  Use your variable names to ‘type’ your Ids
  • Thus, aId is an Account Id, qiId is a quote Item Id
Account a;  // the account being worked on
Account aOld; // the prior version of the Account from Trigger.old
ID aId;  // an account Id

Consistency in collection variable names

  • You are constantly coding in the bulk idiom or handling result lists from queries. Because SFDC provides different instance methods for lists, sets, and maps and because each collection type serves a different purpose, it greatly improves code readability when the variable name makes it clear whether it is a list, set or map.  I always append my collection variable names with either ‘List’, ‘Set’, or ‘Map’. It also helps you code as you operate on the collection – as you type the variable name, you remind yourself of how it works (for example, maps aren’t in any sort order).
  • Since lists are often created to do DML or are the results of queries, add a common shorthand to the variable name as to purpose. For example ‘ins’ for a insert list, ‘upd’ for an update list, or ‘res’ for a query result list

Good names

List<Account> aInsList;  // a list of Accounts to insert
List<Opportunity] oUpdList;  // a list of Opportunities to update
List<Contract> cReslist = [select id from Contract where name like 'Foo%'];  // query result

Set<ID> aIdSet;  // a set of unique accountIds

Map<ID,Case> csIdToCaseMap; // a map of Case Ids to Case SObjects
Map<ID,List<Quote>> oIdToQuoteListMap;  // Map of Oppo ID to a list of Quotes

// Map of Case Id to Case with related lists fetched from a query
Map<ID,Case> csIdToCaseWRelListMap =
  new Map<ID,Case> ([select id, accountId, caseNumber, closedDate, contactId, subject, type,
		     (select id, commentBody, createdDate, createdById, isPublished
			     from CaseComments order by createdDate),
		     (select id, messageDate, subject
			     from EmailMessages order by MessageDate asc)
		    from Case where id IN :csIdSet]);

Avoid doing this…

List<Account> accts;  // when referenced in the code, is it a list, set or map?
List<Opportunity] updates;  // updates of what sObject?

Set<ID> ids;  // a set of Ids to what sObject?