Sort columns in joomla via populateState method
getstate, joomla, sorting
Solution
After just coming across the same issue I found that, as you said, the superclass populateState() does indeed have the behaviour defined. However, it also does a check to ensure your field is in the "whitelist".
if (!in_array($value, $this->filter_fields))
If you look at com_content you will see this section at the top of the model class (in your case models/articles.php):
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array(
'id', 'a.id',
'title', 'a.title',
//...(more fields here)
'publish_up', 'a.publish_up',
'publish_down', 'a.publish_down',
);
$app = JFactory::getApplication();
$assoc = isset($app->item_associations) ? $app->item_associations : 0;
if ($assoc)
{
$config['filter_fields'][] = 'association';
}
}
parent::__construct($config);
}
You will need to include this section so that the ModelList class knows that the 'ordering' field is in the whitelist. Obviously substitute the fields with those on which you wish to filter.
Problem
I'm sorting table columns in Joomla Backend. I adjust settings according to this tutorial. As we can see it is suggested to override `populateState` method and manually obtain sorting options. ``` public function populateState() { $filter_order = JRequest::getCmd('filter_order'); $filter_order_Dir = JRequest::getCmd('filter_order_Dir'); $this->setState('filter_order', $filter_order); $this->setState('filter_order_Dir', $filter_order_Dir); } ``` But I noticed that the native component `com_content` does not set these options explicitly in the model file `administrator/components/com_content/models/articles.php`. ``` protected function populateState($ordering = null, $direction = null) { // Initialise variables. $app = JFactory::getApplication(); $session = JFactory::getSession(); ............................................ ............................................ ............................................ // List state information. parent::populateState('a.title', 'asc'); } ``` Instead it just invokes parent `populateState`. And in fact `JModelList::populateState()` includes this: ``` protected function populateState($ordering = null, $direction = null) { // If the context is set, assume that stateful lists are used. if ($this->context) { $app = JFactory::getApplication(); ..................................... ..................................... ..................................... $value = $app->getUserStateFromRequest($this->context.'.ordercol', 'filter_order', $ordering); if (!in_array($value, $this->filter_fields)) { $value = $ordering; $app->setUserState($this->context.'.ordercol', $value); } $this->setState('list.ordering', $value); // Check if the ordering direction is valid, otherwise use the incoming value. $value = $app->getUserStateFromRequest($this->context.'.orderdirn', 'filter_order_Dir', $direction); if (!in_array(strtoupper($value), array('ASC', 'DESC', ''))) { $value = $direction; $app->setUserState($this->context.'.orderdirn', $value); } $this->setState('list.direction', $value); } else { $this->setState('list.start', 0); $this->state->set('list.limit', 0); } } ``` So I'm trying to imitate the code of the native `com_content`. Thus I assume that ``` class CompViewData extends JView { function display($tpl = null) { $this->state = $this->get('State'); ``` Will invoke parent `JModelList::populateState()` (so I'm not overriding it in the modal class) and set `$this->setState('list.ordering', $value);`. But for some reason when I invoke `$this->state->get()` in `getListQuery()` to build my SQL query with ordering ``` protected function getListQuery() { $orderCol = $this->state->get('list.ordering', 'id'); $orderDirn = $this->state->get('list.direction', 'asc'); ``` This variables happen to be not defined. What am I missing? I assume it is somehow connected with proper user session, but I don't have evidence whatsoever.