Jump to content

Creating a sub and sub-sub menu using category and sub-categories.


Recommended Posts

I do have a list of categories and its sub categories, something like this.

INSERT INTO categories VALUES
            (1,NULL, 'Products', NULL),
            (2,1, 'Computers', NULL),
            (3,2, 'Laptops', NULL),
            (4,2, 'Desktop Computers', NULL),
            (5,2, 'Tab PCs', NULL),
            (6,2, 'CRT Monitors', NULL),
            (7,2, 'LCD Monitors', NULL),
            (8,2, 'LED Monitors', NULL),
            (9,1, 'Mobile Phones', NULL),
            (10,9, 'LG Phone', NULL),
            (11,9, 'Anroid Phone', NULL),
            (12,9, 'Windows Mobile', NULL),
            (13,9, 'iPad', NULL),
            (14,9, 'Samsung Galaxy', NULL),
            (15,1, 'Digital Cameras', NULL),
            (16,1, 'Printers and Toners', NULL);

Now I need to create a Product sub and sub-sub menu using this product list.

 

This is my expecting Markup for the menu.

---
---
---
<li class="current-menu-item menu-item-has-children">
    <a href="#">Products</a>
    <ul class="sub-menu">        
        <li>
            <a href="#">Laptops & Desktop Monitors</a>
            <ul class="sub-menu">
                <li"><a href="products.php&product-id=5">Category 1</a></li>
                <li"><a href="products.php&product-id=6">Category 2</a></li>
                <li"><a href="products.php&product-id=7">Category 3</a></li>
            </ul>
        </li>    
        <li><a href="products.php&product-id=4">Mobile Phones</a></li>
        <li><a href="products.php&product-id=4">Phones Accessories</a></li>
        <li><a href="products.php&product-id=4">Computer accessories</a></li>
    </ul>
</li>
---
---
---

So I tried it using recursion as @Barand showed me in earlier post.

$prep_stmt =   "SELECT  category_id
                                            , name
                                            , IFNULL(parent, 0)
                                FROM categories
                                ORDER BY name";
                                                            
$stmt = $mysqli->prepare($prep_stmt);

if ($stmt) {
    // Execute the prepared query.
    $stmt->execute();    
    $stmt->store_result();
    
    $numrows = $stmt->num_rows;

    if ($numrows >= 1) {
    
        // get variables from result.
        $stmt->bind_result($id, $name, $parent);
        
        // Fetch all the records:
        while ($stmt->fetch()) {
            $cats[$parent][$id] = $name;
        }
        
        // Close the statement:
        $stmt->close();
        unset($stmt);    
    }
}

<?php
    // ------- Display Category List --------
    function displayList(&$cats, $parent, $level=0) {
        switch ($level) {
            case 0: $class = "sub-menu"; break;
            case 1: $class = "sub-menu"; break;
            case 2: $class = "children2"; break;
        }
        if ($parent==0) {
            foreach ($cats[$parent] as $id=>$nm) {
                displayList($cats, $id);
            }
        }
        else {
            echo "<ul class='$class'>\n";
            foreach ($cats[$parent] as $id=>$nm) {
                echo "<li><a href='products.php?product=$id'>$nm</a></li>\n";
                if (isset($cats[$id])) {
                    displayList($cats, $id, $level+1);  //increment level
                }
            }
            echo "</ul>\n";
        }  
    }
    
    
    displayList($cats, 0);

?>

It display my sub menu correctly but not displaying sub sub menu. This is the rendering HTML from above code.

<li>
    <a href="">Products</a>
                                            
    <ul class='sub-menu'>
        <li><a href='products.php?product=22'>Computer Accessaries</a></li>
            <ul class='sub-menu'>
                <li><a href='products.php?product=24'>Network Cables</a></li>
                <li><a href='products.php?product=23'>USB Cables</a></li>
            </ul>
        <li><a href='products.php?product=2'>Computers</a></li>
            <ul class='sub-menu'>
                <li><a href='products.php?product=6'>CRT Monitors</a></li>
                <li><a href='products.php?product=4'>Desktop Computers</a></li>
                <li><a href='products.php?product=3'>Laptops</a></li>
                <li><a href='products.php?product=7'>LCD Monitors</a></li>
                <li><a href='products.php?product=8'>LED Monitors</a></li>
                <li><a href='products.php?product=5'>Tab PCs</a></li>
            </ul>
        <li><a href='products.php?product=15'>Digital Cameras</a></li>
            <ul class='sub-menu'>
                <li><a href='products.php?product=21'>test</a></li>
            </ul>
        <li><a href='products.php?product=18'>test2</a></li>
        <li><a href='products.php?product=19'>test3</a></li>
    </ul>
</li>

Can anybody tell me how to fix this problem?

 

Thank you.

 

 

Have you tried modifying the code so that the sub-sub menu is within the <li> tag of the sub menu? So this

<li><a href='products.php?product=22'>Computer Accessaries</a></li>
<ul class='sub-menu'>
    <li><a href='products.php?product=24'>Network Cables</a></li>
    <li><a href='products.php?product=23'>USB Cables</a></li>
</ul>
 
Should be this
<li><a href='products.php?product=22'>Computer Accessaries</a>
<ul class='sub-menu'>
    <li><a href='products.php?product=24'>Network Cables</a></li>
    <li><a href='products.php?product=23'>USB Cables</a></li>
</ul>
</li>

Check your code:

echo "<li><a href='products.php?product=$id'>$nm</a></li>\n";
if (isset($cats[$id])) {
    displayList($cats, $id, $level+1);  //increment level
}

You're closing the li element before you call displayList(), but you must close it afterwards. Because displayList() generates the ul element with the sub-entries.

 

You also can't just insert PHP variables directory into URLs or HTML markup. They have to be escaped and encoded:

<?php

function html_escape($value, $encoding)
{
    return htmlspecialchars($value, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE, $encoding);
}



$product_url = 'products.php?'.http_build_query(['id' => $id]);

echo '<li><a href="'.html_escape($product_url, 'UTF-8').'">'.html_escape($nm, 'UTF-8').'</a>';
if (isset($cats[$id]))
{
    displayList($cats, $id, $level + 1);
}
echo '</li>';
  • Like 1

@Jacques1, Thank you for your answer and suggestion. Can you Kindly explain what is the reason to use escaped and encoded urls?

 

And also I needed to change this line :

return htmlspecialchars($value, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE, $encoding);

to

return htmlspecialchars($value, ENT_QUOTES | 'ENT_HTML5' | 'ENT_SUBSTITUTE', $encoding);

get it to work. Is it a typo?

 

Thank you.

Can you Kindly explain what is the reason to use escaped and encoded urls?

 

Some characters obviously have a special meaning when used in an HTML context (like “<” or “&”). If your PHP variables happen to include those characters, you'll quickly end up with all kinds of bugs and security vulnerabilities. Escaping prevents that by turning the special characters into HTML entities. For example, the less-than sign is converted into < which denotes a literal less-than sign rather than the beginning of an HTML element.

 

URL-encoding does the same thing for URLs.

 

Sometimes escaping may seem unnecessary, because you believe that the data is harmless (e. g. a simple number). You should still escape it to avoid any risks. Advanced template engines like Twig automatically escape all input by default.

 

 

 

Is it [the htmlspecialchars() constants] a typo?

 

No, you're using an outdated PHP version. Those constants were introduced in PHP 5.4. All versions before 5.5 have reached end-of-life and are no longer supported.

 

So it's time for an update (or a proper hoster). For now, you can just remove the two offending constants (do not turn them into strings). They're not critical.

Edited by Jacques1
  • Like 1
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.