Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

[Contribution] Category Box as Nested Unordered List v1.0


nate_02631

Recommended Posts

WHAT IS IT?

This contribution is an alternate category box which will output your store's categories as a proper nested unordered list, instead of a collection of non-breaking spaces, quasi-bullets and break tags.

 

What's the big deal about that you ask? With the categories now output as an unordered list, you can now more easily apply a lot of nifty CSS to turn your category list into a horizontal drop-down or vertical fly-out menu, make it a collapsible menu, easily attach bullets, add cool mouseover effects, or just about anything you can dream up!

 

The advantage of this technique over pure javascript solutions is that it is much more flexible, easier to apply CSS trickery to, is more search-engine friendly and makes just one query to the database.

 

Output includes optional CSS class tags to mark categories as selected or as parent cats. You can also choose to render all of your categories (useful for dynamic menus) or to render only the root cats and the selected category tree. Note that this contribution merely provides a foundation for you to construct a more attractive/functional menu by providing a more semantically-correct output. A little CSS-magic is required on your end, though I have included a sample vertical flyout menu CSS. I have included some resources in the readme.

 

The download is available in the Contributions: http://www.oscommerce.com/community/contributions,4201

 

Any feedback, bug reports are welcome, or if you just want to post some cool unordered list menu resources or show off what you've done below...

Edited by Johnson

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

  • Replies 98
  • Created
  • Last Reply

Top Posters In This Topic

Thanks for this great contribution, this is exactly what I want! The other dynamic category enhancement I have run into I never got right...

I have had a look at Suckerfish and this contributions looks very promising!

If I have gotten the instructions right, doing a clean "to-start-with" install of this contribution is just a matter of putting ul_categories.php in the boxes directory and adding the example css to the stylesheet.

I run into trouble though, because the menu only shows the first four main categories and no sub levels fly out...

Running it without stylesheet renders an unorderd list (as promised) with the four first main categories and all their sub levels.

Hmm.

Have I missed something?

Link to comment
Share on other sites

Here's more...

I have 22 main categories in total and three levels at maximum...

 

Firefox:

The webpage in Swedish shows the first four main categories and all four fly-out!

The webpage in English shows the first three main categories and all three fly-out!

 

IE:

The webpage in Swedish shows the first four main categories and none of them fly-out!

The webpage in English shows the first three main categories and none of them fly-out!

 

We have to fix this to be able to use this contrib, of course...I'm not sure how.

Link to comment
Share on other sites

Hi,

 

Yes, with the contrib I included the CSS from the "suckerfish" menus, it also makes use of some Javascript, which I did not include as part of the distribution. This JS I believe is to make browsers work that don't recognize the "hover" state for elements other than <A> anchor tags (such as older versions of Explorer). I am using a suckerfish style menu with the JS and am having no Explorer problems. See the son of suckerfish for details...

 

Also, when you are doing CSS based styles, you need to allow for the # of submenus you intend to have. I think the included example only allows for two sublevels...

 

The included CSS is not meant to be a starting point, but rather just an illustration of what's possible. There's plenty of people smarter than me doing stuff with CSS and lists (some resource links included in readme)...

 

Interesting point about the different languages... I did use the lang in the query - pretty sure it's being sucked in correctly... Will check it again...

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

This contrib seems to be what I am looking for... I was wondering if you could direct me to a working live example, I would like to see this in action before I install it on my store.

 

Thank you

James Tomasello

Link to comment
Share on other sites

Hi - nothing to see really ;). It simply outputs your category tree (either the whole thing or just the roots and selected subcat tree, as the default osc cat box) as a bulleted list (with subbullets for categories).

 

The sample CSS supplied makes it resemble a fly-out menu (which of course you've seen), but the idea is that it generates a bullet list *framework* where you can more easily use CSS to style as desired...

 

I am in the process of redoing my dad's photography site and wanted to include a category dropdown embedded in the header, which I why I came up with this little contrib. I plan to use the technique described in "Suckerfish dropdowns" - which uses CSS and just a *teeny* bit of javascript to bring older MSIE's in line... but that is not completely represented in the included sample CSS...

 

I've included some resources for styling list-menus, but you can do a ton with them, like having expandable/collapsable menus, fly-out/drop-down menus, menus with mouseover effects, or whatever else you can dream up! Heck, the drop-downs at the top of this forum are just a gussied-up unordered list (with maybe a little JS thrown in!)...

 

Give it a try! The one script file in the package will not override any other so it won't mess up your site! (goes in includes/boxes)

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

Hi!

I still have the problem I posted earlier... I believe it's something that has to be fixed in ul_categories.php.

Here's what happens if I set the "show_full_tree" to "true":

The menu has 3 or 4 top level categories, depending on language. In the last top level categoriy there is a tangled up version of the rest of the categories. It seems like the script does not find it's way back to the "root". The UL-list drifts deeper into new levels.

(Without CSS, this contribution makes a very nice site map by the way...)

Setting the "show_full_tree" to "false" renders all 22 top level categories perfectly!

But that's what you get with the standard menu... Since I have 840 products in 22 top level categories with sometimes as much as 4(or 5?) sub levels, rendering the full tree with all the fly-outs will give customers a fair chance to get an overview of the products...

Link to comment
Share on other sites

Between lines 122-130 there's this piece of code:

if ($GLOBALS['this_level'] != $level) {

			if ($GLOBALS['this_level'] < $level)
					$output .= "\n".'<ul>';
				else
					$output .= '</ul></li>'."\n";		

			$GLOBALS['this_level'] = $level;
	}

I believe that there has to be some code here checking if were back att root level or not... and if were not keep on </ul>'ing until we are... Anybody knows how to fix that?

Link to comment
Share on other sites

Between lines 122-130 there's this piece of code:

if ($GLOBALS['this_level'] != $level) {

			if ($GLOBALS['this_level'] < $level)
					$output .= "\n".'<ul>';
				else
					$output .= '</ul></li>'."\n";		

			$GLOBALS['this_level'] = $level;
	}

I believe that there has to be some code here checking if were back att root level or not... and if were not keep on </ul>'ing until we are... Anybody knows how to fix that?

 

 

Hello from Germany. Try this. For me it works fine now (normal Osc-looking). Thanks at the coder of this contribution.

 

 

<?php
/*
 $Id: ul_categories.php,v 1.00 2006/04/30 01:13:58 nate_02631 Exp $

Outputs the store category list as a proper unordered list, opening up
possibilities to use CSS to style as drop-down/flyout, collapsable or 
other menu types.

 osCommerce, Open Source E-Commerce Solutions
 http://www.oscommerce.com

 Copyright (c) 2006 Nate Welch http://www.natewelch.com

 Released under the GNU General Public License
*/

// BEGIN Configuration options

 // Set to false to display the unordered list only. Set to true to display in
// a regular box. The former is useful for better integrating the menu with your layout.
$show_ulcats_as_box = true;

// Indicates whether or not to render your entire category list or just the root categories
// and the currently selected submenu tree. Rendering the full list is useful for dynamic menu
// generation where you want the user to have instant access to all categories. The other option
// is the default oSC behaviour, when the subcats aren't available until the parent is clicked. 
$show_full_tree = true;	

// This is the CSS *ID* you want to assign to the UL (unordered list) containing
// your category menu. Used in conjuction with the CSS list you create for the menu.
// This value cannot be blank.
$idname_for_menu = 'nav';

// This is the *CLASSNAME* you want to tag a LI to indicate the selected category.
// The currently selected category (and its parents, if any) will be tagged with
// this class. Modify your stylesheet as appropriate. Leave blank or set to false to not assign a class. 
$classname_for_selected = 'selected';

// This is the *CLASSNAME* you want to tag a LI to indicate a category has subcategores.
// Modify your stylesheet to draw an indicator to show the users that subcategories are
// available. Leave blank or set to false to not assign a class. 	
$classname_for_parent = 'daddy';

// END Configuration options

// Global Variables
$GLOBALS['this_level'] = 0;

// Initialize HTML and info_box class if displaying inside a box
if ($show_ulcats_as_box) {
echo '<tr><td>';
$info_box_contents = array();
$info_box_contents[] = array('text' => BOX_HEADING_CATEGORIES);
new infoBoxHeading($info_box_contents, true, false);					
}

// Generate a bulleted list (uses configuration options above)
$categories_string = tep_make_cat_ullist();

// Output list inside a box if specified, otherwise just output unordered list
if ($show_ulcats_as_box) {
$info_box_contents = array();
$info_box_contents[] = array('text' => $categories_string);
new infoBox($info_box_contents);
	echo '</td></tr>';	
} else {
echo $categories_string;	
}


// Create the root unordered list
function tep_make_cat_ullist($rootcatid = 0, $maxlevel = 0){

global $idname_for_menu, $cPath_array, $show_full_tree, $languages_id;

// Modify category query if not fetching all categories (limit to root cats and selected subcat tree)
	if (!$show_full_tree) {
	$parent_query	= 'AND (c.parent_id = "0"';	

			if (isset($cPath_array)) {

				$cPath_array_temp = $cPath_array;

				foreach($cPath_array_temp AS $key => $value) {
						$parent_query	.= ' OR c.parent_id = "'.$value.'"';
					}

					unset($cPath_array_temp);
			}	

	$parent_query .= ')';				
	} else {
	$parent_query	= '';	
	}

	$result = tep_db_query('select c.categories_id, cd.categories_name, c.parent_id from ' . TABLE_CATEGORIES . ' c, ' . TABLE_CATEGORIES_DESCRIPTION . ' cd where c.categories_id = cd.categories_id and cd.language_id="' . (int)$languages_id .'" '.$parent_query.' order by sort_order, cd.categories_name');

	while ($row = tep_db_fetch_array($result)) {				
	$table[$row['parent_id']][$row['categories_id']] = $row['categories_name'];
}

$output .= '<ul id="'.$idname_for_menu.'">';
$output .= tep_make_cat_ulbranch($rootcatid, $table, 0, $maxlevel);

	// Close off nested lists
for ($nest = 0; $nest <= $GLOBALS['this_level']; $nest++) {
	$output .= '</ul>';		
	}

return $output;
}

// Create the branches of the unordered list
function tep_make_cat_ulbranch($parcat, $table, $level, $maxlevel) {

global $cPath_array, $classname_for_selected, $classname_for_parent;

$list = $table[$parcat];

while(list($key,$val) = each($list)){

	if ($GLOBALS['this_level'] != $level) {

					// BoF changed by asmus
			if ($GLOBALS['this_level'] < $level)
					$output .= "\n".'<li><ul>';
				else
					$output .= '</ul></li>'."\n";		
					// EoF changed by asmus		
			$GLOBALS['this_level'] = $level;
	}

	if (isset($cPath_array) && in_array($key, $cPath_array) && $classname_for_selected) {
		$this_cat_class = ' class="'.$classname_for_selected.'"';
	} else {
		$this_cat_class = '';		
		}	

	$output .= '<li'.$this_cat_class.'><a href="';

	if (!$level) {
				unset($GLOBALS['cPath_set']);
					$GLOBALS['cPath_set'][0] = $key;
		$cPath_new = 'cPath=' . $key;

	} else {
					$GLOBALS['cPath_set'][$level] = $key;		
		$cPath_new = 'cPath=' . implode("_", array_slice($GLOBALS['cPath_set'], 0, ($level+1)));
	}

	if (tep_has_category_subcategories($key) && $classname_for_parent) {
		$this_parent_class = ' class="'.$classname_for_parent.'"';
	} else {
		$this_parent_class = '';		
		}				

	$output .= tep_href_link(FILENAME_DEFAULT, $cPath_new) . '"'.$this_parent_class.'>'.$val;		

	if (SHOW_COUNTS == 'true') {
		$products_in_category = tep_count_products_in_category($key);
		if ($products_in_category > 0) {
			$output .= ' (' . $products_in_category . ')';
		}
	}

	// BoF changed by asmus		
	$output .= '</a></li>."\n"';	

	if (!tep_has_category_subcategories($key)) {
		$output .= '';	
	}						 
	// EoF changed by asmus									

	if ((isset($table[$key])) AND (($maxlevel > $level + 1) OR ($maxlevel == '0'))) {
		$output .= tep_make_cat_ulbranch($key,$table,$level + 1,$maxlevel);
	}

	} // End while loop

return $output;
}	

?>

Link to comment
Share on other sites

The code does not recognize category depth properly on my store. The last post was no help to me, and actually contains two bugs. I don't know how you got it to work perfectly for you...

 

The original code sees the first category and lists everything under that category properly. Then the next top level category get listed under the deepest category from the first list and continues to "step in" very far for each additional top level category. Does this make sense? What is happening?

James Tomasello

Link to comment
Share on other sites

Don't suppose you have an example to look at? I can do some further testing, but it seemed to work O.K. with the different menus I tried...

 

Does the category tree render as expected without CSS? (proper nesting, etc...)

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

SPEAKING OF EXAMPLES...

 

Take a look at http://www.seelily.com/fec/ - which has the default CSS applied... I directed him to add the simple JS on this page:

 

http://www.htmldog.com/articles/suckerfish/

 

(specifically for the "Suckerfish" technique whose CSS is included in the package) which gets some versions of MSIE to recognize the :hover event for other elements other than anchor tags...

 

EidionNight, if you can get back to me with answers on previous post, and/or provide me with an .sql dump of your categories & categories_description tables, I would be happy to test it out on my test setup...

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

Looks like we cross-posted, EidolonNight ;)

 

That is quite a list! Do you think your could PM me the HTML of that unordered list and I can see what's going on - and/or the sql dump would be helpful... Looks like is missing *one* </UL> to close off, although I don't know if the language thing is possibly interfering?

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

I've got the problem solved the caveman way.

Paste this over the stuff at line 120 and on...

while(list($key,$val) = each($list)){

	if ($GLOBALS['this_level'] != $level) {

			if ($GLOBALS['this_level'] < $level)
					$output .= "\n".'<ul>';
			elseif ($GLOBALS['this_level'] -1 == $level)
					$output .= '</ul></li>'."\n";		
			elseif ($GLOBALS['this_level'] -2 == $level)
					$output .= '</ul></li></ul></li>'."\n";	
			elseif ($GLOBALS['this_level'] -3 == $level)
					$output .= '</ul></li></ul></li></ul></li>'."\n";	
			elseif ($GLOBALS['this_level'] -4 == $level)
					$output .= '</ul></li></ul></li></ul></li></ul></li>'."\n";					

			$GLOBALS['this_level'] = $level;
	}

This takes care of the depth in my categories...

Link to comment
Share on other sites

Me cavemen - me code HTML ;)

 

Thanks for the post Micke, it reflects just what I suspected the problem was after EidolonNight sent me his HTML...

 

The top categories of his list (Baseball, Football, Basketball Hockey) goes down to four levels but only steps back one (to level three) when it should go back *two* to level two... This is causing the progressive nesting effect seen in these categories.

 

The latter half of the list (NASCAR, Golf Tennis) renders correctly (albiet at the wrong level) because it doesn't jump levels like that.

 

Awful sorry as I thought I accounted for this in the package. Micke's "brute force" approach should work, though I'll see if I can come up with something less "barbaric" ;-) and I'll add it to the package in the contribs section - maybe I'll include another CSS example or two, and include the JS for the suckerfish technique while I'm at it...

 

Will post back here when I've added it...

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

A version 1.1 update has been uploaded to the contributions which should fix the aforementioned glitch (regardless of # of levels) and also adds a couple extra config options to render optional HTML before and after the menu (if not rendering in a box). Thought it could be useful in certain situations to better jibe with layouts, if needed.

 

I have included updated vertical fly-out and horiz drop downs based on the Suckerfish menus as well their JS which brings MSIE in line. The examples are somewhat lame and just included to give you an idea of what's possible. I encourage readers of this thread to post more interesting examples/resources below...

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

ok i got a question... ok questions haha

what can i change in the code if i dont want the categories to expand at all. i might want to just have the parent categories diplay, even if it has sub cats i dont want that part of the menu..

 

and if i decide against that i have another question..

i changed this code area and inserted my own code to ditch the lame categories textand the little half circle thing at the top and put my graphic. this is where i put it

// Initialize HTML and info_box class if displaying inside a box
if ($show_ulcats_as_box) {
echo '<tr><td>';
$info_box_contents = array();
  echo  '' . tep_image(DIR_WS_IMAGES . 'shopnav.gif', 'Categories') . '';				
}

// Generate a bulleted list (uses configuration options above)

its the echo line.

but theres is a gap between this image and the first parent category and i want it to be seamless like a <br> tag.

also i dont want my parent category names to have the offset spacing before it, and i dont want the children to be offset either. cause it doesnt go with my layout. im sure youll understand when you lok at my page..

http://www.enveamerica.com

 

and im in the middle of the facelift so dont mind the mess :P

Link to comment
Share on other sites

oops sorry it was my bad.. i had padding in my css. haha awesome.. got it.. 1 question now is there a quick way to disable the category from expanding the children cats?

Link to comment
Share on other sites

1 question now is there a quick way to disable the category from expanding the children cats?

It's an unusual request ;) but you could comment out the if/else statement block dealing with if (isset($cPath_array)) so that the query just fetches categories who don't have a parent. Set the config in the file also so it doesn't render the whole tree.

 

As for spacing above the list, if you have the latest version (which you should as it includes a minor bugfix), you can opt not to render the category list in a typical box and assign and HTML before and after the list that fits yur needs.

 

P.S. I am *not* getting topic notifications on this thread even though I'm subscribed - whasupwitdat?

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

EDIT TO ABOVE:

Actually you want to comment out (or delete) just this:

if (isset($cPath_array)) {

$cPath_array_temp = $cPath_array;

foreach($cPath_array_temp AS $key => $value) {
	$parent_query .= ' OR c.parent_id = "'.$value.'"';
}

unset($cPath_array_temp);
}

...and that should make it so only root categories are rendered in all cases...

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

cool thanks..

you can see why i might want to disable the menu from expanding if you look at my site now.

is there anyway to apply a seperate css class to the children categories that are expanded, because if they have the same css as the rest of my menu its hard to actually see what was expanded. it looked like you have this functionality but when i try to apply a diff class it doesnt seem to work.

 

also how can i get the same effect to my information.php file.

i have like 5 menu choices in there i want to have the same css class as the category menu so the buttons are the same format.

 

you can see my page here

http://www.enveamerica.com

 

ps. thx for the contrib!

Link to comment
Share on other sites

is there anyway to apply a seperate css class to the children categories that are expanded

Yes, there is, though it's a bit beyond the scope of the contribution (and this thread)... Check the included CSS for hints... #nav LI, is the first level #nav UL LI, the second, and so on... More info likely available on the Internets...

** Please do not PM with personal support requests (even if offering "payment"). Thank you.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...