PHP navigation with $_GET method ignoring css active class [duplicate] - php

This question already has answers here:
how to add active to a tag and li tag with php
(5 answers)
Closed 8 years ago.
My hover links work as well as the navigation, but the active link will not come on.
My CSS active:
#header ul li a.active,
#header ul li a.active:hover {
color:#fff;
background:#000;
font-weight:bold;
Here is my nav.php file:
<ul>
<?php
$pages = array(
"index.php?p=home" => "Home",
"index.php?p=contact" => "Contact Us",
"index.php?p=services" => "Services",
"index.php?p=employees" => "Employees",
"index.php?p=dashboard" => "Dashboard");
$p = (isset($_GET['p'])) ? $_GET['p'] : "";
foreach ($pages as $url => $label) {
echo '<li ';
if (preg_match("/$p/",$url)) {
echo "class='active'";
}
echo '><a href=', "$url", '>', "$label", '</a></li>';
}
?>
</ul>
This is my method inside of the index page retrieving each page:
<?php
if (file_exists("pages/$p.php")) {
include("pages/$p.php");
}else{
include("pages/home.php");
}
?>

I suppose that you are using urls like: /index.php?p=page_name
<ul>
<?php
$pages = array(
"home" => "Home",
"contact" => "Contact Us",
"services" => "Services",
"employees" => "Employees",
"dashboard" => "Dashboard");
$p = (isset($_GET['p'])) ? $_GET['p'] : "";
foreach ($pages as $url => $label) {
echo '<li ';
if ($p == $url) {
echo "class='active'";
}
echo '>' . $label . '</li>';
}
?>
</ul>

Related

php: Generate dynamic menu with CSS code from multidimensional array

I'm trying to mark the current requested page as active in my menu but something seems to go wrong... Me and my co-workers can't figure out what's going wrong... I've been trying to figure this one out for more than a week now, I've read what feels like dozens of questions and answers on this and other sites to no avail.
The one thing that really puzzles me is how the value of $page seems to change from a string to a number as you can tell with the debugging I've implemented.
This is the relevant code from index.php:
$pages = array('home','overons','onsteam','organisatie','diensten','aandeslag',
'ictlab','eendagbij','opdrachtgevers','verwijzers',
'trajectbegeleiding','contact');
if(in_array($_GET['p'], $pages)) {
$content = $_GET['p'];
} else {
$content = "home";
}
echo "<!-- content = ".$content." -->\n";
require($inc_path.'navbar'.$php_ext);
and the code from navbar.php:
$menu = array (
'home',
'overons' => array (
'onsteam',
'organisatie'
),
'diensten' => array (
'aandeslag',
'ictlab',
'eendagbij'
),
'opdrachtgevers',
'verwijzers' => array (
'trajectbegeleiding'
),
'contact'
);
$pagenames = array (
'home' => 'Home',
'overons' => 'Over Ons',
'onsteam' => 'Ons Team',
'organisatie' => 'Organisatie',
'diensten' => 'Diensten',
'aandeslag' => 'Aan De Slag',
'ictlab' => 'ICT Lab',
'eendagbij' => 'Een dag bij',
'opdrachtgevers' => 'Opdrachtgevers',
'verwijzers' => 'Verwijzers',
'trajectbegeleiding' => 'Traject begeleiding',
'contact' => 'Contact'
);
function MakeMenu($menu, $currentpage, $level = 0) {
echo "<!-- MakeMenu0: currentpage = ".$currentpage." -->\n";
global $pagenames;
$ret = "";
$indent = str_repeat(" ", $level * 2);
if ($level!=0) {
$ret .= "<!-- MakeMenu1: Level = ".$level." -->\n";
$ret .= sprintf("%s<ul class=\"dropdown-menu\">\n", $indent);
} else {
$ret .= "<!-- MakeMenu2: Level = 0 -->\n";
$ret .= sprintf("%s<ul class=\"nav navbar-nav\">\n", $indent);
}
$indent = str_repeat(" ", ++$level * 2);
foreach ($menu as $page => $subpages) {
if (!is_numeric($page)) {
if ($page==$currentpage) {
$ret .= "<!-- MakeMenu3: page (".$page.") = currentpage (".$currentpage.") -->\n";
if (is_array($subpages)) {
$ret .= sprintf("%s<li class=\"active dropdowm\"><a href='?p=%s'>%s<span class='caret'></span></a>", $indent, $page, $pagenames[$page]);
} else {
$ret .= sprintf("%s<li class=\"active\"><a href='?p=%s'>%s</a>", $indent, $page, $pagenames[$page]);
}
} else {
$ret .= "<!-- MakeMenu4: page (".$page.") != currentpage (".$currentpage.") -->\n";
if (is_array($subpages)) {
$ret .= sprintf("%s<li class=\"dropdown\"><a href='?p=%s'>%s<span class='caret'></span></a>", $indent, $page, $pagenames[$page]);
} else {
$ret .= sprintf("%s<li><a href='?p=%s'>%s</a>", $indent, $page, $pagenames[$page]);
}
}
}
if (is_array($subpages)) {
$ret .= "\n";
$ret .= MakeMenu($subpages, $currentpage, $level + 1);
$ret .= $indent;
} else if (strcmp($page, $subpages)) {
if ($page==$currentpage){
$ret .= "<!-- MakeMenu5: page (".$page.") = currentpage (".$currentpage.") -->\n";
$ret .= sprintf("%s<li class=\"active\"><a href='?p=%s'>%s</a>", $indent, $subpages, $pagenames[$subpages]);
} else {
$ret .= "<!-- MakeMenu6: page (".$page.") != currentpage (".$currentpage.") -->\n";
$ret .= sprintf("%s<li><a href='?p=%s'>%s</a>", $indent, $subpages, $pagenames[$subpages]);
}
}
$ret .= sprintf("</li>\n", $indent);
}
$indent = str_repeat(" ", --$level * 2);
$ret .= sprintf("%s</ul>\n", $indent);
return($ret);
}
echo MakeMenu($menu, $content);
And the very puzzeling output:
<!-- MakeMenu0: currentpage = overons -->
<!-- MakeMenu0: currentpage = overons -->
<!-- MakeMenu0: currentpage = overons -->
<!-- MakeMenu0: currentpage = overons -->
<!-- MakeMenu2: Level = 0 -->
<ul class="nav navbar-nav">
<!-- MakeMenu5: page (0) = currentpage (overons) -->
<li class="active"><a href='?p=home'>Home</a></li>
<!-- MakeMenu3: page (overons) = currentpage (overons) -->
<li class="active dropdowm"><a href='?p=overons'>Over Ons<span class='caret'></span></a>
<!-- MakeMenu1: Level = 2 -->
<ul class="dropdown-menu">
<!-- MakeMenu5: page (0) = currentpage (overons) -->
<li class="active"><a href='?p=onsteam'>Ons Team</a></li>
<!-- MakeMenu6: page (1) != currentpage (overons) -->
<li><a href='?p=organisatie'>Organisatie</a></li>
</ul>
</li>
<!-- MakeMenu4: page (diensten) != currentpage (overons) -->
<li class="dropdown"><a href='?p=diensten'>Diensten<span class='caret'></span></a>
<!-- MakeMenu1: Level = 2 -->
<ul class="dropdown-menu">
<!-- MakeMenu5: page (0) = currentpage (overons) -->
<li class="active"><a href='?p=aandeslag'>Aan De Slag</a></li>
<!-- MakeMenu6: page (1) != currentpage (overons) -->
<li><a href='?p=ictlab'>ICT Lab</a></li>
<!-- MakeMenu6: page (2) != currentpage (overons) -->
<li><a href='?p=eendagbij'>Een dag bij</a></li>
</ul>
</li>
<!-- MakeMenu6: page (1) != currentpage (overons) -->
<li><a href='?p=opdrachtgevers'>Opdrachtgevers</a></li>
<!-- MakeMenu4: page (verwijzers) != currentpage (overons) -->
<li class="dropdown"><a href='?p=verwijzers'>Verwijzers<span class='caret'></span></a>
<!-- MakeMenu1: Level = 2 -->
<ul class="dropdown-menu">
<!-- MakeMenu5: page (0) = currentpage (overons) -->
<li class="active"><a href='?p=trajectbegeleiding'>Traject begeleiding</a></li>
</ul>
</li>
<!-- MakeMenu6: page (2) != currentpage (overons) -->
<li><a href='?p=contact'>Contact</a></li>
</ul>
Well regarding puzzling behavior:
The one thing that really puzzles me is how the value of $page seems
to change from a string to a number as you can tell with the debugging
I've implemented.
If you look closely at this line:
foreach ($menu as $page => $subpages) {
you will see that key of an array is assigned to $page. From your array:
$menu = array (
'home',
'overons' => array(
'onsteam',
'organisatie'
),
'diensten' => array(
'aandeslag',
'ictlab',
'eendagbij'
),
'opdrachtgevers',
'verwijzers' => array(
'trajectbegeleiding'
),
'contact'
);
we can see that some of pages are keys, and some are values. That is why you have sometimes pages names and sometimes array indexes.
You can define your array as following to prevent this behavior:
$menu = [
'home' => null,
'overons' => [
'onsteam' => null,
'organisatie' => null
],
'diensten' => [
'aandeslag' => null,
'ictlab' => null,
'eendagbij' => null
],
'opdrachtgevers' => null,
'verwijzers' => [
'trajectbegeleiding' => null
],
'contact' => null
];
Going further you have a really complicated recursive function. I would suggest using PHP Iterators. In particular RecursiveArrayIterator alongside with RecursiveIteratorIterator, that can be extended like this:
class UlRecursiveIteratorIterator extends RecursiveIteratorIterator
{
public function beginIteration()
{
echo '<ul class="nav navbar-nav">', PHP_EOL;
}
public function endIteration()
{
echo '</ul>', PHP_EOL;
}
public function beginChildren()
{
echo str_repeat(' ', $this->getDepth() + 1), '<ul class="dropdown-menu">', PHP_EOL;
}
public function endChildren()
{
echo str_repeat(' ', $this->getDepth() + 1), '</ul>', PHP_EOL;
echo str_repeat(' ', $this->getDepth()), '</li>', PHP_EOL;
}
}
Having this iterator, your function can be refactored to one simple foreach loop:
$iterator = new RecursiveArrayIterator($menu);
$iterator = new UlRecursiveIteratorIterator(
$iterator,
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $page => $_) {
$active = false;
// Used for pritty print only. Remove in production.
$depth = $iterator->getDepth();
$line = str_repeat(' ', ($depth + 1) + ($depth === 0 ? 0 : 1));
if ($page === $content) {
$active = true;
}
$class = $active ? 'active' : '';
if ($iterator->callHasChildren()) {
$line .= "<li class=\"$class dropdown\"><a href='?p=$page'>{$pagenames[$page]}<span class='caret'></span></a>";
} else {
$line .= "<li class=\"$class\"><a href='?p=$page'>{$pagenames[$page]}</a>";
}
echo $line, PHP_EOL;
}
Here is the demo.

How can I remove nested nav from all top-level listed items, except for Services in a PHP array?

I am trying to remove the nested list ($subPages) from displaying under all of the top-level lists ($pages), except for Services; however my code is allowing the nested list items to display under all three top-level list items.
Can anyone help me remove the nested list items from all top-level list items, except for one?
NB. I am new to PHP, and would like to just stick to PHP without any other languages. My PHP code may be in efficient; if you spot room for improvement, let me know.
<nav class="navBar wAuto fRight positAb">
<?php
$pages = array(
'/about/' => 'About',
'/services/' => 'Services',
'/book-a-service/' => 'Book a service'
);
$subPages = array(
'/services/bathroom-installation' => 'Bathroom installation',
'/services/boiler-repair' => 'Boiler repair',
'/services/boiler-service' => 'Boiler service',
'/services/gas-oil' => 'Gas & oil',
'/services/heat-recovery' => 'Heat recovery',
'/services/heating-plumbing' => 'Heating and plumbing',
'/services/rainwater-harvesting' => 'Rainwater harvesting',
'/services/solar-solutions' => 'Solar solutions',
'/services/underfloor-heating' => 'Underfloor heating'
);
$activePage = $_SERVER['REQUEST_URI'];
echo '<ul>';//open nav
foreach( $pages as $url => $anchor){
$activeClass = ($_SERVER['REQUEST_URI'] == $url) ? " active" : "";
echo '<li class="fLeft"><a class="font13'.$activeClass.'" href="'.$url.'"';
if($url == '/services/'){
echo 'id="parent"';
}
if($url == '/book-a-service/')
echo 'id="ctaUHP"';
echo '>'.$anchor.'</a>';
//Open nested nav
if(isset($url) == '/services/'){
echo '<ul class="wAuto positAb">';
foreach ($subPages as $url => $anchor){
echo '<li class="fullWidth"><a class="font10" href="'.$url.'"';//open nested nav
echo '>'.$anchor.'</a></li>';
}
};
echo '</li></ul>'; //close nested nav
}
//Close submenu
echo '</ul>';
//close nav
?>
</nav>
In the code for open nested nav, change if(isset($url) == '/services/') to if($url == '/services/'){
Explanation: You don't need to verify if the $url is set, you just need to print the nested nav when your $url == '/services/', that's why you need to remove the function isset() :)
EDIT
You lacked some {} and I even rearranged some of your code, so now looks like this :)
echo '<ul>'; //open nav
foreach( $pages as $url => $anchor) {
$activeClass = ($_SERVER['REQUEST_URI'] == $url) ? " active" : "";
echo '<li class="fLeft"><a class="font13'.$activeClass.'" href="'.$url.'"';
if($url == '/services/') {
echo 'id="parent"';
}
if($url == '/book-a-service/') {
echo 'id="ctaUHP"';
}
echo '>'.$anchor.'</a>';
//verify if exists nested nav
if($url == '/services/') {
echo '<ul class="wAuto positAb">'; //open nested nav
foreach ($subPages as $url => $anchor) {
echo '<li class="fullWidth"><a class="font10" href="'.$url.'">'.$anchor.'</a></li>';
}
echo '</ul>'; //close nested nav
}
echo '</li>';
}
echo '</ul>'; //close nav

php navigation using get or include

index.php is controlling the site.
I have elseif include based on variable $p
right now $p does not have anything in it and i'm not understanding why.
Also is using include the industry standard or would GET be a better choice?
In the header file which is included on index.php but it just takes me to the page link instead of storing the page in $p
<?php
$pages = array(
"home" => "HOME",
"services" => "SERVICES",
"employees" => "EMPLOYEES",
"contact" => "CONTACT");
$p = (isset($_GET['p'])) ? $_GET['p'] : "";
foreach ($pages as $url => $label) {
echo '<li ';
if ($p == $url) { echo '<li><a class="active" href="' . htmlspecialchars(urlencode($url)). '.php">'
. htmlspecialchars($label) . '</a></li>'; } else { echo '<li>' . $label . '</li>'; }
}
?>
This is the index.php file:
<?php include('includes/header.php'); ?>
<?php
if ($p == "services") {
include("services.php");
} elseif($p == "employees") {
include("employees.php");
} elseif($p == "contact") {
include("contact.php");
} else {
include("home.php");
};
?>
<?php include('includes/footer.php'); ?>
It really depends on what you are trying to do. Maybe I am misunderstanding your question, however include and $_GET are two completely separate things.
$_GET is an array of the query string out of your URL. So, for instance, if your URL was mysite.com/index.php?a=rawr&p=services then $_GET would be array("a" => "rawr", "p" => "services"); If you don't have any parameters in your URL assigned to p, then $_GET["p"] would be empty
Source:
http://www.php.net/manual/en/reserved.variables.get.php
EDIT:
I think I'm starting to understand your question now. Using your current method would be fine, I would just change up the code slightly:
<?php
$pages = array(
"home" => "HOME",
"services" => "SERVICES",
"employees" => "EMPLOYEES",
"contact" => "CONTACT"
);
$p = (isset($_GET['p'])) ? $_GET['p'] : "";
foreach ($pages as $url => $label) {
?>
<li><a <?= $p == $url ? 'class="active"' : ""?> href="index.php?p=<?=$url?>" > <?=$label?> </a></li>
<?php
}
?>

Get current url excluding Included file names

I have a file named administrator1.php and inside it test.php is included. So code inside administrator1.php is
<?php include 'test.php'; ?>
I have a dynamic navigation menu inside test.php. Code is
<?php
$menu = array(
'users' => array('text'=>'USERS', 'url'=>'administrator1.php'),
'createProfile' => array('text'=>'CREATE PROFILE', 'url'=>'administrator2.php'),
'payment' => array('text'=>'PAYMENTS', 'url'=>'administrator3.php'),
'defense' => array('text'=>'DEFENSE', 'url'=>'administrator4.php'),
'progressReport' => array('text'=>'PROGRESS REPORT', 'url'=>'administrator5.php'),
);
class Nav {
function GenerateMenu($items) {
$html = "<ul>";
foreach($items as $item) {
if(stristr(__FILE__,$item['url'])===FALSE) {
$html .= "<li><a href='{$item['url']}' ><span><B>{$item['text']}</B></span> </a> </li>";
}
else {
$html .= "<li class='active'><a href='{$item['url']}' ><span><B>{$item['text']}.nnn</B></span> </a></li>";
}
}
$html .= "</ul>";
return $html;
}};
echo Nav::GenerateMenu($menu);
?>
And I have called the Nav method inside the same file.
Problem here is, the whole navigation bar will be printed, but selected item's ('USERS') CSS class active will not be called. But if I replace this whole code in administrator1.php file without including a test.php file it works fine. So I guess it is a problem to file path of the included file. And is it because I have used __FILE__ to get current path? Then how can I get current file path excluding included files names in the path?
For calling the static function we can use :: operator. But for accessing the non-static member of the class you should make the object, like -
$nav_ob = new Nav();
echo $nav_ob->GenerateMenu($menu);
And there s problem, when you are creating array -
$menu = array(
'users' => array('text'=>'USERS', 'url'=>'administrator1.php'),
'createProfile' => array('text'=>'CREATE PROFILE', 'url'=>'administrator2.php'),
'payment' => array('text'=>'PAYMENTS', 'url'=>'administrator3.php'),
'defense' => array('text'=>'DEFENSE', 'url'=>'administrator4.php'),
'progressReport' => array('text'=>'PROGRESS REPORT', 'url'=>'administrator5.php'), //Here
);
Comma after the last element. It should be -
$menu = array(
'users' => array('text'=>'USERS', 'url'=>'administrator1.php'),
'createProfile' => array('text'=>'CREATE PROFILE', 'url'=>'administrator2.php'),
'payment' => array('text'=>'PAYMENTS', 'url'=>'administrator3.php'),
'defense' => array('text'=>'DEFENSE', 'url'=>'administrator4.php'),
'progressReport' => array('text'=>'PROGRESS REPORT', 'url'=>'administrator5.php')
);
UPDATED
<?php
$menu = array(
'users' => array('text'=>'USERS', 'url'=>'administrator1.php'),
'createProfile' => array('text'=>'CREATE PROFILE', 'url'=>'administrator2.php'),
'payment' => array('text'=>'PAYMENTS', 'url'=>'administrator3.php'),
'defense' => array('text'=>'DEFENSE', 'url'=>'administrator4.php'),
'progressReport' => array('text'=>'PROGRESS REPORT', 'url'=>'administrator5.php')
);
class Nav {
function GenerateMenu($path, $items) {
$html = "<ul>";
foreach($items as $item) {
if(stristr($path,$item['url'])===FALSE) {
$html .= "<li><a href='{$item['url']}' ><span><B>{$item['text']}</B></span> </a> </li>";
}
else {
$html .= "<li class='active'><a href='{$item['url']}' ><span><B>{$item['text']}.nnn</B></span> </a></li>";
}
}
$html .= "</ul>";
return $html;
}};
?>
And on each administrator.php file after including the above php file call the method like -
$nav_ob = new Nav();
echo $nav_ob->GenerateMenu(__FILE__, $menu);
Hope this will help.
Found the answer!
Replaced __FILE__ with $_SERVER["PHP_SELF"]. So the code is;
class Nav {
function GenerateMenu($items) {
$html = "<ul>";
foreach($items as $item) {
if(stristr($_SERVER["PHP_SELF"],$item['url'])===FALSE) {
$html .= "<li><a href='{$item['url']}' ><span><B>{$item['text']}</B></span> </a> </li>";
}
else {
$html .= "<li class='active'><a href='{$item['url']}' ><span><B>{$item['text']}.</B></span> </a></li>";
}
}
$html .= "</ul>";
return $html;
}};
$nav_ob = new Nav();
echo $nav_ob->GenerateMenu($menu);
Now it works as i wanted! Thank you everyone for the help given!

multidimensional array

i have a multidimensional array like this
$role = array (
'Dashboard' => null,
'Students' =>
array (
'Admission' => array ( 0 => 'Entry' ,1 => 'Review' , 2 => 'Approved/Reject'
),
'Search' => null,
'AdvanceSearch' => null,
'Courses' => null
),
'HR' => array ('Settings' => null),
'Employee Management' => array ( 0 => 'Entry',1 => 'Association',2 => 'Search' ),
'Employee Attendance' => null,
'Payroll' => array (0 => 'Generate Pay Slip',1 => 'Payroll Run' , 2 => 'Payroll Revert',3 => 'View Pay Slips'),
'Finance' => null,
'More' => null);
and i want to print this array result in my html as
i am trying to do this by using recursion but unable to do that as DIV are not properly closed ..
here is the code that i am trying in my html
<?php
$child = 0;
function RecursiveWrite($array, $child ) {
$parent_array_size = count($array);
foreach ($array as $key => $vals) {
if(is_array($vals)){
$inner_array_size = count($vals);
echo "<div class='main clear'><input type='checkbox'/> ".$key." ";
RecursiveWrite($vals,$child);
}else{
$child = 0;
if(is_numeric($key)){
echo " <div class='left'> <input type='checkbox' class=''/> ".$vals." </div></div>";
}else{
echo "<div class='clear'><input type='checkbox'/> ".$key." </div></div>";
}
}
//
}
}
RecursiveWrite($role, $child);
?>
here is working code
How can i get this Any suggestion ... ?
Your Problem is missing closing div after recursion
Try this Function
function RecursiveWrite($array, $child )
{
$parent_array_size = count($array);
foreach ($array as $key => $vals)
{
if(is_array($vals))
{
$inner_array_size = count($vals);
echo "<div class='deep'><div class='extra'><input type='checkbox'/> ".$key."</div>";
RecursiveWrite($vals,$child);
echo "</div>";
}
else
{
if(is_numeric($key)){
echo "<span class='single'><input type='checkbox' class=''/> ".$vals."</span>";
}else{
echo "<div class='single'><input type='checkbox'/> ".$key." </div>";
}
}
}
}
Use This Css
<style type="text/css">
.parent {border: solid 1px #000;}
.parent div {border: solid 1px #000; margin:5px;}
.extra {border:0px !important;}
.single {margin-left:10px !important; border:0px !important;}
span.single {display:inline-block; margin-left:20px;}
</style>
Use this to call your Function
<div class="parent"><? RecursiveWrite($role, $child);?></div>
Put all the code Provided in one page with your array.
For better Codding standard you should Septate your style html and php for this try your luck ;)
You're not closing the div in the right places, when calling the recursion, right after ending the recursion you need to write the ending div:
open div
run recursion
close div
As well, you have two unnecessary div closing. Always make sure you open as many div as you close and vice versa. I've marked the places that needed to be changed in the code.
code:
<?php
$child = 0;
function RecursiveWrite($array, $child ) {
$parent_array_size = count($array);
foreach ($array as $key => $vals) {
if(is_array($vals)){
$inner_array_size = count($vals);
echo "<div class='main clear'><input type='checkbox'/> ".$key." ";
RecursiveWrite($vals,$child);
echo "</div>"; /* <== ADD THIS */
}else{
$child = 0;
if(is_numeric($key)){
echo " <div class='left'> <input type='checkbox' class=''/> ".$vals." </div>"; /* <== REMOVE EXTRA DIV */
}else{
echo "<div class='clear'><input type='checkbox'/> ".$key." </div>"; /* <== REMOVE EXTRA DIV */
}
}
//
}
}
RecursiveWrite($role, $child);
?>
you can find a working example at http://codepad.viper-7.com/507rLc

Categories