[SalesForce] Issues with sorting on pageblock table

Hi I recently came across a jQuery animated table sorter plugin from here and I'm trying to leverage it on one of my visualforce pages. It seems straightforward enough but I can't for some reason get it to work on my page. Below is my code:

<apex:page Controller="CasesController" showHeader="false" docType="HTML-5.0" id="thePage">

 <apex:includeScript value="{!URLFOR($Resource.jQuery, 'js/jquery-1.7.2.min.js')}"/>
 <apex:includeScript value="{!URLFOR($Resource.jQuery, 'js/jquery.tools-1.2.2.min.js')}"/>
 <apex:includeScript value="{!URLFOR($Resource.jQueryAnimatedTableSorter, 'animatedtablesorter-0.2.2/tsort.js')}"/>
 <apex:includeScript value="{!URLFOR($Resource.jQueryAnimatedTableSorter, 'animatedtablesorter-0.2.2/tsort.min.js')}"/>

 <apex:stylesheet value="{!URLFOR($Resource.jQueryAnimatedTableSorter,'/animatedtablesorter-0.2.2/style.css')}"/> 


<apex:form id="theForm">      
      <apex:pageBlock id="thePageBlock">
          <apex:pageBlockTable value="{!MyCaseList}" var="mylist" id="thePageBlockTable">          
              <apex:column headerValue="Case Number">
              <apex:outputLink value="{!mylist.CaseNumber}">{!mylist.CaseNumber}</apex:outputLink>
              </apex:column>
              <apex:column value="{!mylist.CreatedDate}"/>
              <apex:column value="{!mylist.Requested_By__c}"/>
              <apex:column value="{!mylist.Subject}"/>
              <apex:column value="{!mylist.Release_Type__c}"/>
              <apex:column value="{!mylist.Status}"/>
              <apex:column value="{!mylist.Priority}"/>
              <apex:column value="{!mylist.Version__c}"/>
              <apex:column value="{!mylist.OwnerId}"/>
              <apex:column value="{!mylist.Type}"/>
          </apex:pageBlockTable>               
      </apex:pageBlock>          
    </apex:form> 

<script language="javascript" type="text/javascript">

  var j$ = jQuery.noConflict();

 j$(document).ready(function(){
     var dataTable = document.getElementById("{!$Component.AssignmentRequest:thePage:theForm:thePageBlock:thePageBlockTable}");

     j$(datatTable.tableSorter).tableSort( {
         sortBy: ['numeric','numeric','text','text','text','text','text','text','text','text',],

         animation: 'slide',
         speed: 400

         });

  }); 
</script>       
</apex:page> 

Anyone with any suggestions as to what I may be missing? Thanks.

Best Answer

A couple of issues:


You don't need both of these lines. Keep the .min script and remove the other from the page markup.

<apex:includeScript value="{!URLFOR($Resource.jQueryAnimatedTableSorter, 'animatedtablesorter-0.2.2/tsort.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jQueryAnimatedTableSorter, 'animatedtablesorter-0.2.2/tsort.min.js')}"/>

This:

j$(document).ready(function(){
     var dataTable = document.getElementById("{!$Component.AssignmentRequest:thePage:theForm:thePageBlock:thePageBlockTable}");

Based on the structure in your example code should be: (removed AssignmentRequest, used dot notation for the hierarchy)

j$(document).ready(function(){
     var dataTable = document.getElementById("{!$Component.thePage.theForm.thePageBlock.thePageBlockTable}");

Your variable for the element in the jQuery selector is misspelled, datatTable (which you may have since corrected) and the <apex:pageBlockTable> tag does not have a styleClass attribute on it of 'tableSorter' (and does not need to) so this selector is too restrictive and will not match the table in your page.

So this:

 j$(datatTable.tableSorter).tableSort( {

Should be: (corrected spelling, removed CSS class name)

 j$(dataTable).tableSort( {

One other thing to help you troubleshoot a bit:

When you view this page in the browser and look at the source for the page, you should see the $Component element from your VF markup replaced with the actual ID value of the table from your page source. If the value between the parentheses is blank, your $Component syntax is incorrect and needs to be modified.

The result of an "unsuccessful" component reference where VF couldn't find the component you described will look like this in the rendered page markup:

var dataTable = document.getElementById("");

The result of a "successful" component reference based on your example should look similar to this:

var dataTable = document.getElementById("thePage:theForm:thePageBlock:thePageBlockTable");

Related documentation about best practices for referencing component ID values

Related Topic