I have a php/mysql driven menu. I am trying to add an active class to the menu item whenever the URI reflects that menu item (basically, when I am on that page) but every example I find is with a menu that is not populated through an array or repeater like mine.
How can manipulate the active class you see below so that it shows only when I am on that page?
Here is my menu
<?php
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
if($row['id'] == 2){
// below is the active class that is now being populated accross all items equally
echo '<li class="nav-item dropdown active">';
echo '<a href="#" class="nav-link dropdown-toggle animated fadeIn animation-delay-7" data-toggle="dropdown" data-hover="dropdown" role="button" aria-haspopup="true" aria-expanded="false" data-name="services">';
echo $row["pagename"];
echo '<i class="zmdi zmdi-chevron-down"></i>';
echo '</a>';
// create a new list
echo '<ul class="dropdown-menu">';
// loop second/submenu query results
while($sub_row = $result2->fetch_assoc()) {
echo '<li>';
echo '' . $sub_row["pagename"] . '';
echo '</li>';
}
echo "</ul>";
echo '</li>';
} else { // for all other menu links
echo '<li class="nav-item dropdown active">';
echo '' . $row["pagename"] . '';
echo '</li>';
}
}
} else {
echo "0 results";
}
?>
The screenshot below shows the result after it renders. Notice the active class highlighted in yellow, it is added to every item in my main menu (the way I have it coded, which it's wrong of course). The green is the $sub_row["link"] (to answer Mark's question below
Notice, the active class is only needed to be added programmatically on the main menu. (the else portion of my code).
The screenshot below shows how the active class affects the menu item if the user was in the www.domain.com/how-it-works.php page. The active class contians the styles to make the menu item appear that way.
Thanks in advance
Hard to test with not having the DB outputs to match against mate but try this, basically you want an if statement to get the current page URL and match it against the url you get back from the DB.
<?php
if ($result->num_rows > 0) {
$pageURL = str_replace('/', '', $_SERVER['REQUEST_URI']);
$homeURL = $_SERVER['REQUEST_URI'];
// output data of each row
while($row = $result->fetch_assoc()) {
if($row['id'] == 2){ ?>
<li class="nav-item dropdown">
<a href="" class="nav-link dropdown-toggle animated fadeIn animation-delay-7" data-toggle="dropdown" data-hover="dropdown" role="button" aria-haspopup="true" aria-expanded="false" data-name="services">
<?php echo $row["pagename"];?>
<i class="zmdi zmdi-chevron-down"></i>
</a>
<ul class="dropdown-menu">
<?php while($sub_row = $result2->fetch_assoc()) {?>
<li>
<a href="<?php echo $sub_row["link"]; ?>" class="dropdown-item">
<?php echo $sub_row["pagename"] ?>
</a>
</li>
<?php } ?>
</ul>
</li>
<?php
} else if($row['id'] == 1){ ?>
<li class="nav-item dropdown <?php echo ($homeURL == $row["link"])? 'active' : '';?>">
<a href="<?php echo $row["link"]; ?>" class="nav-link dropdown-toggle animated fadeIn animation-delay-7">
<?php echo $row["pagename"]; ?>
</a>
</li>
<?php
} else { ?>
<li class="nav-item dropdown <?php echo ($pageURL == $row["link"])? 'active' : '';?>">
<a href="<?php echo $row["link"]; ?>" class="nav-link dropdown-toggle animated fadeIn animation-delay-7">
<?php echo $row["pagename"]; ?>
</a>
</li>
<?php }
}
} else {
echo "0 results";
}
?>
Edit:
Bit that gets the current page url is:
$pageURL = end(explode('/', $_SERVER['REQUEST_URI']));
Bit that does the check is (this is just a shorthand if statement:
<?php echo ($pageURL == $row["link"])? 'active' : '';?>
Related
I have this code that supposed to generate a multi-level menu from my database. My problem I have a specific HTML code when there are/are no child menu.
Here is the HTML Code if the menu does not have a child menu:
<li class="nav-item dropdown">Menu</li>
Here is the HTML code if the menu has a child menu:
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle arrow-none" href="javascript: void(0);" id="topnav-user-access" role="button">
<span key="t-user-access">Parent Menu</span> <div class="arrow-down"></div>
</a>
<div class="dropdown-menu" aria-labelledby="topnav-user-access">
Child Menu 1
Child Menu 2
...
</div>
</li>
Here is my PHP code to generate the menu.
public function generate_multilevel_menu($module_id, $username, $parent_menu = null){
$menu = '';
if(!empty($parent_menu)){
$query = 'SELECT MENU_ID, MENU, PARENT_MENU, IS_LINK, MENU_LINK FROM technical_menu WHERE MODULE_ID = :module_id AND PARENT_MENU = :parent_menu ORDER BY ORDER_SEQUENCE, MENU';
}
else{
$query = 'SELECT MENU_ID, MENU, PARENT_MENU, IS_LINK, MENU_LINK FROM technical_menu WHERE MODULE_ID = :module_id AND (PARENT_MENU IS NULL OR PARENT_MENU = "0") ORDER BY ORDER_SEQUENCE, MENU';
}
$sql = $this->db_connection->prepare($query);
$sql->bindValue(':module_id', $module_id);
if(!empty($parent_menu)){
$sql->bindValue(':parent_menu', $parent_menu);
}
if($sql->execute()){
while($row = $sql->fetch()){
$menu_id = $row['MENU_ID'];
$menu_access_right = $this->check_role_access_rights($username, $menu_id, 'menu');
if($menu_access_right > 0){
if(!empty($row['MENU_LINK'])){
$menu .= ''. $row['MENU'] .'';
#$menu .= '<li class="nav-item dropdown">'. $row['MENU'] .'</li>';
}
else{
$menu .= '<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle arrow-none" href="javascript: void(0);" id="topnav-user-access" role="button">
<span key="t-user-access">'. $row['MENU'] .'</span> <div class="arrow-down"></div>
</a>';
}
$menu .= '<div class="dropdown-menu" aria-labelledby="topnav-user-access">' . $this->generate_multilevel_menu($module_id, $username, $row['MENU_ID']) . '</div>';
$menu .= '</li>';
}
}
return $menu;
}
}
Here is the screenshot of my database structure and details.
Here is the sample output of my code:
My problem is that I can't seem to incorporate the HTML code to fit my code. The code works if the HTML code is a simple HTML list but using my HTML code and conditions I can't seem to fix it. What part of my code do I need to modify to accommodate my if conditions?
I am showing categories in Menu. Some categories have subcategories.
function for getting parent categories
function get_parent_category(){
$query="select * from blog_categories where parent_id=0
ORDER BY
CASE id
WHEN '2' THEN 1
WHEN '1' THEN 2
WHEN '3' THEN 3
ELSE id
END";
$rows=array();
$result=$this->query($query);
while($row=$this->fetch_array($result)){
$row['url']=$this->get_cat_url($row);
$rows[]=$row;
}
return $rows;
}
Function for subcategories
function get_child_category(){
$query="select * from blog_categories where parent_id!=0";
$rows=array();
$result=$this->query($query);
while($row=$this->fetch_array($result)){
$row['url']=$this->get_cat_url($row);
$rows[]=$row;
}
return $rows;
}
Showing on the page like this:
<ul class="nav navbar-nav">
<li>Home</li>
<?php
foreach($this->parent_category as $cat){
foreach($this->child_category as $child_cat){
if($cat['id']==$child_cat['parent_id']){
?>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><?php echo $cat['name'];?>
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><?php echo $child_cat['name']?></li>
</ul>
</li>
<?php
}elseif($cat['parent_id']==0){
?>
<li><span><?php echo $cat['name'];?></span></li>
<?php
}
?>
<?php }}?>
Output and Problem
The Main category circle in red color is seerah which has two subcategories. showing two times for first one in drop down one subcategory and for second time second subcategory is showing.
DB structure
What i wants:
I wants to show each subcategories under each parent category without repetition , how can i achieve this?
Here is how i handled the problem
<?php
foreach($this->parent_category as $cat){
$html = '';
foreach($this->child_category as $child_cat){
if($cat['id']==$child_cat['parent_id']){
$html .= '<li>' . $child_cat['name'] . '</li>';
// here is all child categories are saved in var.
}
}
if ($html == '') {
?>
<li><span><?php echo $cat['name'];?></span></li>
<?php
} else {
?>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><?php echo $cat['name'];?>
<span class="caret"></span></a>
<ul class="dropdown-menu">
<?php echo $html; ?> // here is displayed under parent category
</ul>
</li>
<?php
}
}
?>
Output
To me it seem you did not split your html and loops properly here:
foreach($this->parent_category as $cat){
foreach($this->child_category as $child_cat){
if($cat['id']==$child_cat['parent_id']){
?>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><?php echo $cat['name'];?>
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><?php echo $child_cat['name']?></li>
</ul>
</li>
Usually whenever you have a loop you should have some output before any nested loop started. In your case first level loop is about Categories which should become an <li> of parent main menu <ul>.
I think. You need to transform this fragment to:
foreach($this->parent_category as $cat){ ?>
<li ...>
...
<ul ...> <?php
foreach($this->child_category as $child_cat){ ?>
<li>...</li> <?php
} ?>
</ul>
</li> <?php
}
when you do not have repetitive value in $rows, why you use this part again for $cat['name']?
elseif($cat['parent_id']==0){
?>
<li><span><?php echo $cat['name'];?></span></li>
<?php
}
when in first part of foreach you create
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><?php echo $cat['name'];?>
I have a WHILE loop to create a set of 4 tabs with tab titles I get from the DB. I also have a field named tab_id (1,2,3,4) inside the DB.
When I run this code the tab_id is "1" for all 4 rows...but the tab titles display correctly. What am I doing wrong?
<?php
while($rows = mysqli_fetch_array($result)){
if ($rows['tab_id'] = 1) { ?>
<li class="active"><a href="#tab<? echo $rows['tab_id']; ?>"
role="tab" data-toggle="tab" ><? echo $rows['tab_title']; ?></a>
</li>
<?php } else { ?>
<li><a href="#tab<? echo $rows['tab_id']; ?>" role="tab" data-
toggle="tab" ><? echo $rows['tab_title']; ?></a></li>
<?php }} ?>
A single = is an assignment operator in php. So php thinks you are saying "Declare $rows['tab_id'] as 1, does 1 loosely evaluate as true?" ...the answer is "yes", so the condition always returns true. (This is the same logic occurring in the while loop on the previous line.)
To make a loose comparison (that is all that is needed) you merely need to add one more = to make ==.
Further advice is that your snippet can be written more D.R.Y. (Don't Repeat Yourself). You are only modifying class="active" so there is no need to rewrite the entire <li> tag.
Suggested code:
while($rows = mysqli_fetch_array($result)){
<li<?php if($rows['tab_id'] == 1) echo ' class="active"'; ?>><a href="#tab<? echo $rows['tab_id']; ?>"
role="tab" data-toggle="tab" ><? echo $rows['tab_title']; ?></a>
</li>
<?php } ?>
or
while($rows = mysqli_fetch_array($result)){
echo "<li",($rows['tab_id'] == 1 ? ' class="active"' : ''),">";
echo "<a href=\"#tab{$rows['tab_id']}\" role=\"tab\" data-toggle=\"tab\" >{$rows['tab_title']}</a>";
echo "</li>";
}
<?php
while($rows = mysqli_fetch_array($result)){
if ($rows['tab_id'] ==1) { ?>
<li class="active"><a href="#tab<? echo $rows['tab_id']; ?>"
role="tab" data-toggle="tab" ><? echo $rows['tab_title']; ?></a>
</li>
<?php } else { ?>
<li><a href="#tab<? echo $rows['tab_id']; ?>" role="tab" data-
toggle="tab" ><? echo $rows['tab_title']; ?></a></li>
So I have a lot of dynamic PHP webpages in my current project and am wondering how to deal with logged in/not logged in users. Various components throughout the pages are switched for logged in users. Some are entire divs, some just a couple words here and there. Some pages may ultimately have 10+ components like this.
I have previously read that having PHP sprinkled throughout a page can degrade performance, as well as echoing HTML in php, both of which are frequent in my project because of this issue.
I am wondering if there is some trick here to avoiding this?
Here is one example, which shows that some of the lengthiness of some embedded HTML scripts:
<?php
if (isset($_SESSION['sess_username']) and $_SESSION['sess_username'] != '') {
echo '<div class="logged-user">';
echo '<div class="btn-group">';
echo '<a href="#" class="btn btn-link dropdown-toggle" data-toggle="dropdown">';
echo '<img src="assets/img/user-avatar.png" alt="User Avatar" />';
echo '<span class="name">' . $sess_username . '</span>';
echo '<span class="caret"></span>';
echo '</a>';
echo '<ul class="dropdown-menu" role="menu">';
echo '<li>';
echo '<a href="#">';
echo '<i class="fa fa-user"></i>';
echo '<span class="text">Profile</span>';
echo '</a>';
echo '</li>';
echo '<li>';
echo '<a href="#">';
echo '<i class="fa fa-cog"></i>';
echo '<span class="text">Settings</span>';
echo '</a>';
echo '</li>';
echo '<li>';
echo '<a href="#">';
echo '<i class="fa fa-power-off"></i>';
echo '<span class="text">Logout</span>';
echo '</a>';
echo '</li>';
echo '</ul>';
echo '</div>';
echo '</div>';
} else {
echo '<p><span>Log In</span></li></p>';
}
?>
One option I thought of as far as performance would be essentially having code for two pages, and just running an if/else at the top of the page, and then direct the user to the proper page. This would avoid having as many if/else statements throughout the page, although it wouldn't necessarily reduce the amount of PHP sprinkled in the page.
Sincere thanks for any help!
Also, if anyone knows how to easily format code to pull-left in SO, I would love to know. I am sure it looks pretty crappy in my posts.
You can just close the PHP tags like so:
<?php if (isset($_SESSION['sess_username']) and $_SESSION['sess_username'] != ''): ?>
<div class="logged-user">
.. more html ..
</div>
<?php endif; ?>
First, you don't need to echo the html.
<?php if (isset($_SESSION['sess_username']) and $_SESSION['sess_username'] != '') { ?>
<div class="logged-user">
<div class="btn-group">
<a href="#" class="btn btn-link dropdown-toggle" data-toggle="dropdown">
<img src="assets/img/user-avatar.png" alt="User Avatar" />
<span class="name"><?php echo $sess_username;?></span>
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li>
<a href="#">
<i class="fa fa-user"></i>
<span class="text">Profile</span>
</a>
</li> ... </ul>
</div>
</div>
<?php } else { ?>
<p><span>Log In</span></li></p>
<?php } ?>
Second, if you have several pages with several content areas accessible only to logged in users, can you redesign the site and simply load a logged in version of the page with the proper components? Another option might be to set an html class as a variable.
Ex:
if (isset($_SESSION['sess_username']) and $_SESSION['sess_username'] != '') {
//user is logged in, set authorized variable:
$component_authorized = 'show';
} else {
$component_authorized = 'hide';
}
..
<div id="some_content">
<div id="everyone_see_content">...</div>
<div id="only_auth_user" class="<?php echo $component_authorized;?>"><!-- Auth User content --></div>
<div class="other_stuff">
<!--everyone sees here-->
<ul class="my_class <?php $component_authorized; ?>">
<!-- Only Auth User Sees this list-->
</ul>
</div>
Then just make sure your css has the .hide {display: none;}
The last recommendation is some java use which is a bit lengthy and unnecessary in my opinion.
I'm having a bit of trouble trying to get my head around some php code.
To explain:
I have a navbar made from bootstrap.
I want this nav bar to change it's active class depending on the page.
I have a subnav within the navbar with an li class of 'dropdown'.
When this page is active this li class wants to change to 'dropdown active'
When other pages are active, they just want a simple class of 'active'.
My code is as follows:
PHP:
$pageLoc = 'where';
$nav_items = array('index'=>'Home', 'where'=>'Where?', 'appeals'=>'Current Appeals', 'news'=>'Latest News', 'events'=>'Events', 'dontate'=>'Dontate', );
$nav_sub = array('africa'=>'Africa', 'bangladesh'=>'Bangladesh', 'gaza'=>'Palestine/Gaza', 'kashmir'=>'Kashmir', 'pakistan'=>'Pakistan', 'uk'=>'United Kingdom' );
foreach ($nav_items as $nav_href=>$nav_title) {
if ($pageLoc == $nav_href) && ($pageLoc == 'where') {
echo '<li class="dropdown active">' . $nav_title . '</li>';
}
elseif ($pageHref == $nav_href) && ($pageLoc == 'no') {
echo '<li class="dropdown">' . $nav_title . '</li>';
}
elseif ($pageHref == $nav_href) {
echo '<li class="active">' . $nav_title . '</li>';
}
else {
echo '<li>' . $nav_title . '</li>';
}
}
Navbar:
<ul class="nav pull-right">
<li class="pull-right">
<a class="btn-danger" href="donate"><i class="icon-medkit"> DONATE!</i></a>
</li>
</ul>
<ul class="nav pull-right">
<li class="">
Home
</li>
<li class="dropdown">
<a href="../where/" class="dropdown-toggle disabled" data-toggle="dropdown">
Where?
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li class="nav-header">Where we operate</li>
<li class="divider"></li>
<li>Africa</li>
<li>Bangladesh</li>
<li>Palestine/Gaza</li>
<li>Kashmir</li>
<li>Pakistan</li>
</ul>
</li>
<li class="">
Current Appeals
</li>
<li class="">
Latest News
</li>
<li class="">
Events
</li>
</ul>
I am aware that this php is generating a syntax error. I am no pro unfortunately! :( This is
what I originally had:
foreach ($nav_items as $nav_href=>$nav_title) {
if ($pageHref == $nav_href) {
echo '<li class="active">' . $nav_title . '</li>';
}
else {
echo '<li>' . $nav_title . '</li>';
}
}
You've written:
if ($pageLoc == $nav_href) && ($pageLoc == 'where')
It should say:
if ($pageLoc == $nav_href && $pageLoc == 'where')
On a more general note, the absence of detailed debugging information is a pain, but there are workarounds. For example, if you delete half of the code and try to run it again*, does it still give a syntax error? If so, delete a bit more and see what happens; if not, undelete some and see if it works. Keep trying this and narrowing it down until you find where the error is.
*(obviously, don't delete in such a way that you create syntax errors; for example, if you delete the end of an if clause including the }, you'll get non-matching brackets.)