You are here:  » Separate drop-down menus per top level category


Separate drop-down menus per top level category

Submitted by support on Wed, 2016-02-24 12:48 in

Hi everyone,

I've been asked a couple of times recently about creating separate drop-down menus for a top level category in the Category Hierarchy (or any sub-category for that matter), so for example on the demo site, instead of a single Category drop down, there could instead be separate menus for "Domestic Appliances" and "Home Entertainment".

To implement this, first edit html/menu_categories.php and look for the following code at line 4:

  $parent = (isset($_GET["parent"])?intval($_GET["parent"]):0);

...and REPLACE with:

  $parent = (isset($_GET["parent"])?intval($_GET["parent"]):0);
  $prefix = tapestry_normalise($_GET["prefix"]);

And then the following code at line 17:

print "<li class='has-dropdown' onClick='JavaScript:menu_loadCat(".$category["id"].");'>";

...and REPLACE with:

print "<li class='has-dropdown' onClick='JavaScript:menu_loadCat(\"".$prefix."\",".$category["id"].");'>";

And finally the following code at line 21:

print "<ul id='menu_cat".$category["id"]."' class='dropdown'>";

...and REPLACE with:

print "<ul id='".$prefix."_cat".$category["id"]."' class='dropdown'>";

Then in html/menu.php, look for the following code beginning at line 55:

  function menu_loadCat(id)
  {
    if (menu_loadCatDone[id]) return;
    $("#menu_cat"+id).load("<?php print $config_baseHREF?>html/menu_categories.php?parent="+id, function() {});
    menu_loadCatDone[id] = true;
  }

...and REPLACE with:

  function menu_loadCat(prefix,id)
  {
    if (menu_loadCatDone[prefix+id]) return;
    $("#"+prefix+"_cat"+id).load("<?php print $config_baseHREF?>html/menu_categories.php?parent="+id+"&prefix="+prefix, function() {});
    menu_loadCatDone[prefix+id] = true;
  }

With that in place, locate the existing full hierarchy "Category" drop-down menu HTML, which begins at line 23:

        <li class='has-dropdown show-for-medium-up' onClick='JavaScript:menu_loadCat(0);'>
          <a href='#'><?php print translate("Category"); ?></a><ul id='menu_cat0' class='dropdown'><li><a href='#'>&nbsp;<div class="preloader"></div></a></li></ul>
        </li>

If the full hierarchy menu is still required, REPLACE with:

        <li class='has-dropdown show-for-medium-up' onClick='JavaScript:menu_loadCat("menu",0);'>
          <a href='#'><?php print translate("Category"); ?></a><ul id='menu_cat0' class='dropdown'><li><a href='#'>&nbsp;<div class="preloader"></div></a></li></ul>
        </li>

Now to create a new drop down for a sub-category, first you need to know the id value for the category for which you wish to create a menu. To obtain this, login in to /admin/ and go to Category Hierarchy Mapping and click Configure alongside the category name for which you wish to create a menu. The id can then be seen in the URL, e.g.

http://www.webpricecheck.co.uk/admin/categories_hierarchy_configure.php?id=6

So to create a menu for category id 6 with label "Home Entertainment", add the following list item to the menu area as required;

        <li class='has-dropdown show-for-medium-up' onClick='JavaScript:menu_loadCat("menu6",6);'>
          <a href='#'>Home Entertainment</a><ul id='menu6_cat6' class='dropdown'><li><a href='#'>&nbsp;<div class="preloader"></div></a></li></ul>
        </li>

(replace each instance of "6" in the above with the id of the category)

Hope this helps!
Cheers,
David
--
PriceTapestry.com

Submitted by support on Wed, 2016-02-24 12:58

The following code will create a separate drop-down menu for each top level category:

<?php
$sql 
"SELECT id,name FROM `".$config_databaseTablePrefix."categories_hierarchy` WHERE parent='0' ORDER BY name";
database_querySelect($sql,$rows);
foreach(
$rows as $row)
{
  print 
"<li class='has-dropdown show-for-medium-up' onClick='JavaScript:menu_loadCat(\"menu".$row["id"]."\",".$row["id"].");'>";
  print 
"<a href='#'>".$row["name"]."</a><ul id='menu".$row["id"]."_cat".$row["id"]."' class='dropdown'><li><a href='#'>&nbsp;<div class=\"preloader\"></div></a></li></ul>";
  print 
"</li>";
}
?>

Cheers,
David.
--
PriceTapestry.com

Submitted by ItsDavid on Sun, 2018-03-25 12:55

Hi David,

I am working on my own new design and kind of hit a stumbling block with the navigation categories and was wondering if you could assist.

I am trying to remove the JavaScript onClick and actually switch to CSS onClick however, anytime I remove the onClick= I cannot get categories to display But this is what I would like to do.

Currently, when you click "Category" in the Nav it populates with the main Parent Categories and you have to click the parent category to get to the sub-categories.

How can I have the Sub-Categories automatically populate under its parent without the need to depend on a JavaScript Click or any click at all?

Best Regards,
David

Submitted by support on Mon, 2018-03-26 08:59

Hi David,

There's an option for conversion to the hover functionality of the Foundation menu bar in this comment...

Cheers,
David.
--
PriceTapestry.com

Submitted by ItsDavid on Mon, 2018-03-26 14:43

Hi David,

As always thank you for the super fast reply.

I ended up finding that after my post, however, that didn't get me where I thought it would.

One problem I am having is that when I add my menus I end up with this type of structure,

CLOTHING <---- Clickable Link
--> MENS <---- Clickable Link
----> Accessories <---- Clickable Link
----> Activewear <---- Clickable Link
--> WOMEN <---- Clickable Link
----> Accessories <---- Clickable Link
----> Activewear <---- Clickable Link
--> CHILDREN <---- Clickable Link
----> Accessories <---- Clickable Link
----> Activewear <---- Clickable Link
ELECTRONICS <---- Clickable Link
--> TVs <--- Clickable Link
----> HD TVs <---- Clickable Link
----> 4K Ultra TVs <---- Clickable Link
----> UHD TVs <---- Clickable Link
--> PERIPHERALS <--- Clickable Link
----> Home Theatre Systems <---- Clickable Link
----> Speakers <---- Clickable Link

Now I am up against 2 challenges with this example above.

1. The menu keeps getting longer and longer eventually going past to bottom of the page and I have not found a way to make it wrap to a new column after x-number of parent category items and x-number of child category items.

2. Every link in the menu is clickable I need to be able to add placeholders for my menus such as the following example below.

CLOTHING <--- <strong>Placeholder Text For Drop Down In Top Level Navigation</strong>
--> MENS <--- <strong>Placeholder Text in Dropdown Menu</strong>
----> Accessories <---- Clickable Link
----> Activewear <---- Clickable Link
--> WOMEN <--- <strong>Placeholder Text in Dropdown Menu</strong>
----> Accessories <---- Clickable Link
----> Activewear <---- Clickable Link
======> <strong>BREAK TO A NEW COLUMN IF I WANT</strong>
--> CHILDREN <---- <strong>Placeholder Text in Dropdown Menu</strong>
----> Accessories <---- Clickable Link
----> Activewear <---- Clickable Link
ELECTRONICS <--- <strong>Placeholder Text For Drop Down In Top Level Navigation</strong>
--> TVs <--- <strong>Placeholder Text in Dropdown Menu</strong>
----> HD TVs <---- Clickable Link
----> 4K Ultra TVs <---- Clickable Link
----> UHD TVs <---- Clickable Link
--> PERIPHERALS <--- <strong>Placeholder Text in Dropdown Menu</strong>
----> Home Theatre Systems <---- Clickable Link
----> Speakers <---- Clickable Link
------> <strong>BREAK TO A NEW COLUMN IF I WANT</strong>

Hopefully, that provides a better understanding of the menu structure I am looking to achieve.

I am perfectly ok if I need to manually create a new file for each top-level category to be placed in the main navigation than do a file include "Clothing.php" include "Electronics.php" etc, if that's what it takes.

Is there any easy way for me to have a menu navigation structure like this?

The easier the better, however, as I mentioned above, if creating a new file for each top-level navigation item inside maybe a directory "html/menus/clothing.php" "html/menus/electronics.php" is what it takes I am all for it.

One final note. I noticed that any category name that I add "&" "-" to gets removed. Is it possible to allow this only in the name but not the URL?

Best Regards,
David

Submitted by support on Mon, 2018-03-26 17:09

Hi,

In this case - yes it would be much easier to hard code the menus to create the combination of labels (non-clickable) and sub-category menus per top level menu that you require...

As an example based on the Electronics hierarchy that you posted, with the Peripherals/Speakers drop-down excted with a couple of sub-categories...

        <li class="has-dropdown">
          <a href="#">Electronics</a>
          <ul class="dropdown">
            <li><label>TVs</label></li>
            <li><a href='/category/Electronics/TVs/HD-TVs/'>HD TVs</a></li>
            <li><a href='/category/Electronics/TVs/4K-Ultra-TVs/'>4K Ultra TVs</a></li>
            <li><a href='/category/Electronics/TVs/UHD-TVs/'>UHD TVs</a></li>
            <li><label>Peripherals</label></li>
            <li><a href='/category/Electronics/Peripherals/Home-Theatre-Systems/'>Home Theatre Systems</a></li>
            <li class='has-dropdown'>
                <a>Speakers</a>
                <ul class="dropdown">
                  <li><a href='/category/Electronics/Peripherals/Speakers/Freestanding/'>Freestanding</a></li>
                  <li><a href='/category/Electronics/Peripherals/Speakers/Surround/'>Surround</a></li>
                </ul>
            </li>
          </ul>
        </li>

Insert the above code into html/menu.php inside <ul class='left'> or as required...

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by sirmanu on Mon, 2019-07-29 06:38

Hi David.
It would be possible to load all the tree hierarchy without Javascript? Just for SEO purposes.
Thank you

Submitted by support on Mon, 2019-07-29 09:08

Hi,

Sure - here is the standalone code to load the entire Category Hierarchy and render using blockquote indentation - let me know if you're not sure how to incorporate at the location you want to display the index...

<?php
  
function getCategoryPath($id)
  {
    global 
$config_databaseTablePrefix;
    
$categories = array();
    do {
      
$sql "SELECT name,parent FROM `".$config_databaseTablePrefix."categories_hierarchy` WHERE id = '".$id."'";
      
database_querySelect($sql,$rows);
      
array_unshift($categories,$rows[0]["name"]);
    } while(
$id $rows[0]["parent"]);
    return 
implode("/",$categories);
  }
  function 
getCategoryPaths()
  {
    global 
$config_databaseTablePrefix;
    global 
$categoryPath;
    
$sql "SELECT id FROM `".$config_databaseTablePrefix."categories_hierarchy` ORDER BY id";
    
database_querySelect($sql,$rows);
    foreach(
$rows as $row)
    {
      
$categoryPath[$row["id"]] = getCategoryPath($row["id"]);
    }
  }
  function 
node($node)
  {
    global 
$config_databaseTablePrefix;
    global 
$categoryPath;
    global 
$depth;
    global 
$counts;
    
$depth++;
    
$counts[$depth]--;
    print 
"<blockquote>";
    print 
"<a href='".tapestry_indexHREF("category",$categoryPath[$node["id"]])."'>".$node["name"]."</a>";
    
$sql "SELECT id,name FROM `".$config_databaseTablePrefix."categories_hierarchy` WHERE parent='".$node["id"]."' ORDER BY name";
    if (
$counts[($depth+1)] = database_querySelect($sql,$nodes))
    {
      foreach(
$nodes as $node)
      {
        
node($node);
      }
    }
    print 
"</blockquote>";
  }
  
getCategoryPaths();
  
$depth 0;
  
$counts = array();
  
$sql "SELECT id,name FROM `".$config_databaseTablePrefix."categories_hierarchy` WHERE parent='0' ORDER BY name";
  if (
$counts[($depth+1)] = database_querySelect($sql,$nodes))
  {
    foreach(
$nodes as $node)
    {
      
node($node);
    }
  }
?>

Cheers,
David.
--
PriceTapestry.com

Submitted by sirmanu on Mon, 2019-07-29 11:25

Thank you David, this code is very useful and great for a starting point.
It would require a bit of code to properly integrate it on my installation. I will post any problem I have.
PS: thank you for your awesome fast reply.

Submitted by support on Fri, 2019-08-02 10:12

Hi,

Can you re-post the array tree that you were looking to create I accidentally deleted the post when making a couple of changes to other threads - sorry about that! I recall it wasn't in JSON or other standard format, if your rendering process can accept JSON that should be straight forward to generate from the category hierarchy tree...

Thanks,
David.
--
PriceTapestry.com

Submitted by sirmanu on Thu, 2019-08-08 14:46

Hi! No problem David.
A bit of stack overflow solved my problems!

Thank you!