How to add custom filters to components

From Joomla! Documentation

Revision as of 07:28, 23 November 2012 by E-builds (Talk | contribs)


This how-to is intended to give a decent description on how to add dropdown form elements to the backend admin page for a component. I worked out the steps primarily on my own by dissecting/replicating the Banners component. In particular, the 'banners' section of com_banners - not! to be confused with 'banner').

In general, the process of adding these fields breaks down into the following steps:

  • Creating the class that will generate the form element
  • Adapting the view to display the form element
  • Adapting the model to retrieve data from DB & to set submission values in the Joomla 'state'
Frontend component note

I have followed and tested this approach and it's almost the exact same for the frontend component.
Might want to change and redirect this article's title though (with maybe some changes?).

Extend JFormFieldList (models / fields / fieldname.php)

Frequently your filter fields will be very basic; probably simply a dropdown list of one of the columns being displayed on the current page. Regardless, you will need to create your own field element. This really isn't a big deal - this file will probably be less than 70 lines, including comments. The code below will generate the dropdown element to filter by companies. For more information and complex examples on creating this class see Creating_a_custom_form_field_type.

My 'companies' dropdown element:

defined('JPATH_BASE') or die;
 * Custom Field class for the Joomla Framework.
 * @package		Joomla.Administrator
 * @subpackage	        com_my
 * @since		1.6
class JFormFieldMyCompany extends JFormFieldList
	 * The form field type.
	 * @var		string
	 * @since	1.6
	protected $type = 'MyCompany';
	 * Method to get the field options.
	 * @return	array	The field option objects.
	 * @since	1.6
	public function getOptions()
		// Initialize variables.
		$options = array();
		$db	= JFactory::getDbo();
		$query	= $db->getQuery(true);
		$query->select('id As value, name As text');
		$query->from('#__my_companies AS a');
		$query->where('state = 1');
		// Get the options.
		$options = $db->loadObjectList();
		// Check for a database error.
		if ($db->getErrorNum()) {
			JError::raiseWarning(500, $db->getErrorMsg());
		return $options;

Obviously, there is only one section here that needs to be customized:

		$query->select('id As value, name As text');
		$query->from('#__my_companies AS a');
		$query->where('state = 1');

Change the database name and adjust the sql as necessary. This will produce the text and values for the select element options. I highly recommend not changing the value and text names. Although I did not test this theory, it seems likely that ancestor classes are expecting these names as keys in the resulting array.

Modify Model (models / zzz.php)

In your model you have to include these two functions:

protected function getListQuery(){
		$db = JFactory::getDBO();
		$query = $db->getQuery(true);
                //CHANGE THIS QUERY AS YOU NEED...
                $query->select('id As value, name As text');
		$query->from('#__my_companies AS a');
		$query->where('state = 1');
		// Filter
		$search = $this->getState('');
		if (!empty($search)) {
			$query->where('( LIKE '.$search.')');
		return $query;
	 * Method to auto-populate the model state.
	 * Note. Calling getState in this method will result in recursion.
	 * @since	1.6
	protected function populateState($ordering = null, $direction = null)
		// Initialise variables.
		$app = JFactory::getApplication('administrator');
		// Load the filter state.
		$search = $this->getUserStateFromRequest($this->context.'', 'filter_search');
		$this->setState('', $search);
		$state = $this->getUserStateFromRequest($this->context.'.filter.state', 'filter_state', '', 'string');
		$this->setState('filter.state', $state);
		// List state information.
		parent::populateState('', 'asc');

Extra fields and inside words

Here is a small modification to search in multiple fields in your database ánd to also search inside words.

// Filter
		$search = $this->getState('');
		if (!empty($search)) {
			$query->where('( LIKE "%'.$search.'%" OR LIKE "%'.$search.'%"));

Modify View (views / zzz / view.html.php)

In you view class, you have to set the state, like this:

                $this->items		= $this->get('Items');
		$this->pagination	= $this->get('Pagination');
                //Add the state...
		$this->state		= $this->get('State');

Modify Template (views / zzz / tmpl / default.php)

In your template file, remember to include the html form to filter.

<div class="filter-search fltlft">
	<label class="filter-search-lbl" for="filter_search"><?php echo JText::_('JSEARCH_FILTER_LABEL'); ?></label>
	<input type="text" name="filter_search" id="filter_search" value="<?php echo $this->escape($this->state->get('')); ?>" title="<?php echo JText::_('COM_MYCOMPANY_SEARCH_IN_TITLE'); ?>" />
	<button type="submit"><?php echo JText::_('JSEARCH_FILTER_SUBMIT'); ?></button>
	<button type="button" onclick="'filter_search').value='';this.form.submit();"><?php echo JText::_('JSEARCH_FILTER_CLEAR'); ?></button>

Extra: highlighting search terms

Here is some extra to visually mark the found search terms in the results page.


Add this somewhere at top somehwere:

$searchterms = $this->state->get('');
//Highlight search terms with js (if we did a search => more performant and otherwise crash)
if (strlen($searchterms)>1) JHtml::_('behavior.highlighter', explode(' ',$searchterms));

And further in your template, enclose the specific fields with the default highlighter finder.


<span id="highlighter-start"></span>
	<table class="adminlist">
<span id="highlighter-end"></span>


If your default admin template doesn't have required css, you should add the class in your component css.

Example in controller:

JHtml::stylesheet('com_peopleactions/admin.css', array(), true);

In admin.css:

.highlight {   background: none repeat scroll 0 0 #FFFF00; }


Javier Constanzo