Using the same foreach multiple times - php

I'm currently working on a php script and stuck at this part. I have a database table which I want to display information from each row. I have two dropdown menus which I want to have the exact same names with just with a different url. I'm assuming this is possible, and I'm doing something wrong, as I'm not that advanced with php.
I found this question that was similar but didn't seem to see anything that helped much.
Use same foreach multiple times
Here is what I currently have
Top of page
<?php
require("common.php");
if(empty($_SESSION['user']))
{
header("Location: login.php");
die("Redirecting to login.php");
}
$header = "SELECT id, location FROM table";
try
{
$headerstmt = $db->prepare($header);
$headerstmt->execute();
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}
?>
Then here is the section with the foreach loops
<ul class="nav navbar-nav">
<li class="dropdown <?php if ($page == 'view') {echo 'active';} ?>">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">View <b class="caret"></b></a>
<ul class="dropdown-menu">
<?php foreach ($headerstmt->fetchAll() as $hrow) { ?>
<li><?php echo $hrow['location']; ?></li>
<?php } ?>
</ul>
</li>
<li class="dropdown <?php if ($page == 'edit') {echo 'active';} ?>">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Edit <b class="caret"></b></a>
<ul class="dropdown-menu">
<?php foreach ($headerstmt->fetchAll() as $hrow) { ?>
<li><?php echo $hrow['location']; ?></li>
<?php } ?>
</ul>
</li>
</ul>
The first foreach loop works correctly, however the second one is blank.
Thanks in advance if anyone is able help.

You should store the result of $headerstmt->fetchAll() in a variable and then use the resulting variable for the foreach loops.
$results = $headerstmt->fetchAll();
foreach( $results as $row ) {
}
foreach( $results as $row ) {
}
foreach( $results as $row ) {
}

Related

How to know I'm in the first cycle of fetchArray() loop

I want to print an attribute (i.e. active) on the first element of an array.
The ugly way is to use a variable:
<ul class="nav nav-pills">
<?php $firstItem = true; ?>
<?php while ($row = $res_sections->fetchArray()) { ?>
<li class="nav-item">
<a class="nav-link<?php if ($firstItem) echo ' active' ?>" data-toggle="pill" href="#nav<?= $row['section']?>"><?php echo "{$row["section"]}"?></a>
</li>
<?php $firstItem = false; ?>
<?php } ?>
</ul>
I wonder if there's something more elegant.
Is there a way to know if $row is the first element (or any) of the fetchArray() result?
EDIT
Here where fetchArray() comes from:
$db = new SQLite3("/db.sqlite");
$sql_sections = "SELECT DISTINCT section FROM settings";
$res_sections = $db->query(SQLite3::escapeString($sql_sections));

How I can make drop down menu from my categories mysql table only show if parent_id is not 0

So hey there as the title said I am looking for away to make my categories with subcategories. I been looking in stackoverflow for what I need but none has help me of the examples..
Here is how my table look like
So I know what I want and what I need but I have no idea how I can do that possible
I have to SELECT * FROM categories ORDER by position ASC
I have to check if parent_id is bigger then 0.
I have to remove the parent_id from my navbar and show them only under the category name where it should be by dropdown menu .
But I have no idea how I could do all of that ..
Here is how I am selecting only my categories and display them
$catsq = mysqli_query($con,"SELECT * FROM categories ORDER by position ASC");
while($catinfo=mysqli_fetch_assoc($catsq)) {
echo '
<li class="nav-item'.(isset($_GET["cat"]) && $_GET["cat"]==$catinfo["id"] ? " active" : "").'">
<a class="nav-link" href="./index.php?cat='.$catinfo["id"].'">'.$catinfo["name"].'</a>
</li>
';
}
and it's look like this
<ul class="nav navbar-nav">
<li class="nav-item">
<a class="nav-link" href="cat=1">TestCat</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cat=2">TestCat2</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cat=3">TestSub</a>
</li>
</ul>
but I want It to look like this
<ul class="nav navbar-nav">
<li class="">TestCat</li>
<li class="dropdown ">
//TestCat2 have to doing nothing always.
TestCat2</i>
<ul class="dropdown-menu">
<li><a class="nav-link" href="cat=3">TestSub</a></li>
</ul>
</li>
</ul>
when the parent_id is more then 0..
If anyone can help me with this would be great..
Thanks to everybody.
There are several approaches you can take:
Build an array
Nested queries
Recursion
Array
This approach builds a data structure that you can iterate through in your view. Working example
<?php
// get db connection...
// create categories array
$stmt = mysqli_query($con, "SELECT * FROM categories ORDER BY position ASC");
while( $row = mysqli_fetch_assoc($stmt)) {
// $category[ $row['parent_id] ][ $row['id'] ] = $row; // use if you need to access other fields in addition to name
$category[ $row['parent_id] ][ $row['id'] ] = $row['name'];
}
// other php stuff...
?>
<html>
... snip ...
<ul class="nav navbar-nav">
<?php foreach($category[0] as $id => $name): ?>
<?php if( isset( $category[$id]) ): ?>
<li class="dropdown ">
<?= $name ?>
<ul class="dropdown-menu">
<?php foreach($category[$id] as $sub_id => $sub_name): ?>
<li><a class="nav-link" href="?cat=<?= $sub_id ?>" ><?= $sub_name ?></a></li>
<?php endforeach; ?>
</ul>
</li>
<?php else: ?>
<li class="">
<?= $name ?>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
Nested Queries
This method is easiest to display using an imaginary class that does all the sql stuff behind the scenes. For the sake of argument, we will assume a class Category that has a method named listByParent($parent_id) which returns a list of rows having the designated parent_id.
<?php
$cat = new Category();
$topLevel = $cat->listByParent(0);
?>
<html>
... snip ...
<ul class="nav navbar-nav">
<?php foreach( $topLevel as $topRow ): ?>
<!-- note, this method is run on every iteration of top level categories -->
<?php $subRows = $cat->listByParent($topRow['id']) ?>
<?php if( count($subRows)): ?>
<li class="dropdown ">
<?= $topRow['name'] ?>
<ul class="dropdown-menu">
<?php foreach($subRows as $row): ?>
<li><a class="nav-link" href="?cat=<?= $row['id'] ?>" ><?= $row['name'] ?></a></li>
<?php endforeach; ?>
</ul>
</li>
<?php else: ?>
<li class="">
<?= $topRow['name'] ?>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
Recursion
Using recursion would allow you to have “unlimited” levels of subcategories. However, it’s a level of complexity that does not seem warranted in this case. But should you want to pursue it, note that the best way to approach it would be to make a template for the html that could be accessed programatically, with $cat->findByParent() being a key player...

Categories are repeating for each subcategory

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'];?>

Link to blank page and addition new condition in php code

I'd like to add condition to my code so that after click on label it link me to other page. Now this code link to other article on the website. So I guess what should I add to get from my label to other page.
Thank you for answers!
My code is below:
<ul class="nav nav-tabs aboutUsTabs nav-justified" role="tablist">
<?php foreach ($this->items as $key=>$item ){
if($item['children']){ ?>
<li role="presentation" class="<?php if($item['menu']->id==$this->pageId || $item['menu']->id==$this->parentId){ echo 'active'; } ?>"><?php echo $item['menu']->title;?></li>
<?php }else{ ?>
<li role="presentation" class="<?php if($item['menu']->id==$this->pageId || $item['menu']->id==$this->parentId){ echo 'active'; } ?>"><?php echo $item['menu']->title;?></li>
<?php } ?>
<?php } ?>
</ul>
All this start/stop of PHP code hurts my eyes! Anyways, linking to other pages is done with tags. Not quite sure I understand your question, but you could (if you mean labels for form elements) do something like this;
<label for=""> Something Meaningful </label>
I'm sorry, but I took the liberty to clean up your code a little. Hopefully this will make it more readable;
<ul class="nav nav-tabs aboutUsTabs nav-justified" role="tablist">
<?php
foreach ($this->items as $key=>$item ){
$active = NULL;
if($item['menu']->id==$this->pageId || $item['menu']->id==$this->parentId){
$active = 'active';
}
$menu = NULL;
if($item['menu']->id==$this->pageId || $item['menu']->id==$this->parentId){
$menu = 'active';
}
if($item['children']){
echo'<li role="presentation" class="'.$active.'">
'.$item['menu']->title.'
</li>';
}else{
echo'<li role="presentation" class="'.$menu.'">
'.$item['menu']->title.'
</li>';
}
}
?>
</ul>
For your comment question, if you know what item needs a different value, it could be the title f.ex. then you can check against that value and change the output of your element. Maybe something like;
if($item['children']){
if($item['title'] == 'Unique Identifier for your element') {
// In here you could manipulate the output of that one item you want to exclude/change
} else {
// Your normal output
echo'<li role="presentation" class="'.$active.'">
'.$item['menu']->title.'
</li>';
}else{ ... }
And even better would be to perform the check beforehand, so maybe something like;
$link = '#about-us-page-'.$item['menu']->id;
if($item['title'] == "That identifier") {
$link = 'somethingElse';
}
and then change the value of your href tag to;
'.$item['menu']->title.'

creating class active dynamically in php

I am creating a menu dynamically based on the categories registered on the dataBase, What I need is:
When someone click in the link, this option should have the css class 'active', showing in with page the user is and even the pages are created dynamically.
I have no idea how to do this because I am php student and I couldn't find this information in google for "Dynamically menus" Thank you very much.
<nav class="menu">
<ul class="list">
<li class="line"><a id="item" href="index.php">Home</a></li>
<?php
$categories = $db->select("select * from tbl_category");
if($categories){
while ($result = $categories->fetch_assoc()){
echo <<<HTML
<li id="line" ><a class="item" href="categories.php?category=$result[id]">$result[name]</a></li>
HTML;
}
}
?>
</ul>
<nav>
First of all, you're looping through that while loop and adding the id of "line" to each and every <li> element. I suggest you create unique id's for each list item. I don't necessary advocate using the code the way you have it, just as an example, here's your code edited to do just that:
if($categories){
$i = 1;
while ($result = $categories->fetch_assoc()){
$i++;
echo <<<HTML
<li id="line$i" ><a class="item" href="categories.php?category=$result[id]">$result[name]</a></li>
HTML;
}
}
Then when someone clicks on your link, just use jQuery with something like this:
$(".item").click(function() {
$(this).parent('li').addClass('active');
});
Try something like that:
<nav class="menu">
<ul class="list">
<li class="line"><a id="item" href="index.php">Home</a></li>
<?php
$current_page = isset($_GET['category']) ? $_GET['category']: -1;
$categories = $db->select("select * from tbl_category");
if($categories){
while ($result = $categories->fetch_assoc()){
echo '<li id="line">';
if($result['category'] === $current_page) {
// If we're currently in the active page then add the active class to the <a>
echo '<a class="item active" href="categories.php?category='. $result[id] .'">';
} else {
echo '<a class="item" href="categories.php?category='. $result[id] .'">';
}
echo $result['name'];
echo '</a>';
echo '</li>';
}
}
?>
</ul>
<nav>
Thank you all for help, based on your code, I solved doing this:
menu.php:
<nav class="menu" id="menu">
<ul id="list" class="list">
<li id="line" class="<?php if($presentPage == '0')echo 'active';?>"><a id="item" class="item" href="index.php">Home</a></li>
<?php
function checked($pp, $id){
if($pp == $id){
$status = 'active';
return $status;
}
}
$query = "select * from tbl_category";
$category = $db->select($query);
if($category){
while ($result = $category->fetch_assoc()){
echo "
<li id='line' class='".checked($presentPage, $result['id'])."'><a id='item' class='item' href='categories.php?category=".$result['id']."'>".$result['name']."</a></li>
";//end echo
}//end while
}//end if
?>
</ul>
</nav>
In my index.php:
<?php $presentPage = 0;?>
<?php require_once 'header.php';?>
<?php require_once 'menu.php';?>
and in my categories.php:
<?php
if (!isset($_GET['category']) || $_GET['category'] == NULL) {
$presentPage = 0;
}else{
$presentPage = intval($_GET['category']);//just to make sure that the variable is a number
}
?>
<?php require_once 'header.php';?>
<?php require_once 'menu.php';?>
///...my code...
and in my CSS of course:
.active{
background: linear-gradient(#821e82, #be5abe);
}
Thats is working perfectly for me, Thank for all help.

Categories