What i am trying to build is next. Fetch all my menu categories and display them, then fetch all subcategories for each category special all display it also. I hope you understand what i want and saying. I got lost in code and don't now how to do this. Here is my code, hope you can help me.
Here is table structure.
subcategory table
| id | subcategory_name | id_category |
category table
| id | category |
id_category is connected with id in category table
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-left">
<?php
$pdo = connect();
$sql = "SELECT * FROM category";
$query = $pdo->prepare($sql);
$query->execute();
$row = $query->fetchAll();
foreach ($row as $rs) { ?>
<li class="dropdown"><?php echo $rs['category'] ?><span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<?php
$sql = "SELECT subcategory.subcategory_name, subcategory.id_category, category.id, category.category
FROM subcategory
INNER JOIN category
WHERE subcategory.id_category = category.category";
$query = $pdo->prepare($sql);
$query->execute();
$subcat = $query->fetchAll();
foreach ($subcat as $sub) { ?>
<li><?php echo $sub['subcategory_name'] ?></li>
<?php } ?>
</ul>
</li>
<?php } ?>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>Logout</li>
</ul>
</div><!-- /.navbar-collapse -->
</div>
I think you just didn't understand the INNER JOIN sql select statement. You have to declare the relation of the second table with the first one:
SELECT column_list
FROM t1
INNER JOIN t2 ON join_condition1
WHERE where_conditions;
Join condition in where you want to put the "subcategory.id_category = category.category" part of your query. Maybe leave out the actual WHERE clause?
Hope it helps.
Look here
Edit:
WHat I was proposing pointed to rewrite the complete code to do it in one query. But your code could be simplified like this quickly using the already captured variable with the first sql query:
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-left">
<?php
$pdo = connect();
$sql = "SELECT * FROM category";
$query = $pdo->prepare($sql);
$query->execute();
$row = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($row as $rs) { ?>
<li class="dropdown"><?php echo $rs['category'] ?><span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<?php
$sql = "SELECT subcategory_name, id_category
FROM subcategory
WHERE id_category = '".$rs['id']."'";
$query = $pdo->prepare($sql);
$query->execute();
$subcat = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($subcat as $sub) { ?>
<li><?php echo $sub['subcategory_name'] ?></li>
<?php } ?>
</ul>
</li>
<?php } ?>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>Logout</li>
</ul>
</div><!-- /.navbar-collapse -->
</div>
Related
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...
I have a a navigation bar and one of the nav items is a dropdown with sub categories. Only the subcategories are being pulled from the database by using a while loop.
When clicking on one of the dropdown items they will be redirected to dancerProfile.php.
I want dancerProfile.php to pull the menu item name from the other pages.
html
<li class="li-spacing">Home</li>
<li class="dropdown li-spacing">
<a class="dropdown-toggle" data-toggle="dropdown">Dancers<b class="caret"></b></a>
<ul class="dropdown-menu">
<?php
$dancers = "SELECT `dancer_name` FROM `dancers` WHERE name = '$name'";
$dres = mysqli_query($con,$dancers);
//if($res==FALSE){
//die('there was an error running query [' . $con->error . ']');
// }
while($data=mysqli_fetch_array($dres)){
$dancerName = $data['dancer_name'];
foreach ($dancerName as $DANCER){
echo '
<li>'.$data["dancer_name"].'</li>
<li class="divider"><hr></li>
';
}
}
?>
<li>Add New</li>
</ul>
</li>
This works well as all dancers appear in the dropdown.
What I want is that when I click on dancerA the dancerProfile.php will show dancerA information. And when I click on dancerB it will show dancerB info, etc.
But it will only show the last dancer's information no matter which name I click on.
dancerProfile.php
<div class="col-sm-6 dancerInfo">
<div class="row">
<div class="col-sm-6">
<div class="dancerName"><?php echo $dancerName;?></div>
</div>
So When I click on dancerA on the nav bar in any other page, in dancerProfile.php $dancerName should print dancerA. And it should print dancerB if I clicked on dancerB from the nav bar.
but it is only printing dancerB no matter which link I click.
I am using bootstrap. Can anyone help me?
EDIT
Here's an update of what my code looks like now.
<li class="li-spacing">Home</li>
<li class="dropdown li-spacing">
<a class="dropdown-toggle" data-toggle="dropdown">Dancers<b class="caret"></b></a>
<ul class="dropdown-menu">
<?php
$dancers = "SELECT `dancer_name`, `id` FROM `dancers` WHERE name = '$name'";
$dres = mysqli_query($con,$dancers);
$dancerId= 'id';
}
while($data=mysqli_fetch_array($dres)){
$dancerName = $data['dancer_name'];
echo '
<li>'.$data["dancer_name"].'</li>
<li class="divider"><hr></li>
';
}
?>
<li>Add New</li>
</ul>
</li>
And dancerProfile.php:
<?PHP
if(isset($_GET['id'])) {
$dancerId=$_GET['id'];
$dancerquery = "SELECT `dancer_name` FROM `dancers` WHERE id = " . $_GET['id'] . ";";
$dancer_res = mysqli_query($con,$dancers);
if($dancer_res){
$DANCER='dancer_name';
}
}
?>
<div class="col-sm-6 dancerInfo">
<div class="row">
<div class="col-sm-6">
<div class="dancerName"><?php echo " $DANCER ";?></div>
</div>
I also forgot to mention that this navigation is also on dancerProfile page. So all of the code I am providing is on dancerProfile page. I don't know if that matters
My database table
You need pass dancer id or which is unique in your dancer table. something like given below.
<li>'.$data["dancer_name"].'</li>
And now go to dancerProfile.php and try something like this.
if (isset($_GET['dancer_id'])) {
$dancer_id=$_GET['dancer_id'];
//your query
}
Your full code:
<li class="li-spacing">Home</li>
<li class="dropdown li-spacing">
<a class="dropdown-toggle" data-toggle="dropdown">Dancers<b class="caret"></b></a>
<ul class="dropdown-menu">
<?php
$dancers = "SELECT `dancer_name`, `id` FROM `dancers` WHERE name = '$name'";
$dres = mysqli_query($con,$dancers);
$dancerId= 'id';
}
while($data=mysqli_fetch_array($dres)){ ?>
$dancerName = $data['dancer_name'];
<li><?php echo $data['dancer_name']; ?>'</li>
<li class="divider"><hr></li>
<?php } ?>
<li>Add New</li>
</ul>
</li>
Your dancerProfile.php should be
<?PHP
if(isset($_GET['id'])) {
$dancerId=$_GET['id'];
$dancerquery = "SELECT `dancer_name` FROM `dancers` WHERE id = '$dancerId'";
$dancer_res = mysqli_query($con,$dancerquery);
$data=mysqli_fetch_array($dancer_res);
}
?>
<div class="col-sm-6 dancerInfo">
<div class="row">
<div class="col-sm-6">
<div class="dancerName"><?php echo $data['dancer_name'];?></div>
</div>
You are currently overriding the value of $DANCER with each iteration, so the last will always be the used value.
Just change your loop a bit:
while($data=mysqli_fetch_array($dres)){
echo '<li>'.$data['dancer_name'].'</li>';
}
So this is my code:
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">WebSiteName</a>
</div>
<ul class="nav navbar-nav">
<li class="active">Home</li>
<?php
$dbconn= new PDO('sqlite:negozio.db');
$sqlcate = "SELECT * FROM categoria";
foreach($dbconn->query($sqlcate) as $row) { ?>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><?php echo $row['des_categoria']; ?> <span class="caret"></span></a>
<ul class="dropdown-menu">
<?php
$sqltipocate = "SELECT tipo.des_tipo FROM tipo, categoria, tipo_cate WHERE tipo_cate.id_cate = categoria.id_categoria AND tipo_cate.id_tipo = tipo.id_tipo AND tipo_cate.id_categoria = " . $row['id_categoria'] . " "" ";
foreach($dbconn->query($sqltipocate) as $row1) { ?>
<li><?php echo $row1['des_tipo']; ?></li>
<?php } ?>
</ul>
</li>
<?php } ?>
</ul>
</div>
</nav>
Everything is working fine until $sqltipocate blabla...
This error always appears:
syntax error, unexpected T_CONSTANT_ENCAPSED_STRING
Can someone help me?
It is concatenation problem as regarded in previous answers. I can add something may make your life easier. It is sprintf
Your sql query string will be the format parameter of sprintf as follows:
$sqltipocate = sprintf("SELECT tipo.des_tipo FROM tipo, categoria, tipo_cate WHERE tipo_cate.id_cate = categoria.id_categoria AND tipo_cate.id_tipo = tipo.id_tipo AND tipo_cate.id_categoria = %d", $row['id_categoria']);
Use curly braces.
Example:
$id = 1;
$sql = "SELECT * FROM something WHERE id = {$id}";
echo $sql;
//SELECT * FROM something WHERE id = 1
Link to code: http://codepad.org/V9QasGHH
Store your $row['id_categoria'] in variable like
$id = $row['id_categoria'];
Then put $id in query like:
$sqltipocate = "SELECT tipo.des_tipo FROM tipo, categoria, tipo_cate WHERE tipo_cate.id_cate = categoria.id_categoria AND tipo_cate.id_tipo = tipo.id_tipo AND tipo_cate.id_categoria = '".$id."'";
See this tipo_cate.id_categoria = ' " $id " '
I'm trying to create a drop down menu which works with pure css. This works perfectly in HTML without any issues, but when I try to take the information out of my SQL tables, I seem to hit hurdles. I will try to explain the problem as concisely as I can.
HTML without PHP/Mysqli
<div id='menu'>
<ul>
<li><a href='#'><span>Home</span></a></li>
<li cl ass='active has-sub'>
<a href='#'><span>Products</span></a>
<ul>
<li class='has-sub'>
<a href='#'><span>Product 1</span></a>
<ul>
<li><a href='#'><span>Sub Product</span></a></li>
</ul>
</li>
</ul>
</li>
<li><a href='#'><span>About</span></a></li>
<li class='last'><a href='#'><span>Contact</span></a></li>
</ul>
</div>
HTML with PHP/Mysqli
<div id="menu">
<ul>
<li class="current">Main</li>
<li>About Us</li>
<li>Projects</li>
<li class="has-sub">Properties
<ul>
<?php
require_once 'connect.php';
$qry = db_select("select city as city,name from property a left join area b on a.area_id=b.id left join city c on b.city_id=c.id group by city");
foreach ($qry as $row) {
echo "<li class='has-sub'><a href='#'><span>".$row['city']."</span></a></li>";
}
echo "<ul>";
$qry = db_select("select city as city,name from property a left join area b on a.area_id=b.id left join city c on b.city_id=c.id ");
foreach ($qry as $row) {
echo "<li><a href='#'><span>".$row['name']."</span></a></li>";
}
?>
</ul>
<li>Contacts</li>
</ul>
</div>
</div>
This shows all the cities correctly but all properties (name) are not shown as sub menus but just after all the cities.
I know what the issue is but don't know how to solve it.
Basically because I have a foreach it is making multiple (or none) <UL> tags when I need only one for each set. I am not sure how to do this. Hope somebody can help.
I haven't put the CSS because I don't think it is relevant here, but if required I can also put that.
It's a bit unclear about what menu structure you actually want, but it's sure that you are missing couple of closing tags.
<li class="has-sub">Properties
<ul>
<?php
require_once 'connect.php';
$qry = db_select("select city as city,name from property a left join area b on a.area_id=b.id left join city c on b.city_id=c.id group by city");
foreach ($qry as $row)
{
echo "<li class='has-sub'><a href='#'><span>".$row['city']."</span></a></li>";
}
echo "<ul>"; //this seems the issue, should be </ul></li>
?>
Still, I'm a bit unclear about the actual menu structure you are trying to achieve. But try to point out the closing tags properly, that should solve your issue.
Try this, hope it helps.
<ul>
<?php
require_once 'connect.php';
$qry = db_select("select city as city,name from property a left join area b on a.area_id=b.id left join city c on b.city_id=c.id group by city");
foreach ($qry as $row) : ?>
<li class='has-sub'><a href='#'><span><?php echo $row['city']; ?></span></a>
<ul>
<li><a href='#'><span><?php echo $row['name']; ?></span></a></li>
</ul>
</li>
<?php endforeach; ?>
</ul>
Not sure if this is the right way to do it but I found an answer by making sure the first record of each set shows a <UL> but not the rest.
Basically this is done by the following
variable as true
if variable true then "do something" variable is false
else "do something else"
I have also added classes in the UL and Li but that is not relevant.
This works but I am not sure if this is the best way to do it. I haven't tried the other ways, but I would like an opinion whether this is a good way as it is working.
<li class="has-sub"><span>Properties</span>
<?php
$qry=db_select("select distinct city from city a join area b on a.id=b.city_id join property c on b.id=c.area_id");
$first=true;
foreach ($qry as $row)
{
$city=$row['city'];
if ($first)
{
?>
<ul>
<li class='has-sub'><a href='#'><span><?php echo $row['city']; ?></span></a>
<?php
$first=false;
}else{
?>
<li class='has-sub'><a href='#'><span><?php echo $row['city']; ?></span></a>
<?php
}
$city=$row['city'];
$qry=db_select("select city,a.id as id,name from property a left join area b on a.area_id=b.id left join city c on b.city_id=c.id where city='$city' ");
$first=true;
foreach ($qry as $row)
{
if ($first)
{
?>
<ul class="drop_ul"><li class="drop_col"><span><?php echo $row['name']; ?></span></li>
<?php
$first=false;
}
else{
?>
<li class="drop_col"><span><?php echo $row['name']; ?></span></li>
<?php
}}?>
</ul>
</li>
<?php
}
?>
</ul>
there is some errors :
- 2 against 1
- there is no for the item Properties
- the nomber of < number of
let me now about the structure of your menu, is it like this?
Main
About Us
Projects
Properties >>
county >>
name 1
name 2
...
name i
The drop down menu only show the first loop with its first item from database and then every items of the first item shown in the first loop. There is no second item listed of the first loop. Any idea to help me with this loop???
<ul class="pureCSSMenum">
<li class="pureCssMenui">E-Policy
<ul class="pureCssMenum">
<?
$sql = "SELECT * FROM e_category";
$result = mysql_query($sql);
while ($epolicy = mysql_fetch_array($result)) {
?>
<li class="pureCssMenui"><a class="pureCssMenui" href="#"><?=$epolicy['e_cat_name']?></a>
<ul class="pureCssMenum">
<?php
$sql = "SELECT * FROM e_subcategory";
$result = mysql_query($sql);
while ($epolicysub = mysql_fetch_array($result)) {
?>
<li class="pureCssMenui"><a class="pureCssMenui" href="#"><?=$epolicysub['e_subcat_name']?></a></li>
<? } ?>
</ul>
<? } ?>
</li>
</ul>
</li>
</ul>
You must use two result variables $result1, $result2 for outer and inner variable, rest all is fine i think.
Hope this will help