Actions

J1.5 talk

Adding sortable columns to a table in a component

From Joomla! Documentation

Revision as of 11:36, 11 October 2009 by Fletcher (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

There is a problem with this example. As reported in many posts, the column headings only allow DESCending sorts. In addition, the grid.sort method called by JHTML doesn't display the sort direction arrow graphic. If you can live without having the final sort column and sort direction stored in the user state for future use, the problem can be fixed as follows. The whole process is shown rather than alterations.

1. Add a new private variable to the MODEL

var $_order  = array();

2. Add the following lines to the MODEL __construct() function

 $this->_order[] = JRequest::getVar('filter_order', 'fieldName', 'POST', 'cmd');
 $this->_order[] = JRequest::getVar('filter_order_Dir', 'asc', 'POST', 'word');

Replace 'fieldName' with the name of the MySQL field name you want to sort by default.

3. Add a new private function to the MODEL to general the necessary MySQL query suffix

function _buildContentOrderBy() {
 return ' ORDER BY '.$this->_order[0].' '.$this->_order[1].' ';
}

Obviously the MODEL will need to call this function and append the result to any existing MySQL query before execution.

If, for example, the query was stored in a private variable called $_query, the following would need to be added

$this->_query .= $this->_buildContentOrderBy();

4. Add a new public function to the MODEL so that the ordering field and direction can be passed to the VIEW

function getOrder() {
 return $this->_order;
}

5. Add the following lines to the display() function in the VIEW (usually view.html.php)

 $lists =& $this->get( 'order' );
 $this->assignRef( 'lists', $lists );

This passes the array containing the ordering field and direction to the TEMPLATE

6. To conform with HTML add the following to the TEMPLATE (usually default.php)

<?php
JFactory::getDocument()->addScriptDeclaration( "
function tableOrdering( order, dir, task ) {
 var form = document.formName;
 form.filter_order.value = order;
 form.filter_order_Dir.value = dir;
 form.submit( task );
}" ); ?>

This ensures that the Javascript necessary is placed between the the <head></head> tags.

Change 'formName' to the name attribute of the <form> used later (see below)

7. Enclose the table to be sorted in <form></form> tags and add two hidden input fields as follows

<form action="index.php?option=com_componentName" method="post" name="formName">
 ...
 table goes here
 ...
 <input type="hidden" name="filter_order" value="<?php echo $this->lists[0]; ?>" />
 <input type="hidden" name="filter_order_Dir" value="<?php echo $this->lists[1]; ?>" />
</form>

Change the <form> action attribute as needed or use the JRoute method if you have the file router.php set up for SEF URLs.

8. For each of the columns you want to sort, replace each of the column headings with the following (enclosed in 'th' and '/th' tags)

<?php echo JHTML::_( 'grid.sort', 'column1Name', 'field1Name', $this->lists[1], $this->lists[0]); ?>

Leave non-sortable columns unchanged

Preserving the state of 'filter_order' and 'filter_order_Dir' could be achieved by altering the MODEL __construct() function.