jimmyoneshot Posted December 5, 2010 Share Posted December 5, 2010 I need to implement a dynamic 3 tier navigation system using php. I have a mysql table containing the following data:- http://i223.photobucket.com/albums/dd147/jimmyoneshot/categoriestable.jpg And I'm inches away from getting it working. Basically when the user clicks the top level categories (Cat1A, Cat1B etc) the second level categories (Cat2A, Cat2B etc) within each should show beneath them and in turn when the user clicks these second level categories the third level ones (Cat3A, Cat3B etc) should show beneath those. I've done this to an extent using a 'child_of' property and do while loops and some if statements but the problem seems to be when I click a category that doesn't have any categories as it's children such as Cat1D and Cat2B a bullet point is still showing beneath those which it shouldn't. Here's a link to how I have it working at the moment to show this:- http://www.coolvisiontest.com/garyssite/rhrvouchers/voucherspage.php And here's my code. Can anyoone please tell me what I'm doing wrong:- <?php require_once('connectionfile.php'); mysql_select_db($database, $myconnection); $categories2_child_of = "0"; if (isset($_GET['child_of2'])) { $categories2_child_of = $_GET['child_of2']; } $categories3_child_of = "0"; if (isset($_GET['child_of3'])) { $categories3_child_of = $_GET['child_of3']; } $query_getcategories1 = "SELECT category_id, category, is_parent, child_of FROM categories WHERE is_parent=1 AND child_of=0"; $result_getcategories1 = mysql_query($query_getcategories1, $myconnection) or die(mysql_error()); $row_getcategories1 = mysql_fetch_assoc($result_getcategories1); $query_getcategories2 = "SELECT category_id, category, is_parent, child_of FROM categories WHERE is_parent=1 AND child_of=$categories2_child_of"; $result_getcategories2 = mysql_query($query_getcategories2, $myconnection) or die(mysql_error()); $row_getcategories2 = mysql_fetch_assoc($result_getcategories2); $query_getcategories3 = "SELECT category_id, category, is_parent, child_of FROM categories WHERE is_parent=0 AND child_of=$categories3_child_of"; $result_getcategories3 = mysql_query($query_getcategories3, $myconnection) or die(mysql_error()); $row_getcategories3 = mysql_fetch_assoc($result_getcategories3); ?> <ul> <?php do { ?> <li> <a href="voucherspage.php?child_of2=<?php echo $row_getcategories1['category_id']; ?>&child_of3=0"><?php echo $row_getcategories1['category']; ?></a> </li> <?php if($row_getcategories1['category_id']==$categories2_child_of) {?> <?php do { ?> <li> <a href="voucherspage.php?child_of2=<?php echo $categories2_child_of?>&child_of3=<?php echo $row_getcategories2['category_id']; ?>"><?php echo $row_getcategories2['category']; ?></a> </li> <?php if($row_getcategories2['category_id']==$categories3_child_of) {?> <?php do { ?> <li> <?php echo $row_getcategories3['category']; ?> </li> <?php } while ($row_getcategories3 = mysql_fetch_assoc($result_getcategories3)); }?> <?php } while ($row_getcategories2 = mysql_fetch_assoc($result_getcategories2)); }?> <?php } while ($row_getcategories1 = mysql_fetch_assoc($result_getcategories1)); ?> </ul> Quote Link to comment https://forums.phpfreaks.com/topic/220697-3-tier-dynamic-navigation-with-php-can-anyone-help-a-beginner-out/ Share on other sites More sharing options...
chronister Posted December 5, 2010 Share Posted December 5, 2010 I had this same general question no too long ago and got no help on here, so I will help you with what I came up with... it works perfectly and will generate an unlimited nesting un-ordered list. You call the createMenu function to get this done. I am passing in a database class handler ( $db )... you can change it however you want. It then makes calls to the build_menu function and that in turn calls get_child_menu. All in all, it works perfectly, but you may need to adjust things to make it work for you. <?php function createMenu($db, $ulClass = false){ $items = $db->getData("SELECT linkId, displayName, url, parentId FROM navigation ORDER BY sortOrder, parentId, linkId ASC"); while ($row = mysql_fetch_object($items['result'])) { $menu[$row->linkId]['parent'] = $row->parentId; $menu[$row->linkId]['text'] = $row->displayName; $menu[$row->linkId]['link'] = $row->url; } return build_menu($menu, $ulClass); } function build_menu($menu, $ulClass){ $listClass = (isset($ulClass)) ? ' class="'.$ulClass.'"' : ''; $output = "\n".'<ul'.$listClass.'>' . "\n"; // Start menu generation foreach($menu as $linkId => $linkData ) { if (is_array($linkData)){ if($linkData['parent'] == 0 ) { $output .= ' <li class="'.$linkData['class'].'"><a href="'.$linkData['link'].'"><span>'.$linkData['text'].'</span></a>'.get_child_menu($menu, $linkId).'</li>' . "\n"; } } } $output .= '</ul>'."\n"; return $output . "\n\t"; } function get_child_menu($menu, $parentId){ $has_subcats = FALSE; $output = "\n".' <ul>' . "\n"; foreach($menu as $linkId => $linkData){ if ($linkData['parent'] == $parentId ) { $has_subcats = TRUE; $output .= ' <li><a href="'.$linkData['link'].'">'; $output .= $linkData['text']; $output .= '</a>'; $output .= get_child_menu($menu, $linkId); $output .= '</li>' . "\n"; } } $output .= ' </ul>'."\n"; return ( $has_subcats ) ? $output : FALSE; } ?> It is based on the principle of getting the data from the database and returning an array and passing that to the next function. It looks a little cleaner than your existing code. The database is structured like this..... linkId displayName url parentId sortOrder linkId is an auto-incrementing primary key, displayName is what is displayed for the link text, the url is it's href location, the parentId is the parentId of this item and the sortOrder is for specifying sort order. Holler back if you have any questions. Nate Quote Link to comment https://forums.phpfreaks.com/topic/220697-3-tier-dynamic-navigation-with-php-can-anyone-help-a-beginner-out/#findComment-1143087 Share on other sites More sharing options...
jimmyoneshot Posted December 5, 2010 Author Share Posted December 5, 2010 Hi chronister. I know the feeling of not getting much help here so thanks for the great reply The thing is I forgot to mention I really need to get this working using my code that I have above. As a php beginner your code is a fair bit too advanced for me although I have no doubt that it would work. This is for a university project and is meant to use 3 do while loops and if statements as that in conjunction with navigation and parameter passing $_GET etc is what we are learning now. The first question I have is - is the createmenu function in your example an inbuilt php function and what does $ulClass = false mean in it's parameters? Is this some sort of session? There are just so many things in your example I've never touched upon although as I say I'm sure it'd work great. I just don't want to get in the habit of using other people's code that I have no way of understanding just yet simply to solve my problem. I hope you understand what I mean. The problem I have with my own code seems to be something to do with the if statements I think because bullet points list items shouldn't be appearing underneath categories that do not have any children such as Cat1D or Cat2B but for some reason they are like this:- http://www.coolvisiontest.com/garyssite/rhrvouchers/voucherspage.php I'd love to be able to solve my code then I'll look into your code for future reference. Do you have any ideas on this? Thanks for all your help so far. Quote Link to comment https://forums.phpfreaks.com/topic/220697-3-tier-dynamic-navigation-with-php-can-anyone-help-a-beginner-out/#findComment-1143200 Share on other sites More sharing options...
chronister Posted December 5, 2010 Share Posted December 5, 2010 The first question I have is - is the createmenu function in your example an inbuilt php function and what does $ulClass = false mean in it's parameters? Is this some sort of session? No, createMenu is not a built in function, it is created right where you see it at. function createMenu($db, $ulClass = false){ <-- This is the line that is creating this function. The $ulClass = false is an optional parameter to specify a specific class for the un-ordered list that is created. Anytime you create a function, you will typically have parameters that are passed into it. Some of those parameters are optional. By setting $ulClass to false in the function creation, it ensures that the variable is dealt with regardless if I pass a class name into it or not. I don't have proper code in there to handle errors if the $db class handle is not passed, but this code is for me and I will ensure that I pass that into it. Your code is printing empty LI tags because of the way your logic is set. I think it is here <?php do { ?> <li> <?php echo $row_getcategories3['category']; ?> </li> <?php } You have to realize that a do - while loop will do the condition at least once before it hits the while part to determine if it should do it or not. You can try changing <li> <?php echo $row_getcategories3['category']; ?> </li> to if(isset($row_getcategories3['category']){ echo '<li>'.$row_getcategories3['category'].'</li>'; } This checks to see if there is something to display before actually trying to display it. Same principle for the others... if there is not something to show it will probably display an empty LI tag for them. Hope this helps. Nate Quote Link to comment https://forums.phpfreaks.com/topic/220697-3-tier-dynamic-navigation-with-php-can-anyone-help-a-beginner-out/#findComment-1143331 Share on other sites More sharing options...
jimmyoneshot Posted December 5, 2010 Author Share Posted December 5, 2010 Hi mate that mates total sense and isset is something I understand already i.e. checking to see if a value is null or not. SO the li's were basically being printed out even if the value was null. I can't believe I never thought of it. I've made the change you suggested and now I get a parse error. I think it's something small to do with how I've organised my brackets/php tags:- Parse error: syntax error, unexpected '{' in /home/coolvisi/public_html/garyssite/rhrvouchers/voucherspage.php on line 46 It's pointing at the line:- <?php if(isset($row_getcategories3['category']){echo '<li>'.$row_getcategories3['category'].'</li>';}?> Here's the code now with your change in place:- <?php require_once('connectionfile.php'); mysql_select_db($database, $myconnection); $categories2_child_of = "0"; if (isset($_GET['child_of2'])) { $categories2_child_of = $_GET['child_of2']; } $categories3_child_of = "0"; if (isset($_GET['child_of3'])) { $categories3_child_of = $_GET['child_of3']; } $query_getcategories1 = "SELECT category_id, category, is_parent, child_of FROM categories WHERE is_parent=1 AND child_of=0"; $result_getcategories1 = mysql_query($query_getcategories1, $myconnection) or die(mysql_error()); $row_getcategories1 = mysql_fetch_assoc($result_getcategories1); $query_getcategories2 = "SELECT category_id, category, is_parent, child_of FROM categories WHERE is_parent=1 AND child_of=$categories2_child_of"; $result_getcategories2 = mysql_query($query_getcategories2, $myconnection) or die(mysql_error()); $row_getcategories2 = mysql_fetch_assoc($result_getcategories2); $query_getcategories3 = "SELECT category_id, category, is_parent, child_of FROM categories WHERE is_parent=0 AND child_of=$categories3_child_of"; $result_getcategories3 = mysql_query($query_getcategories3, $myconnection) or die(mysql_error()); $row_getcategories3 = mysql_fetch_assoc($result_getcategories3); ?> <ul> <?php do { ?> <li> <a href="voucherspage.php?child_of2=<?php echo $row_getcategories1['category_id']; ?>&child_of3=0"><?php echo $row_getcategories1['category']; ?></a> </li> <!--LEVEL 2 START--> <?php if($row_getcategories1['category_id']==$categories2_child_of) {?> <?php do { ?> <li> <a href="voucherspage.php?child_of2=<?php echo $categories2_child_of?>&child_of3=<?php echo $row_getcategories2['category_id']; ?>"><?php echo $row_getcategories2['category']; ?></a> </li> <?php if($row_getcategories2['category_id']==$categories3_child_of) {?> <?php do { ?> <?php if(isset($row_getcategories3['category']){echo '<li>'.$row_getcategories3['category'].'</li>';}?> <?php } while ($row_getcategories3 = mysql_fetch_assoc($result_getcategories3)); }?> <?php } while ($row_getcategories2 = mysql_fetch_assoc($result_getcategories2)); }?> <?php } while ($row_getcategories1 = mysql_fetch_assoc($result_getcategories1)); ?> </ul> Quote Link to comment https://forums.phpfreaks.com/topic/220697-3-tier-dynamic-navigation-with-php-can-anyone-help-a-beginner-out/#findComment-1143344 Share on other sites More sharing options...
jimmyoneshot Posted December 5, 2010 Author Share Posted December 5, 2010 Aha got it The line should have been:- <?php if(isset($row_getcategories3['category'])){echo '<li>'.$row_getcategories3['category'].'</li>';}?> Thanks again for all the help Nate. You've been great Quote Link to comment https://forums.phpfreaks.com/topic/220697-3-tier-dynamic-navigation-with-php-can-anyone-help-a-beginner-out/#findComment-1143387 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.