You are here:  » Using a drop down list of categories with search.php


Using a drop down list of categories with search.php

Submitted by sfakman on Wed, 2010-02-10 11:32 in

Hi David,

Love your product! It's been a joy to use.

I wanted to add a drop down list of categories as part of the main site search. The intention is a user enters a search term such as "beanie hats" and they want to search within the "Hats and Accessories" category.

I saw in the query string:

"search.php?q=category:Hats and Accessories&select=all"

So I can get it to return all items in a category but I was unsure of the query that would enable me to search within the category.

Many thanks,

George

Submitted by support on Wed, 2010-02-10 14:43

Hi George,

Thank you for your comments. Try the following as a complete replacement for html/searchform.php

<div class='searchform'>
  <form name='search' action='<?php print $config_baseHREF ?>search.php'>
    <input type='text' name='q' id='q' size='35' value='<?php print (isset($q)?$q:""); ?>' />
<?php
  $sql = "SELECT DISTINCT(category) as category FROM `".$config_databaseTablePrefix."products` ORDER BY category";
  if (database_querySelect($sql,$rows))
  {
    print "<select name='category'>";
    print "<option value=''>All categories</option>";
    foreach($rows as $row)
    {
      $selected = (($row["category"]==$_GET["category"])?"selected='selected'":"");
      print "<option value='".$row["category"]."' ".$selected.">".$row["category"]."</option>";
    }
    print "</select>&nbsp;";
  }
?>
    <input type='submit' value='<?php print translate("Search"); ?>' />
  </form>
</div>

...and then make the following changes to search.php (latest version)

Look for the following code on line 155 (11/09A) 215 (12/10B)

          $where = "MATCH ".$matchFields." AGAINST ('".database_safe($parts[0])."')";

...and REPLACE with:

          $where = "MATCH ".$matchFields." AGAINST ('".database_safe($parts[0])."')";
          if ($_GET["category"])
          {
            $where .= " AND category='".database_safe($_GET["category"])."'";
          }

Look for the following code on line 193:

          $where = implode(" AND ",$wheres);

...and REPLACE with:

          $where = implode(" AND ",$wheres);
          if ($_GET["category"])
          {
            $where .= " AND category='".database_safe($_GET["category"])."'";
          }

Look for the following code on line 236 (11/09A) 251 (12/10B)

      $sortHREF .= "sort=";

...and REPLACE with

      if ($_GET["category"])
      {
        $sortHREF .= "&amp;category=".urlencode($_GET["category"])."&amp;";
      }
      $sortHREF .= "sort=";

...and finally look for the following code on line 306 (11/09A) 375 (12/10B)

  require("html/navigation.php");

...and REPLACE with:

    if ($_GET["category"])
    {
      $sort .= "&amp;category=".urlencode($_GET["category"]);
    }
    require("html/navigation.php");

Cheers,
David.

Submitted by sfakman on Wed, 2010-02-10 16:24

Fantastic - one quick one - once the user has done a search, can you just show me the code to ensure the selected category is selected in the drop down still?

Thanks again!

Submitted by support on Wed, 2010-02-10 16:50

Hi,

In html/searchform.php, in place of:

    foreach($rows as $row)
    {
      print "<option value='".$row["category"]."'>".$row["category"]."</option>";
    }

...use:

    foreach($rows as $row)
    {
      $selected = (($row["category"]==$_GET["category"])?"selected='selected'":"");
      print "<option value='".$row["category"]."' ".$selected.">".$row["category"]."</option>";
    }

(i've added this into the code above)

Cheers,
David.

Submitted by sfakman on Thu, 2010-02-11 09:17

Hi David,

That's great - works well.

Just a heads up - I think you may have meant searchform.php not searchresults.php (just in case someone else wants to do the same).

Thanks!

George

Submitted by support on Thu, 2010-02-11 09:18

Ooops yes - corrected above...!

Cheers,
David.

Submitted by italiano28 on Sat, 2010-04-17 07:41

Hello David,i cant see that strings in the latest search.php script,so i don t know where i must to do the changes,can you help me please? Thank you.

Submitted by support on Sat, 2010-04-17 09:35

Hi,

The above instructions refer to the distribution version of search.php in the latest release (11/09A). If that is the version you are running and you have made changes to your copy already the lines will have moved, so if you're not sure if you want to email me your copy I'll make the changes for you.

Otherwise, here are the same change to search.php described for the original version of Price Tapestry (retrospectively named as 01/06A).

Look for the following code on line 79:

          $sql = "SELECT * , MIN( price ) AS minPrice, MAX( price ) AS maxPrice, COUNT( id ) AS numMerchants, MATCH name AGAINST ('".database_safe($parts[0])."') AS relevance FROM `".$config_databaseTablePrefix."products` WHERE MATCH name AGAINST ('".database_safe($parts[0])."') GROUP BY name";

...and REPLACE with:

          if ($_GET["category"])
          {
            $sql = "SELECT * , MIN( price ) AS minPrice, MAX( price ) AS maxPrice, COUNT( id ) AS numMerchants, MATCH name AGAINST ('".database_safe($parts[0])."') AS relevance FROM `".$config_databaseTablePrefix."products` WHERE MATCH name AGAINST ('".database_safe($parts[0])."') AND category='".database_safe($_GET["category"])."' GROUP BY name";
            $sqlResultCount = "SELECT COUNT(DISTINCT(name)) as resultcount FROM `".$config_databaseTablePrefix."products` WHERE MATCH name AGAINST ('".database_safe($parts[0])."') AND category='".database_safe($_GET["category"])."'";
          }
          else
          {
            $sql = "SELECT * , MIN( price ) AS minPrice, MAX( price ) AS maxPrice, COUNT( id ) AS numMerchants, MATCH name AGAINST ('".database_safe($parts[0])."') AS relevance FROM `".$config_databaseTablePrefix."products` WHERE MATCH name AGAINST ('".database_safe($parts[0])."') GROUP BY name";
          $sqlResultCount = "SELECT COUNT(DISTINCT(name)) as resultcount FROM `".$config_databaseTablePrefix."products` WHERE MATCH name AGAINST ('".database_safe($parts[0])."')";
          }

Look for the following code on line 96:

          $sql = "SELECT * , MIN( price ) AS minPrice, MAX( price ) AS maxPrice, COUNT( id ) AS numMerchants FROM `".$config_databaseTablePrefix."products` WHERE ".$where." GROUP BY name";
          $sqlResultCount = "SELECT COUNT(DISTINCT(name)) as resultcount FROM `".$config_databaseTablePrefix."products` WHERE ".$where;

...and REPLACE with:

          if ($_GET["category"])
          {
            $sql = "SELECT * , MIN( price ) AS minPrice, MAX( price ) AS maxPrice, COUNT( id ) AS numMerchants FROM `".$config_databaseTablePrefix."products` WHERE ".$where." AND category='".database_safe($_GET["category"])."' GROUP BY name";
            $sqlResultCount = "SELECT COUNT(DISTINCT(name)) as resultcount FROM `".$config_databaseTablePrefix."products` WHERE ".$where." AND category='".database_safe($_GET["category"])."';
          }
          else
          {
            $sql = "SELECT * , MIN( price ) AS minPrice, MAX( price ) AS maxPrice, COUNT( id ) AS numMerchants FROM `".$config_databaseTablePrefix."products` WHERE ".$where." GROUP BY name";
            $sqlResultCount = "SELECT COUNT(DISTINCT(name)) as resultcount FROM `".$config_databaseTablePrefix."products` WHERE ".$where;
          }

Look for the following code on line 130:

      $sortHREF = $config_baseHREF."search.php?q=".urlencode($q)."&amp;page=1&amp;sort=";

...and REPLACE with

      if ($_GET["category"])
      {
        $sortHREF = $config_baseHREF."search.php?q=".urlencode($q)."&amp;page=1&amp;sort=";
      }
      else
      {
        $sortHREF = $config_baseHREF."search.php?q=".urlencode($q)."&amp;category=".urlencode($_GET["category"])."&amp;page=1&amp;sort=";
      }

...and finally look for the following code on line 196:

  if (isset($navigation)) require("html/navigation.php");

...and REPLACE with:

  if ($_GET["category"])
  {
    $sort .= "&amp;category=".urlencode($_GET["category"]);
  }
  if (isset($navigation)) require("html/navigation.php");

Cheers,
David.

Submitted by italiano28 on Sat, 2010-04-17 17:41

I emailed you...can t find that changes.. Thank you.

Submitted by support on Sat, 2010-04-17 17:44

Hi,

I will look out for your email, but nothing received at this time...

Cheers,
David.

Submitted by italiano28 on Sat, 2010-04-17 18:27

Wrong send XD Now is done,thank you :)

Submitted by support on Sat, 2010-04-17 18:31

Got it - thanks!

I will follow up to your email.

Cheers,
David.

Submitted by bat on Sat, 2011-04-30 14:11

I've put this mod in with my site running version 11/09 and it works a treat, but if you don't enter anything in the search box but you do select a category, no results appear.

Is there a way that you can show 'all results' for the category, if no search term has been entered but a category has been selected?

Submitted by support on Sun, 2011-05-01 09:54

Hello bat,

Sure - in your search.php, look for the following code near the top, after the filters have all been processed to create the $priceWhere variable:

  if ($q)

...and REPLACE that with:

  if ($categoryFilter && !$q)
  {
    $q = "bw:";
  }
  if ($q)

The bw: operator is "begins with", so bw: will return all products; and in this case of course filtered by categoryFilter...

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by bat on Sun, 2011-05-01 13:56

Hi David
I've replaced the code but it doesn't seem to have done anything.
The website it is on is: {link saved}

Submitted by support on Sun, 2011-05-01 15:35

Hi bat,

Could you email me your search.php and I'll check it out for you..

Cheers,
David.
--
PriceTapestry.com

Submitted by Dale on Mon, 2015-09-07 19:21

Hi David

Is this the same approach to take with a Joomla installation, for a category drop-down menu?

Kind regards
Dale

Submitted by support on Tue, 2015-09-08 09:10

Hello Dale,

The above code relates to an earlier distribution of Price Tapestry before front end search filters were implemented (e.g. categoryFilter), which are also implemented in PriceTapestry.org for Joomla, so basically all that is required is to create the drop down as part of the search form using the name "pto_categoryFilter".

As the Joomla search form is based on the Search Form template (/administrator/ > Components > PriceTapestry.org) the easiest thing to do would be to implement the category drop down using essentially the same markup as the category filter field from the Search Filters widget template, so if you add the following code to the Search Form template where required (making sure that it goes inside the <form> ... </form> markup...

<select name='pto_categoryFilter'>
  <option value=''>All Categories</option>
  %CATEGORIES%
</select>

...and then to add swap-out for the %CATEGORIES% placeholder, edit plugins/system/plg_pto_system/pto_search.php and look for the following code at line 34:

  $html = str_replace("%ACTION%",JURI::base(TRUE).$pto_config_baseHREF,$html);

...and REPLACE with:

  global $pto_config_databaseTablePrefix;
  global $pto_categoryFilter;
  $db = JFactory::getDBO();
  $sql = "SELECT DISTINCT(category) FROM `".$pto_config_databaseTablePrefix."products` ORDER BY category";
  $db->setQuery($sql);
  $pto_filterResults = $db->loadObjectList();
  $html_categories = "";
  foreach($pto_filterResults as $product)
  {
    $html_categories .= "<option ".($pto_categoryFilter==$product->category?"selected='selected'":"")." value='".htmlentities($product->category,ENT_QUOTES)."'>".$product->category."</option>";
  }
  $html = str_replace("%CATEGORIES%",$html_categories,$html);
  $html = str_replace("%ACTION%",JURI::base(TRUE).$pto_config_baseHREF,$html);

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by Dale on Tue, 2015-09-08 13:45

Thanks David! Unfortunately, I'm getting a syntax error at the moment:

{code saved}

Regards
Dale

Submitted by support on Tue, 2015-09-08 13:59

Sorry about that, Dale - I missed a ";" copying the code across, but also realised that $db had not been initialised so corrected both in the REPLACEment above...

Cheers,
David.
--
PriceTapestry.com

Submitted by Dale on Tue, 2015-09-08 14:17

No problem, works great. Many thanks David.