You are here:  » Multiple drop-down searchform


Multiple drop-down searchform

Submitted by marco on Sat, 2016-02-27 09:34 in

Hello,

I am trying to create a drop-down searchform (without any text input) on the homepage.

For example on the category field (only one level) and brand field. On default all categories and brands can be in the selectbox. If someone selects a category, only the relevant brands should be (dynamically) listed or if someone first selects a brand then all relevant categories should be listed. And after a selection and a click on the seachbutton the form should lead to the relevant searchresults page.

Could you point me in the right direction for creating this?

Best,
Marco

Submitted by support on Mon, 2016-02-29 14:21

Hello Marco,

A top level only category drop down is trickier but if required let me know and I'll work that out however using merchant and brand as an example, have a go with something like;

  <?php
    if (!isset($merchantFilter)) $merchantFilter = "";
    if (!isset($brandFilter)) $brandFilter = "";
    if (!isset($priceWhere))
    {
      $where = " 1 ";
      $priceWhere = " AND 1 ";
    }
  ?>
  <form name='search' action='<?php print $config_baseHREF ?>search.php'>
      <input type='hidden' name='q' value='bw:' />
      <select name='merchantFilter' onChange='JavaScript:this.form.submit();'>
        <option value=''>Merchant...</option>
        <?php
        $sql = "SELECT DISTINCT(merchant) FROM `".$config_databaseTablePrefix."products`
                  WHERE merchant <> '' AND ".$where.$priceWhere." ORDER BY merchant";
        database_querySelect($sql,$rows);
        foreach($rows as $row)
        {
          $selected = ($merchantFilter==$row["merchant"]?"selected='selected'":"");
          print "<option ".$selected." value='".$row["merchant"]."'>".$row["merchant"]."</option>";
        }
        ?>
      </select>
      <select name='brandFilter' onChange='JavaScript:this.form.submit();'>
        <option value=''>Brand...</option>
        <?php
        $sql = "SELECT DISTINCT(brand) FROM `".$config_databaseTablePrefix."products`
                  WHERE brand <> '' AND ".$where.$priceWhere." ORDER BY brand";
        database_querySelect($sql,$rows);
        foreach($rows as $row)
        {
          $selected = ($brandFilter==$row["brand"]?"selected='selected'":"");
          print "<option ".$selected." value='".htmlspecialchars($row["brand"],ENT_QUOTES,$config_charset)."'>".$row["brand"]."</option>";
        }
        ?>
      </select>
  </form>

This is essentially a modified version of the search filters code, but submitting a fixed query value of "bw:" (begins with) which returns all products, so the search results will be all products filtered by the values of the two drop-downs.

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by marco on Mon, 2016-02-29 16:54

Hi David,

Is it possible to use the values of two drop-downs for selection? Now if only one drop-down is selected it goes straight to the search page?

Best,
Marco

Submitted by support on Mon, 2016-02-29 17:00

Hi Marco,

Sure - if you remove the auto-submit JavaScript from each <select> box:

onChange='JavaScript:this.form.submit();'

...and then introduce a submit button just before the closing </form> tag;

<input type='submit' value='Search' />

Then you'll be able to select multiple values before seeing results...

Cheers,
David.
--
PriceTapestry.com

Submitted by marco on Tue, 2016-03-01 07:12

How can i prevent that a user can make a non existing combination? I think it needs some ajax magic. But the magic part is where i get lost.
Based on the ajax in /node/5473/, i have created this index.php page. Can you see where this goes wrong?

<?php
  if (!isset($_GET["ajax"]))
  {
  require("includes/common.php");
  require("html/headersf.php");
  require("html/menu.php");
  }
?>
  <script type='text/JavaScript'>
    function pt_sf_onchange()
    {
      $("#pt_sr_body").load("<?php print $config_baseHREF?>?ajax=1&"+$("#pt_sf").serialize());
    }
  </script>
  <?php
    if (!isset($merchantFilter)) $merchantFilter = "";
    if (!isset($brandFilter)) $brandFilter = "";
    if (!isset($priceWhere))
    {
      $where = " 1 ";
      $priceWhere = " AND 1 ";
    }
  $merchantFilter = (isset($_GET["merchantFilter"])?$_GET["merchantFilter"]:"");
  $brandFilter = (isset($_GET["brandFilter"])?$_GET["brandFilter"]:"");
  if ($merchantFilter)
  {
    $priceWhere .= " AND merchant = '".database_safe($merchantFilter)."' ";
  }
  if ($brandFilter)
  {
    $priceWhere .= " AND brand = '".database_safe($brandFilter)."' ";
  }
  ?>
<div id='pt_sr_body'>
  <form name='search' id='pt_sf' action='<?php print $config_baseHREF ?>search.php'>
      <input type='hidden' name='q' value='bw:' />
      <select name='merchantFilter[]' onChange='JavaScript:pt_sf_onchange();'>
        <option value=''>Merchant...</option>
        <?php
        $sql = "SELECT DISTINCT(merchant) FROM `".$config_databaseTablePrefix."products`
                  WHERE merchant <> '' AND ".$where.$priceWhere." ORDER BY merchant";
        database_querySelect($sql,$rows);
        foreach($rows as $row)
        {
          $selected =(in_array($row["merchant"],$merchantFilter)?"selected='selected'":"");
          print "<option ".$selected." value='".$row["merchant"]."'>".$row["merchant"]."</option>";
        }
        ?>
      </select>
      <select name='brandFilter[]' onChange='JavaScript:pt_sf_onchange();'>
        <option value=''>Brand...</option>
        <?php
        $sql = "SELECT DISTINCT(brand) FROM `".$config_databaseTablePrefix."products`
                  WHERE brand <> '' AND ".$where.$priceWhere." ORDER BY brand";
        database_querySelect($sql,$rows);
        foreach($rows as $row)
        {
          $selected =(in_array($row["brand"],$brandFilter)?"selected='selected'":"");
          print "<option ".$selected." value='".htmlspecialchars($row["brand"],ENT_QUOTES,$config_charset)."'>".$row["brand"]."</option>";
        }
        ?>
      </select>
      <input type='submit' class='button expand radius' value='Search' />
  </form>
</div>
<?php
  if (!isset($_GET["ajax"])) require("html/footer.php");
?>

Best,
Marco

Submitted by support on Tue, 2016-03-01 10:59

Hello Marco,

I think the trick here is to re-load the form when the user changes a drop-down so that all select boxes update with compatible values only, with only the Search button performing the actual submission to search.php. This requires a separate .php file that only serves the form body, included using require() in the first instance, and subsequently reloaded using jQuery .load().

Create the new file html/form.php:

<?php
  if (isset($_GET["ajax"])) require("../includes/common.php");
  $formMerchant = (isset($merchantFilter)?$merchantFilter:$_GET["merchantFilter"]);
  $formBrand = (isset($brandFilter)?$brandFilter:$_GET["brandFilter"]);
  $formWhere ="";
  if ($formMerchant)
  {
    $formWhere .= " AND merchant ='".database_safe($formMerchant)."' ";
  }
  if ($formBrand)
  {
    $formWhere .= " AND brand ='".database_safe($formBrand)."' ";
  }
?>
<form id='form' action='<?php print $config_baseHREF ?>search.php'>
  <input type='hidden' name='q' value='bw:' />
  <select name='merchantFilter' onChange='JavaScript:formLoad();'>
    <option value=''>Merchant...</option>
    <?php
    $sql = "SELECT DISTINCT(merchant) FROM `".$config_databaseTablePrefix."products`
              WHERE merchant <> '' ".$formWhere." ORDER BY merchant";
    database_querySelect($sql,$rows);
    foreach($rows as $row)
    {
      $selected = ($formMerchant==$row["merchant"]?"selected='selected'":"");
      print "<option ".$selected." value='".$row["merchant"]."'>".$row["merchant"]."</option>";
    }
    ?>
  </select>
  <select name='brandFilter' onChange='JavaScript:formLoad();'>
    <option value=''>Brand...</option>
    <?php
    $sql = "SELECT DISTINCT(brand) FROM `".$config_databaseTablePrefix."products`
              WHERE brand <> '' ".$formWhere." ORDER BY brand";
    database_querySelect($sql,$rows);
    foreach($rows as $row)
    {
      $selected = ($formBrand==$row["brand"]?"selected='selected'":"");
      print "<option ".$selected." value='".htmlspecialchars($row["brand"],ENT_QUOTES,$config_charset)."'>".$row["brand"]."</option>";
    }
    ?>
  </select>
  <input type='submit' value='Search' />
</form>

And then at the point you wish to display the form in your page, use:

<div id='formContainer'>
<?php require("html/form.php"); ?>
</div>
<script type='text/JavaScript'>
function formLoad()
{
  $("#formContainer").load("<?php print $config_baseHREF?>html/form.php?ajax=1&"+$("#form").serialize());
}
</script>

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by marco on Tue, 2016-03-01 19:19

Hi David,

Thank you, this works great.

Except if i try to adjust it to fit my SidebarFiltersListMulti search page.
Tried adding [] to select name and tried adding (in array) to several variables without any luck.

In the end to only change needed is the form output url being changed from:
search.php?q=bw%3A&merchantFilter=ExampleMerchant&brandFilter=ExampleBrand

into:
search.php?q=bw%3A&merchantFilter[]=ExampleMerchant&brandFilter[]=ExampleBrand

Any ideas on how to accomplish this?

Best,
Marco

Submitted by support on Wed, 2016-03-02 09:32

Hello Marco,

Having changed the select box names to array format e.g. name='merchantFilter[]' the only other change required in html/form.php is where $formMerchant and $formBrand are set, which should be changed as follows;

  $formMerchant = (isset($merchantFilter)?$merchantFilter[0]:$_GET["merchantFilter"][0]);
  $formBrand = (isset($brandFilter)?$brandFilter[0]:$_GET["brandFilter"][0]);

Cheers,
David.
--
PriceTapestry.com

Submitted by marco on Wed, 2016-03-02 11:15

Many thanks