Trapdoor In The Sun

Alan Shanahan, Technician & Consultant

Force.com: Visualforce programming, position cursor at first input field

4 Comments

When building a custom Visualforce page with input fields, one common requirement is to place the cursor at the first input field on the page. You would think this would be a simple matter and Salesforce itself manages the task quite well. But when the platform’s default behaviour kicks in and overrides your page’s behaviour, it doesn’t always work smoothly. Or if you want to position on an input field that is not a text entry field it doesn’t always slide into place. Or perhaps you wish to show a dialog box where you wish to conditionally position the cursor to a Confirm or Cancel button depending on prior processing.

In this piece, I’m offering a foolproof way to enable your page to behave exactly as you want it to, in an easy, maintainable way. Here is the step by step way to do this.

First, download a copy of the JQuery library from jquery.com. The minimised (compressed) version is just fine.

Now, upload it to your Salesforce org as a Static Resource.

In your Visualforce page, add this line somewhere after the apex:page tag:

<apex:includeScript value="{!$Resource.JQueryJS}" />

…making sure to replace the JQueryJS text with the name you specified during the Static Resource upload step.

The code below assumes that the page is aware of a “mode” or action passed to it, perhaps as a querystring parameter and parsed separately into a variable called wrkAction.


...

	<script language="JavaScript">

	//----------------------------
	// JQuery initialisation
	//----------------------------
	j$=jQuery.noConflict();
	j$(document).ready(function() {
		initialisePage();
	});

	//-------------------------
	function initialisePage() {
	//-------------------------
		positionCursorToFirstField();
	}
	//-------------------------------------
	function positionCursorToFirstField() {
	//-------------------------------------
		if ('new' == '{!wrkAction}' || 'edit' == '{!wrkAction}' || 'copy' == '{!wrkAction}') {
			j$("[id*=':btnConfirm']").focus();
		}
		if ('del' == '{!wrkAction}') {
			j$("[id*=':btnCancel']").focus();
		}
	}
	</script>

The page buttons might be defined later in your page code, as follows:

	<apex:pageBlockButtons id="pbButtons" location="bottom">
		<apex:commandButton id="btnCancel"  value="Cancel"  immediate="true" onclick="return checkCancel();"  />
		<apex:commandButton id="btnConfirm" value="Confirm" immediate="true" onclick="return checkConfirm();" />
	</apex:pageBlockButtons>

Given that any page element will probably exist in the hierarchy of page elements, the Visualforce page is rendered with the implicit force.com naming applied i.e. the full “pathname” to the element is implied in the name, with colons separating each branch in the tree. For example, an HTML id such as j_id0:j_id1:j_id192:j_id193:j_id196:j_id230:j_id231:j_id232:4:j_id236 would not be unusual.

The above code brings a “best practice” tip to mind – always use page-unique ID values for input fields, buttons and all other page components. Specifying the ID tag also ensures that the force.com implicit naming conventions are not applied.

The JQuery code in the positionCursorToFirstField javaScript method above provides a major advantage: you are now effectively freed from having to worry about the naming hierarchy. The JQuery selector finds the field ending with a colon character followed by the specified unique fieldname. This also means you can move it around on the page and within the page element hierarchy (DOM) and not have to worry about this code failing or needing to be modified.

There’s just one more piece of code needed to ensure the force.com standard processing doesn’t happen i.e. that the platform itself doesn’t try to be too clever and preempt what you’re trying to do. This code masks the effect of the standard “first input field positioning” processing:

	<script language="JavaScript">

	//--------------------------------------------------------------------------------------------------------------
	// This empty function overrides the SFDC standard function, and enables us to control initial field positioning
	//--------------------------------------------------------------------------------------------------------------
	function setFocusOnLoad() {
	}

	</script>
Advertisements

Author: Alan Shanahan

Cloud computing professional, amateur drummer and other things. Doesn't take himself too seriously. He's got a fever ... and the only prescription is more cowbell.

4 thoughts on “Force.com: Visualforce programming, position cursor at first input field

  1. I would think the “taborderhint” property of the inputField components on the page would control which one is selected when the page loads, yes? Or perhaps that only comes into play when the user presses tab. Hmm…

    • Hi Michael,

      Interestingly, the taborderhint keyword is available for the apex:inputField, whereas tabIndex is used by all other input-capable Visualforce components (e.g. apex:inputText, apex:selectRadio, apex:commandButton, etc.) Honestly, I hadn’t given this much consideration but it warrants some further exploration as to behaviour. According to SFDC documentation the taborderhint keyword comes into effect when the user presses the tab key, but I wonder if its behaviour is browser dependent. This seems like an aberration; I can’t see a reason for what looks like an exception. I suppose the point is that the code sample I proposed is more explicit in behaviour and works for all browsers; in fact it can be used to intelligently position the cursor to whatever field is appropriate for the user experience, whether it’s the first field, the last button or any other selectable page component.

      Thanks for your comment, it’s greatly appreciated.
      Alan

Leave a Reply to Alan Shanahan Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s