function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
SteveEthosSteveEthos 

Tab-key Order on pageBlockSection

When you build page layouts in SF, you can create a new Section, and one of the properties is "Tab-key Order", options are "Left-Right" or "Top-Down".

 

How can I create the same effect in Visual Force?

 

The pageBlockSection has the "columns" attrubute, but not the order direction.

 

Then I looked at the inputFields to see if I can change their index, but there is no easily exposed attribute. 

 

This seems like an oversight.  I figured that I could create similiar layouts/flow with VisualForce.

 

Am I missing someplace?

 

Thanks,

Steve 

Ron HessRon Hess
i think the input fields have a taborder attribute that will get the effect you are looking for, you just fill in each one with the tab order and it should work.
SteveEthosSteveEthos

Great, that is exactly what I thought should be there.  

 

It is not mentioned in the documentation, so that was a little confusing. (it mentions all of the mouse in/out stuff, so I thought that it was complete).

adsfasdfasdfasdadsfasdfasdfasd

The inputField input field does not support taborder or tabindex. Since my requirement is to reproduce the existing forms exactly, I cannot substitute inputText etc. for inputField.

 

And since the original form tabbed down the columns instead of across the columns, I now have a VF page that looks exactly right but does not tab correctly.

 

Please tell me there is a work-around for this ...

 

John

SteveBowerSteveBower

 

Hi, I had a similar requirement.   I don't believe there is any way to do it using nothing but VisualForce.  It would be nice if apex:inputField had the "tabindex" option, but it doesn't.  Perhaps it should be an idea.

 

Either way, there is a cheating, ugly, hack which works if you can get past the smell of vomit.

 

The Input and Select tags that are being created from your VisualForce page are available to Javascript.  Even if VF doesn't allow the use of a tabindex, there is no reason you can't add it yourself.   However, you need to be able to specify the tabindex that you want to use in the VF markup, and that's checked when you save it so that you can't just go adding your own tags willy nilly.

 

So, you can cheat and put your tabindex values in some other attribute, like the ID, and then when the page loads your javascript can fix it up.

 

This is overloading the ID, however it will still work as an ID tag, and it gives us a place to pass a string where IE won't try to convert it into a Function when it does it's getAttribute conversions.  (Because getAttribute() doesn't actually return a String in IE-land.)

 

Since Salesforce adds a bunch of stuff to your Id tag to create such lovely ID tags as:  j_id0:j_id2:j_id3:j_id10:your_id_tag,  you then have to strip off the stuff that's added to the attribute value to get just what you want.

 

So you can use:

 

<script language="javascript">
function fixElements(tagn,attrib) {
var tags = document.getElementsByTagName(tagn);
var ti;
var pos;
// Since Salesforce builds a complex Id using the Id's of previous elements, we need
// to find the one that we want.
// Note: this means we're searching for tags like:
// apex:inputfield id="tabIndex4" ....>
var pat = /:tabIndex[0-9]+/;
for (var i=0; i < tags.length; i++) {
if (tags[i].getAttribute(attrib) != null) {
pos = tags[i].getAttribute(attrib).search(pat);
if (pos != -1) {
ti = tags[i].getAttribute(attrib).slice(pos+9);
tags[i].setAttribute('tabIndex',ti);
}
}
}
}
fixElements("input","id");
fixElements("select","id");
</script>

 

 Then, you can use VF code like:

 

 

<snip.....>
<apex:pageBlockSection showHeader="true" title="Information Gathered at Intake" columns="2">
<apex:inputField id="tabIndex1" required="true" value="{!Child__c.Name}"/>
<apex:inputField id="tabIndex9" required="true" value="{!Child__c.Gender__c}"/>
<apex:inputField id="tabIndex2" required="true" value="{!Child__c.Child_Last_Name__c}"/>
<apex:inputField id="tabIndex10" required="true" value="{!Child__c.Language__c}"/>
<apex:inputField id="tabIndex3" required="true" value="{!Child__c.Date_of_birth__c}"/>
<apex:inputField id="tabIndex11" value="{!Child__c.Specify_Other_Language__c}"/>
<apex:inputField id="tabIndex4" required="true" value="{!Child__c.Ethnicity__c}"/>
<apex:inputField id="tabIndex12" value="{!Child__c.SSN__c}"/>
<apex:inputField id="tabIndex5" value="{!Child__c.Living_with_client__c}"/>
<apex:pageBlockSectionItem />
<apex:inputField id="tabIndex6" value="{!Child__c.If_not_where__c}"/>
<apex:pageBlockSectionItem />
<apex:inputField id="tabIndex7" value="{!Child__c.Child_placement_status__c}"/>
<apex:pageBlockSectionItem />
<apex:inputField id="tabIndex8" required="true" value="{!Child__c.Custody__c}"/>
</apex:pageBlockSection>
</snip.....>

 

 Ugly, gross, but it works in those cases where the user REALLY wants it that way.   I haven't found any problems with this approach yet, but of course your mileage may vary.  Feedback if anybody has improvements or other approaches would be great.

 

Best, Steve.

adsfasdfasdfasdadsfasdfasdfasd
Awesome idea -- thank you thank you thank you!
JMPlayer22JMPlayer22
I can't get this to work...I copied the javascript exact and then made sure to change my Ids to fit like it says and it's not working...still just tabbing from left to right instead of down one side and down the other like I have it tagged to do.  Is there something specific that I'm not seeing like..."showheader" has to be true or something?

<script language="javascript">

function confirmCancel()

{

var isCancel = confirm("Are you sure you wish to cancel?");

if(isCancel) return true;

}

function fixElements(tagn,attrib)

{

var tags = document.getElementsByTagName(tagn);

var ti;

var pos;

// Since Salesforce builds a complex Id using the Id's of previous elements, we need

// to find the one that we want.

// Note: this means we're searching for tags like:

// apex:inputfield id="tabIndex4" ....>

var pat = /:tabIndex[0-9]+/;

for (var i=0; i < tags.length; i++)

{

if (tags[i].getAttribute(attrib) != null)

{

pos = tags[i].getAttribute(attrib).search(pat);

if (pos != -1)

{

ti = tags[i].getAttribute(attrib).slice(pos+9);

tags[i].setAttribute('tabIndex',ti);

}

}

}

}

fixElements("input","id");

fixElements("select","id");

</script>

 

 

<apex:pageBlockSection title="Contacts" columns="2">

 

<apex:inputField id="tabIndex1" value="{!welcome.Primary_Contact__c}"/>

<apex:inputField id="tabIndex5" value="{!welcome.Secondary_Contact__c}"/>

<apex:inputField id="tabIndex2" value="{!welcome.Primary_Contact_Phone__c}"/>

<apex:inputField id="tabIndex6" value="{!welcome.Secondary_Contact_Phone__c}"/>

<apex:inputField id="tabIndex3" value="{!welcome.Primary_Contact_Email__c}"/>

<apex:inputField id="tabIndex7" value="{!welcome.Secondary_Contact_Email__c}"/>

<apex:inputField id="tabIndex4" value="{!welcome.Primary_Contact_Access__c}"/>

<apex:inputField id="tabIndex8" value="{!welcome.Secondary_Contact_Access__c}"/>

 

</apex:pageBlockSection>

 ...a little help, please! :)

Message Edited by JMPlayer22 on 02-10-2010 08:18 AM
Message Edited by JMPlayer22 on 02-10-2010 08:22 AM
Message Edited by JMPlayer22 on 02-10-2010 08:22 AM
Message Edited by JMPlayer22 on 02-10-2010 08:23 AM
Message Edited by JMPlayer22 on 02-10-2010 08:23 AM
SteveBowerSteveBower

I think you'll have to debug your particular page to see what's going on.  The solution did work, so somethings not going right in your situation.

 

I'd try:

 

1. Checking the javascript console in your browser to see if you're getting any Javascript messages.

 

2. Throwing a few alerts into the javascript to see if you're even getting to the various parts of the code.

 

3. Looking at the generated source code for your page and visually making sure that the Id's are correct and that the pattern matcher will find them.

 

Good luck, Steve.

 

p.s. as an aside:

 

function confirmCancel() {

return confirm("Are you sure you wish to cancel?");

}

 

 

stollmeyerastollmeyera

This is a wonderful workaround.  Just wanted to send my thanks along.  

SF7SF7

Hi 

I tried to use this code and it gives me an error saying id =tabindex already used 

can u help me out plz

Thanks

Akhil

stollmeyerastollmeyera

@Akhil,

 

There is actually a new in API version 23.0 that allows you to easily input taborders into your visualforce pages.  In the case of an input field, it works as such:

 

<apex:inputField taborderhint="1" Value="{!lead.company}"/>

<apex:inputField taborderhint="2" Value="{!lead.rating}"/>

 

In this case the page will start on the Company field and, upon clicking TAB, will shift to the Lead Rating field.  Hope this helps.  

SF7SF7

Hi  stollmeyera,

 

Thanks for replying , actually i tried that but the problem i had a function in a repeat tag when ever we use a repeat tag input field doesnt support tabhint.

And i cant remove the repeat tag becoz i got an important function in it.

 

Akhil

 

 

astroboiiiastroboiii

Nice solution Steve!  Unfortunately for me I could not use it as some pageblocksections and pageblocksectionitems were conditionally being rendered thus throwing off the tab orders.

I did some minimal testing and found out how the tab orders are working and how to work with them.  This is an extremely manual and tedious approach yet will always work.  At least through my exhaustive testing I have yet to break it or find a hitch.

Essentially what I do is the following:
1. Using Firebug or dev. console, find out the initial tabindex value for the first element where you expect your users to start tabbing from.

2. Upon finding this value go to your VF page and start adding tabIndex values for your input fields and 'tabOrderHint' values for your inputField's. One KEY thing to note here is that while tabIndex values when rendered are taken as defined in the VF page, tabOrderHint values have 10 added to defined values.  e.g. <apex:inputField value="{!Account.Name}" tabOrderHint="1" /> when rendered and checked via firebug/dev console will show you a tabindex value of 10.  I'm sure someone will be able to answer why, but I did not dig any deeper to understand why but just noticed this as a hard rule in using them.

That's it.

 

Now an example to illustrate:

 

<apex:page ...>
	 <!-- INDIVIDUAL CONTACT INFO SECTION -->
        <apex:pageBlockSection title="example">
                <apex:inputText value="" taborderhint="1"/>       
                <apex:inputField value="" taborderhint="2"/>       
                <apex:inputText value="" taborderhint="21"/>       
                <apex:inputText value="" taborderhint="22"/>       
                <apex:inputText value="" taborderhint="23"/>       
                <apex:inputField value="" taborderhint="3"/>       
                <apex:inputText value="" taborderhint="31"/>       
		...
	</apex:pageBlockSection>
</apex:page>

 
I hope that helps anyone who is just looking for a straightforward way of accomplishing this task.  What a nightmare :)

BijayBijay

Hi

I have use the javascript logic as mentioned in this post for tab order, but not able get the expected result, Can anyone please help me out...

 

Below is my code

 

<apex:page standardController="Case">
<script language="javascript">  function fixElements(tagn,attrib)
{
        var tags = document.getElementsByTagName(tagn);
        var ti;    
        var pos;
        alert('hari');      
        // Since Salesforce builds a complex Id using the Id's of previous elements, we need       
        // to find the one that we want.       
        // Note: this means we're searching for tags like:
        // apex:inputfield id="tabIndex4" ....>
        var pat = /:tabIndex[1-7]+/;
        for (var i=0; i < tags.length; i++) {
            if (tags[i].getAttribute(attrib) != null) {
                pos = tags[i].getAttribute(attrib).search(pat);
                if (pos != -1) {
                    ti = tags[i].getAttribute(attrib).slice(pos+9);
                    tags[i].setAttribute('tabIndex',ti);
                }
            }
        }
    }
        fixElements("input","id");
    fixElements("select","id");
</script>
<apex:form >
<apex:pageBlock >
    
        <apex:pageBlockSection columns="2" title="example" showHeader="true">
                <apex:inputText value="{!Case.Account}" id="tabIndex7" />      
                <apex:inputField value="{!Case.SuppliedCompany}" id="tabIndex3"/>      
                <apex:inputText value="{!Case.Subject}" id="tabIndex1"/>      
                <apex:inputText value="{!Case.SuppliedPhone}" id="tabIndex4"/>      
                <apex:inputText value="{!Case.SuppliedName}" id="tabIndex5"/>      
                <apex:inputField value="{!Case.Asset}" id="tabIndex6"/>      
                <apex:inputText value="{!Case.Subject}" id="tabIndex2"/>      

    </apex:pageBlockSection>
    </apex:pageBlock>
    </apex:form>
</apex:page>