You are here:  » Sub Navigation


Sub Navigation

Submitted by stevewales20 on Mon, 2013-07-15 17:55 in

Hi David,

I'm looking to create subnavigation similar to play.com where you can see which selections have been made. I've recently moved my search filters into a separate file like you have done with v13.

I have this so far:

  if ($subCategoryFilter) { ?>
<p class="first-header">
        You have selected:</p>
  <?php
  }

I can't think of a way to include other filters so that i can show multiple filters that have been selected, is best way to pass the url? also after clicking on for example categories, and then merchants, it basically overrides the first selection, is that normal? Is there a way to include more than one?

Thanks
Steve

Submitted by support on Tue, 2013-07-16 08:13

Hi Steve,

What you need to do is make sure that the href constructed for each link in your navigation includes the values of any other filters and the sort variables that are set, that way they will be preserved. Have a go with something like:

<?php
  $navHREF = $config_baseHREF."search.php?q=".urlencode($q);
  if ($sort!="relevance") $navHREF .= "&sort=".$sort;
  if ($minPrice) $navHREF .= "&minPrice=".$minPrice;
  if ($maxPrice) $navHREF .= "&maxPrice=".$maxPrice;
  if ($merchantFilter) $navHREF .= "&merchantFilter=".urlencode($merchantFilter);
  if ($categoryFilter) $navHREF .= "&categoryFilter=".urlencode($categoryFilter);
  if ($brandFilter) $navHREF .= "&brandFilter=".urlencode($brandFilter);
  if ($subCategoryFilter) $navHREF .= "&subCategoryFilter=".urlencode($subCategoryFilter);
  if ($subCategoryFilter)
  {
    print "<p class='first-header'>
           You have selected: <a href='".$navHREF."'>".$subCategoryFilter."</a>
           </p>";
  }
  // etc.
?>

If you wanted some inspiration for a breadcrumb trail there's a pretty comprehensive version in this post which may be of interest...

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by stevewales20 on Tue, 2013-07-16 20:36

Hey david,

That seemed to work well thank you.

{link saved}

This seems to be functioning sort of how i'd like it. I'm struggling to come up with a way to remove the selection though. Is there a way remove a part of the href? or store the variable to be removed?

Also can you suggest a better way of doing this? i did think of using a function, but i couldnt get my head around it:

if (($subCategoryFilter) || ($merchantFilter) || ($brandFilter)) { ?>
    <div class="remove-selection box rounded">
<p class="filter-header">
        You have selected</p>
<ul>
<?php if ($subCategoryFilter) { ?>
<li>
<a href="<?php echo $navHREF ?>">
<?php echo $subCategoryFilter ?>
</a>
<a class="unselect" href=">X
<span class="box">
<span>Remove Selection</span>
</span>
</a>
</li>
<?php }
if ($merchantFilter) { ?>
<li>
<a href="<?php echo $navHREF ?>">
Store: <?php echo $merchantFilter ?>
</a>
<a class="unselect" href=">X
<span class="box">
<span>Remove Selection</span>
</span>
</a>
</li>
<?php }
if ($brandFilter) { ?>
<li>
<a href="<?php echo $navHREF ?>">
Brand: <?php echo $brandFilter ?>
</a>
<a class="unselect" href=">X
<span class="box">
<span>Remove Selection</span>
</span>
</a>
</li>
<?php ?>
</ul>
</div>
<?php
  }
  ?>

or do you think that should suffice?

Thank you very much.
Steve

Submitted by stevewales20 on Tue, 2013-07-16 20:42

Also is it possible to look at this and let me know will it cause any problems?

//print "<li><a href='".$filterHREF.$merchantFilterHREF.$categoryFilterHREF.$subCategoryFilterHREF."&amp;brandFilter=".urlencode($row["brand"])."'>".$row["brand"]."</a></li>";
print "<li><a href='".$navHREF."&amp;brandFilter=".urlencode($row["brand"])."'>".$row["brand"]."</a></li>";

Basically i removed the multiple variables and it seems to work better than the previous line.

Steve

Submitted by support on Wed, 2013-07-17 07:53

Hi Steve,

Above looks fine - should amount to the same thing. Regarding creating a remove selection HREF, the tidiest way is probably with a function to return navHREF but excluding the parameter passed in the optional parameter; so in place of where you currently have:

  $navHREF = $config_baseHREF."search.php?q=".urlencode($q);
  if ($sort!="relevance") $navHREF .= "&sort=".$sort;
  if ($minPrice) $navHREF .= "&minPrice=".$minPrice;
  if ($maxPrice) $navHREF .= "&maxPrice=".$maxPrice;
  if ($merchantFilter) $navHREF .= "&merchantFilter=".urlencode($merchantFilter);
  if ($categoryFilter) $navHREF .= "&categoryFilter=".urlencode($categoryFilter);
  if ($brandFilter) $navHREF .= "&brandFilter=".urlencode($brandFilter);
  if ($subCategoryFilter) $navHREF .= "&subCategoryFilter=".urlencode($subCategoryFilter);

...have a go with:

  function navHREF($exclude="")
  {
    $parameters = array(
      "sort","minPrice","maxPrice",
      "merchantFilter","categoryFilter","brandFilter","subCategoryFilter"
      );
    $navHREF = $config_baseHREF."search.php?q=".urlencode($q);
    foreach($parameters as $parameter)
    {
      if ($parameter != $exclude)
      {
        $navHREF .= "&".$parameter."=".urlencode($GLOBALS[$parameter]);
      }
    }
  }

...and then for example, under your subCategoryFilter section:

<span><a href='<?php print navHREF("subCategoryFilter"); ?>'>Remove Selection</a></span>

...and Remove Selection will be a link to the results with subCategoryFilter removed...

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by stevewales20 on Wed, 2013-07-17 21:49

Edit*

Ah very sorry for the multiple edits. I finally got it working :)

function displayFilters($filter, $navHREF, $selected, $q, $extra="")
{
?>
<li>
<a href="<?php print navHREF($filter$q?>">
<?php echo $extra.$selected ?>
</a>
<a class="unselect" href="<?php print navHREF($filter$q?>">X
<span class="box">
<span>Remove Selection</span>
</span>
</a>
</li>
<?php
}
function navHREF($exclude="", $q)
{
$parameters = array( //Filter array
"categoryFilter","subCategoryFilter","merchantFilter","brandFilter","sort","minPrice","maxPrice"
);
$navHREF = $config_baseHREF."search.php?q=".urlencode($q);
foreach($parameters as $parameter)
{
if ($parameter != $exclude)
{
if ($GLOBALS[$parameter]) { //check if the parameter is populated
$navHREF .= "&".$parameter."=".urlencode($GLOBALS[$parameter]);
}
}
}
return $navHREF;
}
//check if filters are populated.
if (($subCategoryFilter) || ($merchantFilter) || ($brandFilter)) { ?>
    <div class="remove-selection box rounded">
<p class="filter-header">
        You have selected</p>
<ul>
<?php
if ($subCategoryFilter)
print displayFilters("subCategoryFilter", $navHREF, $subCategoryFilter, $q);
if ($merchantFilter)
print displayFilters("merchantFilter", $navHREF, $merchantFilter, $q, "Store: ");
if ($brandFilter)
print displayFilters("brandFilter", $navHREF, $brandFilter, $q, "Brand: ");
?>
</ul>
</div>
<?php
  }
  ?>

I wanted to try and tidy the code up a little and remove some of the extra repeated code. Any suggestions? The function seems to have quite a few parameters passed to it, there a more efficient way?

Thanks for your time!!

Steve

Submitted by support on Thu, 2013-07-18 07:48

Hi Steve,

Looks pretty good - I think $navHREF and $q are redundant as it stands so no need for them to be passed through the function calls, it looks like $navHREF isn't actually used, and $q can be accessed globally in the navHREF() function - something like;

function displayFilters($filter, $selected, $extra="")
{
  ?>
  <li>
  <a href="<?php print navHREF($filter?>">
  <?php echo $extra.$selected ?>
  </a>
  <a class="unselect" href="<?php print navHREF($filter?>">X
  <span class="box">
  <span>Remove Selection</span>
  </span>
  </a>
  </li>
  <?php
}
function navHREF($exclude="")
{
  $parameters = array( //Filter array
  "categoryFilter","subCategoryFilter","merchantFilter","brandFilter","sort","minPrice","maxPrice"
  );
  $navHREF = $config_baseHREF."search.php?q=".urlencode($GLOBALS["q"]);
  foreach($parameters as $parameter)
  {
    if ($parameter != $exclude)
    {
      if ($GLOBALS[$parameter]) { //check if the parameter is populated
        $navHREF .= "&".$parameter."=".urlencode($GLOBALS[$parameter]);
      }
    }
  }
  return $navHREF;
}
//check if filters are populated.
if (($subCategoryFilter) || ($merchantFilter) || ($brandFilter)) { ?>
    <div class="remove-selection box rounded">
<p class="filter-header">
        You have selected</p>
<ul>
<?php
if ($subCategoryFilter)
  print displayFilters("subCategoryFilter", $subCategoryFilter);
if ($merchantFilter)
  print displayFilters("merchantFilter", $merchantFilter, "Store: ");
if ($brandFilter)
  print displayFilters("brandFilter", $brandFilter, "Brand: ");
?>
</ul>
</div>
<?php
}
?>

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by stevewales20 on Thu, 2013-07-18 09:29

Ah cheers David.

The problem I had with q was it wasn't being populated using $GLOBALS. Not sure why though. I'll try again later. Thanks for the pointers.

Thanks!
Steve

Submitted by stevewales20 on Sat, 2013-07-20 18:20

Hi David,

Me again :)

    $h2 = $q; // this is what was originally displayed
    $h2 = str_replace("merchant:","",$h2);
    $h2 = str_replace("category:","",$h2);
    $h2 = str_replace("brand:","",$h2);
    $h2 = str_replace("bw:","",$h2);
    $q = str_replace(":","",$h2);

Having some issues using the search.php filtering. I'm trying to use 'merchant:' and use it to filter the side navigation. As you see from above I installed that many moons ago to filter the $h2 variable. This is causing issues with other parts of the script.

I'm not trying to use the code below to display the merchant logo instead of the you selected box. Is there a way i can overcome this whilst still keeping away the extra stuff.

Also whilst i'm on here. How can I sanitise the logo input? Currently it's relying on user input which is not safe. Is there some variable I can use to call it?

 if ($q == strstr($q,'merchant:')) { ?>
<div class="remove-selection box rounded">
<h5><?php print $merchantFilter;?></h5>
<ul>
<?php
if (file_exists("logos/".$merchantFilter))
{
$logo = $config_baseHREF."logos/".$merchantFilter;?>
<a href='<?php print $config_baseHREF."search.php?q=merchant:".urlencode($merchantFilter)."&merchantFilter=".urlencode($merchantFilter); ?>'><img class="photo" width="90" height="90" src='<?php print $logo?>' alt='<?php print $merchantFilter ?>' /><a/>
<?php }
?>
</ul>
</div>
 <?php } else {
if (($subCategoryFilter) || ($merchantFilter) || ($brandFilter)) { ?>
<div class="remove-selection box rounded">
<h5><?php print $categoryFilter;?></h5>
<p class="filter-header">
You have selected</p>
<ul>
<?php
if ($subCategoryFilter)
print displayFilters("subCategoryFilter", $subCategoryFilter, $q);
if ($merchantFilter)
print displayFilters("merchantFilter", $merchantFilter, $q, "Store: ");
if ($brandFilter)
print displayFilters("brandFilter", $brandFilter, $q, "Brand: ");
?>
</ul>
</div>
<?php
}
 }

Thanks again. Its very much appreciated.

Steve

Submitted by support on Sun, 2013-07-21 09:21

Hi Steve,

In place of:

if ($q == strstr($q,'merchant:'))

...you can detect a merchant index search by inspecting $parts[0] instead; e.g.

if ($parts[0]=="merchant")

And then in the remainder of your code, in place of $merchantFilter use $parts[1]

That should be all it is!

Cheers,
David.
--
PriceTapestry.com

Submitted by stevewales20 on Sun, 2013-07-21 13:17

Thanks david your a star, just using parts[1] and im getting a load of extra fluff, empty space? which means i cant use it to call the logo.

$merchantName = tapestry_search($parts[1]);
if ($parts[0]=="merchant") { ?>
<div class="remove-selection box rounded">
<?php print $merchantName;
$merchantFilterURL = (isset($merchantFilter)?"&amp;merchantFilter=".urlencode($merchantFilter):"");
?>
<?php
if (file_exists("logos/".$merchantName))
{
$logo = $config_baseHREF."logos/".$merchantName;
?>
<a href='<?php print $config_baseHREF."search.php?q=merchant:".urlencode($parts[1])."".$merchantFilterURL ?>'>
<img src='<?php print $logo?>' alt='<?php print $merchantName?>' /><a/>
<?php ?>
</div>

tried using tapestry_search to remove it, but nothing is happening.
{link saved}

Cheers
Steve

Submitted by support on Mon, 2013-07-22 08:18

Hi Steve,

I think there's a conflict going on between a merchant index search (q=merchant:Merchant Name) and merchantFilter - the two should never appear in the same query - since for a merchant:Merhant Name search there is only ever going to be one merchant in the result set;

However visually working through your code, it looks like it would only be executed if $parts[0] is "merchant", in which case, $parts[1] should only contain a valid merchant name at this point...

I just asked in your other question regarding undefined indexes if you could forward a couple of files for me to check for you - if you would also like to attach the file containing the above code that will help as I'll be able to check it out in context for you.

Just on a general PHP note, when combining PHP conditionals and HTML code, the alternative syntax is often easier to use; for example, instead of:

<?php if ($foo=="bar") { ?>
<span>It's Bar!</span>
<?php ?>

...you can use:

<?php if ($foo=="bar"): ?>
  <span>It's Bar!</span>
<?php endif; ?>

...more on those at:

http://php.net/manual/en/control-structures.alternative-syntax.php

Cheers,
David.
--
PriceTapestry.com