Welcome, Guest
Username: Password: Remember me

TOPIC: [HELP GUIDE] Filter menu item on category

[HELP GUIDE] Filter menu item on category 16 Sep 2012 20:11 #3693

  • dyvel
  • dyvel's Avatar
  • Offline
  • Elite Member
  • Posts: 200
  • Thank you received: 11
  • Karma: 10
Hi

This is something I think many would find useful, so I thought I'd share my solution. I needed a solution to filter my list of items without having the user involved - eg. to select a category to show items from.

So beyond the "obvious" of creating the relations between the tables, and adding the category to a filter in the list view, I had to do some custom coding. I'm not really a very skilled coder, so my solution my not be the best, but it works.

I needed to filter on 3 tables, so my code below is based on that - you would need to modify the code to your component

First:
in my default.xml file for the view in question I added this after layout:
    <!-- Add fields to the request variables for the layout. -->
	<fields name="params">
		<fieldset name="request">
			<field name="category"
				type="text"
				description="Category"
				label="Category"
				size="5"
			/>
			<field name="network_carrier"
				type="text"
				description="Carrier"
				label="Carrier"
				size="5"
			/>
			<field name="brand_model"
				type="text"
				description="Model"
				label="Model"
				size="5"
			/>
		</fieldset>
	</fields>

in components/com_[componentname]/models/[viewname].php I modified the WHERE - FILER:
		// Get filter fra menu params
		$app = JFactory::getApplication(); 
		$params = $app->getParams(); 
		
		//WHERE - FILTER : Network carrier
		if($this->getState('filter.network_carrier')) {
			$query->where('a.network_carrier = '. (int)$this->getState('filter.network_carrier'));
		} elseif($params->get('network_carrier')) {
			$query->where('a.network_carrier = '. (int)$params->get('network_carrier'));
		}
		
		//WHERE - FILTER : Brand Model
		if($this->getState('filter.brand_model')) {
			$query->where('a.brand_model = '. (int)$this->getState('filter.brand_model'));
		} elseif($params->get('brand_model')) {
			$query->where('a.brand_model = '. (int)$params->get('brand_model'));
		}
		
		//WHERE - FILTER : Category
		if($this->getState('filter.category')) {
			$query->where('a.category = '. (int)$this->getState('filter.category'));
		} elseif($params->get('category')) {
			$query->where('a.category = '. (int)$params->get('category'));
		}


in components/com_[componentname]/views/[viewname].php I modified the code after //Filters:
		// Get filter fra menu params
		$app = JFactory::getApplication(); 
		$params = $app->getParams(); 

		//Network carrier > Title
		$model_network_carrier = JModel::getInstance('networkcarriers', 'ComparemobileModel');
		$this->filters['network_carrier'] = new stdClass();
		$this->filters['network_carrier']->list = $model_network_carrier->getItems();
		if ($model->getState("filter.network_carrier")){
			$this->filters['network_carrier']->value = $model->getState("filter.network_carrier");
		} else {
			$this->filters['network_carrier']->value = $params->get('network_carrier');
		}

		//Brand Model > Title
		$model_brand_model = JModel::getInstance('brandmodels', 'ComparemobileModel');
		$model_brand_model->addJoin("LEFT JOIN #__comparemobile_brands AS _brand_ ON _brand_.id = a.brand");
		$model_brand_model->addSelect("_brand_.title AS _brand_title");
		$model_brand_model->addGroupBy("_brand_.title");
		$this->filters['brand_model'] = new stdClass();
		$this->filters['brand_model']->list = $model_brand_model->getItems();
		if ($model->getState("filter.brand_model")){
			$this->filters['brand_model']->value = $model->getState("filter.brand_model");
		} else {
			$this->filters['brand_model']->value = $params->get('brand_model');
		}
		
		//Category > Title
		$model_category = JModel::getInstance('categories', 'ComparemobileModel');
		$this->filters['category'] = new stdClass();
		$this->filters['category']->list = $model_category->getItems();
		$this->filters['category']->list = $model_category->getItems();
		if ($model->getState("filter.category")){
			$this->filters['category']->value = $model->getState("filter.category");
		} else {
			$this->filters['category']->value = $params->get('category');
		}

last I modified default_filters.php template for the view:
<?php
defined('_JEXEC') or die('Restricted access'); 
// Get filter fra menu params
$app = JFactory::getApplication(); 
$params = $app->getParams();
$category = $params->get('category');
$brand_model = $params->get('brand_model');
$network_carrier = $params->get('network_carrier');
?>
<?php if(!$category || !$brand_model || !$network_carrier) { ?>
<script language="javascript" type="text/javascript">
<!--


function resetFilters()
{
	if (typeof(jQuery) != 'undefined')
	{
		jQuery('.filters :input').val('');

	/* TODO : Uncomment this if you want that the reset action proccess also on sorting values
		jQuery('#filter_order').val('');
		jQuery('#filter_orderDir').val('');
	*/
		document.adminForm.submit();
		return;
	}

//Deprecated
	if ($('filter_network_carrier') != null)
	    $('filter_network_carrier').value='';
	if ($('filter_brand_model') != null)
	    $('filter_brand_model').value='';
	if ($('filter_category') != null)
	    $('filter_category').value='';


/* TODO : Uncomment this if you want that the reset action proccess also on sorting values
	if ($('filter_order') != null)
	    $('filter_order').value='';
	if ($('filter_orderDir') != null)
	    $('filter_orderDir').value='';
*/

	document.adminForm.submit();
}

-->
</script>

<fieldset id="filters" class="filters">
	<legend><?php echo JText::_( "JSEARCH_FILTER_LABEL" ); ?></legend>



	<div style="float:right;">
		<div style="float:left">
				<div class="filter filter_buttons">
					<button onclick="this.form.submit();"><?php echo(JText::_("JSEARCH_FILTER_SUBMIT")); ?></button>
					<button onclick="resetFilters()"><?php echo(JText::_("JSEARCH_FILTER_CLEAR")); ?></button>
				</div>
		</div>
	</div>

	<div>

		<?php if (!$category) { ?>
		<div style="float:left">
			<!-- SELECT : Category  -->

				<div class='filter filter_category'>
					<?php echo JDom::_('html.form.input.select', array(
											'dataKey' => 'filter_category',
											'dataValue' => $this->filters['category']->value,
											'list' => $this->filters['category']->list,
											'labelKey' => 'title',
											'nullLabel' => "COMPAREMOBILE_FILTER_NULL_CARRIER",
											'submitEventName' => 'onchange'
												));

						?>
				</div>
		</div>
		<?php } ?>
		
		<?php if (!$network_carrier) { ?>
		<div style="float:left">
			<!-- SELECT : Network carrier > Title  -->

				<div class='filter filter_network_carrier'>
					<?php echo JDom::_('html.form.input.select', array(
											'dataKey' => 'filter_network_carrier',
											'dataValue' => $this->filters['network_carrier']->value,
											'list' => $this->filters['network_carrier']->list,
											'labelKey' => 'title',
											'nullLabel' => "COMPAREMOBILE_FILTER_NULL_CARRIER",
											'submitEventName' => 'onchange'
												));

						?>
				</div>
		</div>
		<?php } ?>
		
		<?php if (!$brand_model) { ?>
		<div style="float:left">
			<!-- SELECT : Brand Model > Title  -->

				<div class='filter filter_brand_model'>
					<?php echo JDom::_('html.form.input.select', array(
											'dataKey' => 'filter_brand_model',
											'dataValue' => $this->filters['brand_model']->value,
											'list' => $this->filters['brand_model']->list,
											'labelKey' => 'title',
											'nullLabel' => "COMPAREMOBILE_FILTER_NULL_MODEL",
											'submitEventName' => 'onchange',
											'groupBy' => array(
													'brand' => '_brand_title'
											)
												));

						?>
				</div>
		</div>
		<?php } ?>
		
	</div>

	<div clear='all'></div>

</fieldset>
<?php } ?>

So now, my filters will only show up if the filter is not pre filled in menu and if all filters is pre filled, the filters option will not show at all in my view.

I hope this helps some of you creating better components.

Cheers...
The administrator has disabled public write access.
The following user(s) said Thank You: admin, sonysony, JoomGuy

Re: How to guide: filter menu item on category 16 Sep 2012 20:58 #3694

  • sonysony
  • sonysony's Avatar
  • Offline
  • New Member
  • Posts: 15
  • Thank you received: 5
  • Karma: 2
works like a charm B)


UPGRADE:
I did just quick test and this is working almost for anything.
For example you would like to show only featured items - for reference also see example above!

Important: there is no need that field must be in filter box, if you want base fields from table( all are always selected). But this does not include foreign key fields.

1. You need field "featured" in your table as bool

2. In XML add (also see examle above):
<fields name="params">
		<fieldset name="request">
			<field name="featured" type="radio" default="0" label="Show only featured" description="Show only featured">
				<option value="0">NO</option>
				<option value="1">YES</option>
			</field> 
		</fieldset>
	</fields>

3. component/models/your_view.php
After line //WHERE - FILTER : ***
Add if you did not before:
$app = JFactory::getApplication(); 
$params = $app->getParams();
Add
if ($params->get('featured')==1) { $query->where('a.featured = 1'); }
Last Edit: 16 Sep 2012 22:10 by sonysony.
The administrator has disabled public write access.
The following user(s) said Thank You: admin, JoomGuy

Re: How to guide: filter menu item on category 17 Sep 2012 06:13 #3695

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 987
  • Karma: 140
Thank you very much dyvel.

Karma +2
Coding is now a piece of cake
The administrator has disabled public write access.

Re: How to guide: filter menu item on category 17 Sep 2012 08:39 #3702

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 987
  • Karma: 140
Isn't 2.0 easier for that ?
Coding is now a piece of cake
The administrator has disabled public write access.

Re: How to guide: filter menu item on category 17 Sep 2012 09:56 #3703

  • sonysony
  • sonysony's Avatar
  • Offline
  • New Member
  • Posts: 15
  • Thank you received: 5
  • Karma: 2
I belive it was almost the same.

In v 1.5 the things ware/are like this in function _buildQueryWhere($where = array())

you add anywhere: $where[] = "a.featured = 1";

in v. 2.0 is: $query->where('a.featured = 1');

for me is the same.
The administrator has disabled public write access.

Re: [HELP GUIDE] Filter menu item on category 17 Sep 2012 16:37 #3705

  • sonysony
  • sonysony's Avatar
  • Offline
  • New Member
  • Posts: 15
  • Thank you received: 5
  • Karma: 2
I do not have time, so I will just put quick info, how qou can make select box, so you do not need to write down cid.

Some information you will get here: docs.joomla.org/Developing_a_Model-View-...5/Using_the_database

in component/your_component/views/collection_view/tmpl/default.xml
<fields name="request">
<fieldset name="request" addfieldpath="/administrator/components/your_component/models/fields/">
                        <field
                                name="category"
                                type="categorycid"
                                label="Select category"
                                description="Select category"
                        />
</fieldset>
</fields>

in /administrator/components/your_component/models/fields/ create new file for examlple: categorycid.php
<?php
// No direct access to this file
defined('_JEXEC') or die;
 
// import the list field type
jimport('joomla.form.helper');
JFormHelper::loadFieldClass('list');
 
class JFormFieldYourComponent extends JFormFieldList
{
        protected $type = 'categorycid'; //must be the same as type in xml
 
        protected function getOptions() 
        {
                $db = JFactory::getDBO();
                $query = 'SELECT id, title FROM #__your_component_categories';
                $db->setQuery($query);
                $categories = $db->loadObjectList();
                $options = array();
		$options[] = JHTML::_('select.option','',JText::_('-- Select --')); //Put default value to empty
                if ($categories)
                {
                        foreach($categories as $category) 
                        {
                                $options[] = JHtml::_('select.option', $category->id, $category->title);
                        }
                }
                $options = array_merge(parent::getOptions(), $options);
                return $options;
        }
}

I hope that this is enough to understand, at least for those with a little more knowledge
Last Edit: 17 Sep 2012 16:40 by sonysony.
The administrator has disabled public write access.
The following user(s) said Thank You: admin, dyvel
Time to create page: 0.156 seconds

Get Started