Looking for a better way to set a default filter on initial view of a backend list view.

50 views
Skip to first unread message

Neo314

unread,
Feb 29, 2024, 10:36:55 PMFeb 29
to Joomla! General Development
Hi folks,

I have managed to achieve my goal, but it seems there should be a simpler way to do this. I want to make it so that when a back-end list view is opened, it defaults to filter the list of reservations to the most current event. However, after the initial view, the filters work normally, i.e. you can clear the filter and view all reservations for all events again. This turned out to be more challenging than expected.

I start with a function in the model that:
  1. Reads a user state flag to determine that this is a first/initial opening of the list by the user
  2. Finds the most recent event id, 
  3. Sets the filter value in state, 
  4. Sets a flag in the user state saying that the initial view has been set (so we know not to replace an empty filter if the user clears the filter).
  5. Sets the most recent event id in a user state value (for potential messaging options, optional)

public function checkDefaultFilter()
{
$app = Factory::getContainer()->get(SiteApplication::class);
$test = $app->getUserState('request_visit_default');
if (!$test) {
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select($db->quoteName('e.id'))
->from($db->quoteName('#__gwrequests_events','e'))
->order($db->quoteName('e.event_start') . ' DESC');
$db->setQuery($query);
$db->execute();
$event_id = $db->loadResult();
$this->setState('filter.event_id',$event_id);
$app->setUserState('default.event_id',$event_id);
return $event_id;
} else {
return false;
}
}

Then I execute the method at the top of the getListQuery method or the filter is not applied
$this->checkDefaultFilter();

and then at the top of the HtmlView file display method I need this IF statement in order to get the filter form to show and have the correct event selected.

$app = Factory::getContainer()->get(SiteApplication::class);
$this->items = $this->get('Items');
$this->pagination = $this->get('Pagination');
$this->state = $this->get('State');
$this->filterForm = $this->get('FilterForm');
$this->activeFilters = $this->get('ActiveFilters');
$this->default_event_id = $app->getUserState('default.event_id');

if (!$app->getUserState('request_visit_default')) {
$this->filterForm->getData()->set('filter.event_id', $this->default_event_id); //->get('filter')->event_id = 22;
$this->activeFilters = array('event_id' => $this->default_event_id);
$app->setUserState('request_visit_default',true);
}

Anyone know of an easier way to accomplish this. 

It seems like I should just be able to push this filter into use somewhere, but everything I tried either not filter the records, or filter the records but not be able to be cleared, or not show the current filter on the filter form (and thus be unable to be cleared.

Neo314

unread,
Mar 1, 2024, 11:40:58 PMMar 1
to Joomla! General Development
I found my better answer. It was through populateState.

protected function populateState($ordering = null, $direction = null) {

$app = Factory::getContainer()->get(SiteApplication::class);
if ($app->getUserState('request_visit_default') === null) {
$app->setUserState('request_visit_default',true);
}
if ($app->getUserState('request_visit_default')) {

$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select($db->quoteName('e.id'))
->from($db->quoteName('#__gwrequests_events','e'))
->order($db->quoteName('e.event_start') . ' DESC');
$db->setQuery($query);
$db->execute();
$event_id = $db->loadResult();
$cur_state = $app->getUserState($this->context . '.filter', null);
$cur_state['event_id'] = $event_id;
$app->setUserState($this->context . '.filter',$cur_state,'array');
$app->setUserState('default.event_id',$event_id);
}
parent::populateState($ordering = null, $direction = null);
}
Reply all
Reply to author
Forward
0 new messages