A Tree (Sliding) Menu Written In PHP
Recently posed on Yahoo! Answers:
Regarding PHP, what would be a good way to make dynamic tree like menu?
So when the user first looks at the page, they see
2004
2005
2006
2007When they click on the year, a sub menu drops down as follows.
2004
2005
–january
–february
–march
–…..
–december
2006
2007
etc.
if they click on the year again, the menu will collapse
im trying to avoid javascript at all possiblethanks
For the most part, tree (aka sliding, aka dynamic) menus these days seldom involve posting back to the server; they’re more commonly made either with CSS alone, JavaScript alone or a combination of the two. However, some folks want to keep things both aesthetic and primitive, for maximum compatibility.
So, without further ado, here’s a tree (slider / dynamic) menu written solely in PHP.
Our script will do the following:
- Receive from the querystring the current year selected and test it for type and range (that is, make sure it’s an integer between a starting and ending year). If there is not a year in the querystring, all the years will be collapsed.
- Display the months for the selected year, with a link back to the same page that adds month and year variables to the querystring.
- We’ll pretty it all up by using nested lists and styling them with CSS.
OK, Step 1 is to set some variables. We’re going to use a loop to output the years for this menu, so we need to know the lowest and highest years we’ll be outputting. Setting these as virtual constants makes it easier to amend our code for later dates.
We next set the value of a variable we’ll call $theyear to be the same as the y value in our querystring. Finally, we test to see if the y variable is present, in the proper format and in range; if any of those are not the case, we set the value of $theyear to be zero, for reasons that will be explained shortly.
$MIN_YEAR = 2004; $MAX_YEAR = 2007; $theyear = $_GET['y']; if(ereg('^[0-9]{4}$', $theyear)) { if($theyear > $MAX_YEAR || $theyear < $MIN_YEAR) { $theyear = 0; } } else { $theyear = 0; }
Before we get into the code that will actually output our menu, we need to create two functions.
The first we will call monthName. It will take an integer as an argument and return a string with the name of the month that corresponds to the integer. For example, if it gets 1 as an argument, it will return “January,” if it gets 12 as an argument, it will return “December.” If the input is out of range, the function will return “No Month.”
function monthName($intput) { switch($intput) { case 1: $out = "January"; break; case 2: $out = "February"; break; case 3: $out = "March"; break; case 4: $out = "April"; break; case 5: $out = "May"; break; case 6: $out = "June"; break; case 7: $out = "July"; break; case 8: $out = "August"; break; case 9: $out = "September"; break; case 10: $out = "October"; break; case 11: $out = "November"; break; case 12: $out = "December"; break; default: $out = "No Month"; } return $out; }
The second function we need will be called makeURL. The issue we face in using this script is that we’ll be dynamically creating navigation links based on the year selected. We could normally handle that by just appending the appropriate y and m (year and month) variables to the current script’s name.
But what if we have other querystring variables? We need to preserve those so we can pass them back to the page, along with the newly selected month and year variables. So, to accommodate that, we get from PHP the name of the current script, examine each querystring variable, and if it isn’t a year or month variable, we append it right back on to the querystring.
We replace the year value for the querystring with the new year generated by the menu; and, if we provide an optional $month parameter to the function, we append that month to the URL as well.
function makeUrl($year, $month = 0) { $url = $_SERVER['PHP_SELF'] . "?"; foreach($_GET as $key => $value) { if($key != 'y' && $key != 'm') { $url .= "$key=$value&"; } } $url .= "y=$year"; if($month != 0) { $url .= "&m=$month"; } return $url; }
The code to output the tree / sliding menu itself is very simple. We just create an unordered list and start iterating through all the years from the $MIN_YEAR to the $MAX_YEAR, writing each out as a list item.
If the year we are outputting matches the year in the querystring, we create another unordered list beneath the current list item, and output all 12 months of the year. We create new nav links as we go along.
To finish up, we close our loops, and that’s it.
echo "<ul>\n"; for($i = $MIN_YEAR; $i <= $MAX_YEAR; $i++) { echo "<li lang=\"majorBranch\"><a href=\"" . makeUrl($i) . "\">$i"; if($theyear == $i) { echo "</a>"; echo "<ul>\t"; for($x = 1; $x <= 12; $x++) { echo "<li lang=\"minorBranch\"><a href=\"" . makeUrl($i, $x) ."\">".monthName($x)."</a></li>\n"; } echo "</ul>\n"; } else { echo "</a>"; } echo "</li>\n"; } echo "</ul>\n";
You can see a working demo of this at http://www.dougv.com/demo/phptreemenu/. And, of course, you can download the source code under the terms of the Creative Commons Attribution / Share-Alike 2.5 License:
A Tree (Sliding) Menu Written In PHP Demo Code
I distribute code under the latest version of the Creative Commons Attribution / Share-Alike License.































dougv.com | The Web home of Doug Vanderweide » Blog Archive » A Discourse On The Nature Of Learning How To Program:
[...] Also, explaining things takes a lot more time than doing things. I knocked out the code for the PHP menu in about 15 minutes, but it took about an hour to document it and write my blog entry on it. [...]
January 9, 2007, 2:54 AM