I have a website where the navbar is fully dynamic, in which you can add multiple children as you want! The logic is fine, but I just need to add a divider to separate them from each other according to design requirements. Now the thing is.... The <li class="divider"></li> works but it also adds the divider to the last index of every iteration of navbar menu as it is self explanatory. I don't want to add a divider to the last iteration of loop!
Here's my code:
<ul class='nav navbar-nav'>
<li><img id="navbar-home" src="images/navbar_home.png" class="img-responsive"></li>
<?php
function display_children($parent, $level) {
$conn=mysqli_connect("localhost","root","") or die ("not connected");
mysqli_select_db($conn,"occ")or die ("not selected");
$result = mysqli_query($conn,"SELECT a.id, a.title,a.page_id, Deriv1.Count FROM `menu` a LEFT OUTER JOIN (SELECT parent, COUNT(*) AS Count FROM `menu` GROUP BY parent) Deriv1 ON a.id = Deriv1.parent WHERE a.parent=" . $parent);
while ($row = mysqli_fetch_array($result)) {
if ($row['Count'] > 0) {
echo "<li><a href='" . base_url().'pages/'.$row['page_id'] . "'>" . strtoupper(str_replace('-', ' ', clean($row['title']) )). "<span class=caret></span></a>";
echo "<ul class=\"dropdown-menu\">";
display_children($row['id'], $level + 1);
echo "</ul>";
echo "</li>";
echo "<li class=\"divider\"></li>";
} elseif ($row['Count']==0) {
echo "<li><a href='" . base_url().'pages/'.$row['page_id'] . "'>" . strtoupper(str_replace('-', ' ', clean($row['title'])) ) . "</a></li>";
echo "<li class=\"divider\"></li>";
} else;
}
}
function clean($string) {
return preg_replace('/[^A-Za-z0-9\-]/', ' ', $string); // Removes special chars.
}
display_children(0, 1);
?>
</ul>
Here is the screenshot of the issue, in case someone wants clarification:
You could use pure CSS to do this, with the last-child selector:
.nav .dropdown-menu .divider:last-child {
display: none;
}
To do it with php, you could instead of echoing all the menu items, add it to an array, and check if the last item is equal to the divider. Then your code would look something like this:
function display_children($parent, $level) {
$conn=mysqli_connect("localhost","root","") or die ("not connected");
mysqli_select_db($conn,"occ")or die ("not selected");
$result = mysqli_query($conn,"SELECT a.id, a.title,a.page_id, Deriv1.Count FROM `menu` a LEFT OUTER JOIN (SELECT parent, COUNT(*) AS Count FROM `menu` GROUP BY parent) Deriv1 ON a.id = Deriv1.parent WHERE a.parent=" . $parent);
$returnHtml = array();
while ($row = mysqli_fetch_array($result)) {
if ($row['Count'] > 0) {
$returnHtml[] = "<li><a href='" . base_url().'pages/'.$row['page_id'] . "'>" . strtoupper(str_replace('-', ' ', clean($row['title']) )). "<span class=caret></span></a>";
$returnHtml[] = "<ul class=\"dropdown-menu\">";
display_children($row['id'], $level + 1);
$returnHtml[] = "</ul>";
$returnHtml[] = "</li>";
$returnHtml[] = "<li class=\"divider\"></li>";
} elseif ($row['Count']==0) {
$returnHtml[] = "<li><a href='" . base_url().'pages/'.$row['page_id'] . "'>" . strtoupper(str_replace('-', ' ', clean($row['title'])) ) . "</a></li>";
$returnHtml[] = "<li class=\"divider\"></li>";
} else;
}
if (end($returnHtml === "<li class=\"divider\"></li>")) {
array_pop($returnHtml);
}
return implode('', $returnHtml);
}
function clean($string) {
return preg_replace('/[^A-Za-z0-9\-]/', ' ', $string); // Removes special chars.
}
echo display_children(0, 1);
Related
I have a problem coding the numbers of pages of a pagination.
I will be as simple as possible in detailing what I need to do.
There are N numbers of pages (keep track as $listPages);
I need to show a maximum of 5 pages numbers generated as $listCount "1(current),2,3,4,5 + Next + Last" and keep the pattern with increasing pages (example for page 33 "First + Prev + 31,32,33 (current),34,35 + Next + Last");
$list keep track of the current page;
I written this code for the moment but it doesn't work correctly giving as output (example on page 7 "1,2,3,4,5,6,7(current),8,9 + Next + Last) it works going up, but it keep previous numbers. I hope some could help coding it, thanks!
function ShowPageNumbers($pageUrl, $listPages, $list) {
global $listPagesCount;
foreach (range(1, $listPages) as $listCount) {
//Check if current page
if($listCount == ($list - 1)) {
echo "<li class='current' style='margin:3px;'>";
echo "<span class='pages-nav-item'>" . $listCount . "</span>";
echo "</li>";
$listPagesCount++;
} else {
if (($list - 1) == 1) {
//null
} else {
//echo "<li class='the-prev-page' style='margin:3px;'>";
//echo "<a class='pages-nav-item' href=" . $pageUrl . ($listCount + 4) . " title=" . ($listCount + 4) . ">«</a>";
//echo "</li>";
}
echo "<li style='margin:3px;'>";
echo "<a class='pages-nav-item' href=" . $pageUrl . $listCount . " title=" . $listCount . ">" . $listCount . "</a>";
echo "</li>";
$listPagesCount++;
if($listPagesCount >= 3 && $listPagesCount == $list + 1) {
echo "<li class='the-next-page' style='margin:3px;'>";
echo "<a class='pages-nav-item' href=" . $pageUrl . $listCount . " title=" . $listCount . ">»</a>";
echo "</li>";
echo "<li class='extend' style='margin:3px;'>";
echo "<span class='pages-nav-item'>...</span>";
echo "</li>";
echo "<li class='last-page first-last-pages' style='margin:3px;'>";
echo "<a class='pages-nav-item' href=" . $pageUrl . $listPages . " title='Ultimo'>Ultimo</a>";
echo "</li>";
break;
}
}
}
}
I need after the end of a loop in a recursive function to return the $build variable
This is my code:
$traverse = function ($tree,$build = '') use (&$traverse) {
foreach ($tree as $key=>$menu) {
if (count($menu->children) > 0) {
$build .= "<li ><a href='" . $menu->url . "'>" . $menu->text . "</a><ul>";
$traverse( $menu->children,$build);
$build .= "</ul></li>";
} else {
$build .= "<li ><a href='" . $menu->url . "'>" . $menu->text . "</a></li>";
}
}
};
$traverse($tree );
Regarding my comment u should have:
$traverse = function ($tree) use (&$traverse) {
$build = '';
if (count($menu->children) > 0) {
$build .= "<li ><a href='" . $menu->url . "'>" . $menu->text . "</a><ul>";
$build .= $traverse($menu->children);
$build .= "</ul></li>";
} else {
$build .= "<li ><a href='" . $menu->url . "'>" . $menu->text . "</a></li>";
}
return $build;
};
As u can see u also don't need to pass and use $build as argument to the function.
Also u should check the html code for being valid at the end. Because of it won`t be.
<?php
$query = "SELECT name FROM prodGroups";
$result = mysql_query($query);
$prodGroups = array();
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$prodGroups[] = $row['name'];
}
if (count($prodGroups) == 0) // IF NO PRODUCT GROUPS EXIST
for ($j=1 ; $j<4 ; $j++)
{
echo "<li><a href='#'><span>Empty product group " . $j . "</span></a></li>";
}
else // FOR WHEN PRODUCT GROUPS DO EXIST
foreach ($prodGroups as $aGroup) // CYCLE THROUGH PRODUCT GROUPS
{
echo "<li class='submenu'><a href='#'><span>" . $aGroup . "</span></a>";
$query = "SELECT name FROM products WHERE prodGroup='$aGroup'";
$result = mysql_query($query);
for ($j=0 ; $j<count($prodGroups) ; ++$j)
{
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) // PLACE PRODUCTS INTO AN ARRAY
**{
$products[] = $row['name'];
}**
if (!isset($products)) // IF THERE ARE NO PRODUCTS INSIDE A PRODUCT GROUP
echo "<ul><li><a href='#'><span>No products</span></a></li></ul></li>";
else // FOR WHEN PRODUCT(S) DO EXIST INSIDE A PRODUCT GROUP
{
echo "<ul>";
if(isset($products))
foreach ($products as $item) // CYCLE THROUGH PRODUCTS
{
echo "<li><a href='#'><span>" . $item . "</span></a>";
}
echo "</ul></li>";
}
}
}
?>
Where $products[] = $row['name']; it is carrying ALL the elements, whereas I just want it to carry product names to where they match the prodGroup name? I've tried using unset() to delete array contents in the loop, however this only allows one element in the array per cycle.
Add $products = array();
immediately after:
foreach ($prodGroups as $aGroup) // CYCLE THROUGH PRODUCT GROUPS
{
I tried to rewrite your loop, fixing several issues, most of them minor. I commented my changes. See if this works for you.
foreach ($prodGroups as $aGroup) // CYCLE THROUGH PRODUCT GROUPS
{
echo "<li class='submenu'><a href='#'><span>" . $aGroup . "</span></a>";
$query = "SELECT name FROM products WHERE prodGroup='$aGroup'";
$result = mysql_query($query);
//for loop here has been taken out
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) // PLACE PRODUCTS INTO AN ARRAY
{
$products[] = $row['name'];
}
if (!isset($products)) // IF THERE ARE NO PRODUCTS INSIDE A PRODUCT GROUP
echo "<ul><li><a href='#'><span>No products</span></a></li></ul>";
else // FOR WHEN PRODUCT(S) DO EXIST INSIDE A PRODUCT GROUP
{
echo "<ul>";
//if(isset($products)) - You already checked this..
foreach ($products as $item) // CYCLE THROUGH PRODUCTS
{
echo "<li><a href='#'><span>" . $item . "</span></a></li>"; //Don't forget to close this li
}
echo "</ul>";
}
echo '</li>'; //close li here
unset($products); //unset $products for next loop iteration
}
Of course, please do not use the deprecated mysql extension. See comment by #FreshPrinceOfSO.
This should be a little neater for you to see what I meant by using mysql_num_rows()
<?php
$query = "SELECT name FROM prodGroups";
$result = mysql_query($query);
if( (!$result) || (mysql_num_rows($result) == 0) )// IF NO PRODUCT GROUPS EXIST
{
for ($j=1 ; $j<4 ; $j++)
{
echo "<li><a href='#'><span>Empty product group " . $j . "</span></a></li>";
}
}
else // FOR WHEN PRODUCT GROUPS DO EXIST
{
while($row = mysql_fetch_array($result, MYSQL_ASSOC)) // CYCLE THROUGH PRODUCT GROUPS
{
echo "<li class='submenu'><a href='#'><span>" . $row['name'] . "</span></a>";
$query2 = "SELECT name FROM products WHERE prodGroup='".mysql_real_escape_string($row['name'])."'";
$result2 = mysql_query($query2);
if( (!$result2) || (mysql_num_rows($result2)==0) )
{
echo "<ul><li><a href='#'><span>No products</span></a></li></ul>";
}
else
{
echo "<ul>";
while ($row2 = mysql_fetch_array($result2, MYSQL_ASSOC)) // PLACE PRODUCTS INTO AN ARRAY
{
echo "<li><a href='#'><span>" . $row2['name'] . "</span></a></li>";
}
echo "</ul>";
}
echo "</li>";
}
}
?>
As you can see on http://www.mattmaclennan.co.uk/a2 ... when you hover over "New Motorcycles", it has the array numbers, and not the labels as required. Also, the categories need to be grouped into their IDs. Below is what I have tried.
<?
$output = mysqli_query("SELECT * FROM bikes, bikeTypes WHERE bikes.model_id = bikeTypes.model_id");
$result = array();
while($row = mysqli_fetch_array($output))
{
$result[] = $row;
}
//var_dump($result);
foreach ($result as $key => $val) {
echo "<li><a href='test.php?id=" . $val['model_id'] . "'>".$key.'</a><ul>';
echo "<li><a href='details.php?id=" . $val['bike_id'] . "'>" . $val['bikeName'] . "</a></li>";
echo '</ul>';
echo '</li>';
}
?>
The category field is called 'model'. Thanks for any help!
Thats because you're display the $key, instead of the $value.
<?
$output = mysqli_query("SELECT * FROM bikes, bikeTypes WHERE bikes.model_id = bikeTypes.model_id");
while($row = mysqli_fetch_array($output))
{
echo "<li><a href='test.php?id=" . $row['model_id'] . "'>".$row['???'].'</a><ul>';
echo "<li><a href='details.php?id=" . $row['bike_id'] . "'>" . $row['bikeName'] . "</a></li>";
echo '</ul>';
echo '</li>';
}
?>
I have a search engine and because of the paralympics, I want people to be able to see a h1 countdown I have placed at the top of my site. Underneath will be the looped results from my database. Any ideas where I go wrong? because in this if, it won't echo the h1 tag at all. I would like to above my results.
$query = " SELECT * FROM scan WHERE ";
$terms = array_map('mysql_real_escape_string', $terms);
$i = 0;
foreach ($terms as $each) {
if ($i++ !== 0) {
$query .= " OR ";
}
$query .= "keywords LIKE '%{$each}%'";
}
// Don't append the ORDER BY until after the loop
$query .= "ORDER BY rank";
$query = mysql_query($query) or die('MySQL Query Error: ' . mysql_error($connect));
$numrows = mysql_num_rows($query);
if ($numrows > 0) {
while ($row = mysql_fetch_assoc($query)) {
$id = $row['id'];
$title = $row['title'];
$description = $row['description'];
$keywords = $row['keywords'];
$link = $row['link'];
$rank = $row['rank'];
echo '<h2><a class="ok" href="' . $link . '">' . $title . '</a></h2>' . PHP_EOL;
echo '<p maxlength="10" class="kk">' . $description . '</p>' . PHP_EOL;
echo '<p><a class="okay" href="' . $link . '">' . $link . '<br><br><span class="keywords"></p>' . PHP_EOL;
}
} else {
echo "No results found for \"<b>{$k}</b>\"";
}
if ($k = "Paralympics 2012") {
echo "<h1> Countdown to Paralympics: 7 Days </h1>";
}
if ($k = "Paralympics 2012") {
echo "<h1> Countdown to Paralympics: 7 Days </h1>";
}
Will always print the <h1>. You're doing assignment rather than comparison. Try:
if ($k == "Paralympics 2012")
Also, verify that $k is what you expect it to be when debugging.
One equals (=) assigns, and two/three (==/===) compares. The line
if ($k = "Paralympics 2012") {
Assigns $k to a string, which always returns true, because any string other than an empty one ("") is truthy. Try this:
if ($k === "Paralympics 2012") {
First things first, the <h1> is always displaying, opposite of what you're question states. It's always displaying due to the fact that you're doing an assignment of a non-false value with:
if ($k = "Paralympics 2012") {
Update that to use a comparison to fix that logic issue.
if ($k == "Paralympics 2012") {
Next, to get it to display above your results, you need to actually move that if-statement above the loop that echos the results. Try placing it in the if ($numrows > 0) { block, like this:
if ($numrows > 0) {
if ($k == "Paralympics 2012") {
echo "<h1> Countdown to Paralympics: 7 Days </h1>";
}
while ($row = mysql_fetch_assoc($query)) {
...