Building a tree using nested unordered lists

时光怂恿深爱的人放手 提交于 2021-02-11 15:49:59

问题


How can I build this HTML code:

<ul class="tree">
    <li>Animals
        <ul>
            <li>Birds</li>
            <li>Mammals
                <ul>
                    <li>Elephant</li>
                    <li>Mouse</li>
                </ul>
            </li>
            <li>Reptiles</li>
        </ul>
    </li>
    <li>Plants
        <ul>
            <li>Flowers
                <ul>
                    <li>Rose</li>
                    <li>Tulip</li>
                </ul>
            </li>
            <li>Trees</li>
        </ul>
    </li>
</ul>

From this structure:

CREATE TABLE `categories` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `position` INT(11) DEFAULT NULL,
  `parent_id` INT(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `parent_id_fk` (`parent_id`),
  CONSTRAINT `categories_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `categories` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `categories` (`id`, `position`, `parent_id`)
VALUES
    (1,1,NULL),
    (2,2,NULL),
    (3,1,1),
    (4,2,1),
    (5,1,4),
    (6,2,4),
    (7,3,1),
    (8,1,2),
    (9,1,8),
    (10,2,8),
    (11,2,2);

CREATE TABLE `categories_locale` (
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `slug` VARCHAR(100) NOT NULL DEFAULT '',
  `name` VARCHAR(40) NOT NULL DEFAULT '',
  `path_cache` text,
  `category_id` INT(11) NOT NULL,
  `locale_id` SMALLINT(5) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `categories_locale` (`id`, `slug`, `name`, `path_cache`, `category_id`, `locale_id`)
VALUES
    (1,'animals','Animals',NULL,1,1),
    (2,'plants','Plants',NULL,2,1),
    (3,'birds','Birds',NULL,3,1),
    (4,'mammals','Mammals',NULL,4,1),
    (5,'elephant','Elephant',NULL,5,1),
    (6,'mouse','Mouse',NULL,6,1),
    (7,'reptiles','Reptiles',NULL,7,1),
    (8,'flowers','Flowers',NULL,8,1),
    (9,'rose','Rose',NULL,9,1),
    (10,'tulip','Tulip',NULL,10,1),
    (11,'trees','Trees',NULL,11,1);

回答1:


Hmm, I believe there must be examples available online on how you can accomplish this. Some of them might even talk about new ways to store hierarchical data and you'll find the readings interesting.

Anyways, this code snippet, based on recursion, might help you achieve your HTML.

<?php
// recursive function to generate the category HTML
function generateTree ($parent) {
    global $arrPCat, $arrCat;
    if (array_key_exists($parent, $arrPCat)) {
        echo '<ul' . ($parent == 0 ? ' class="tree"' : '') . '>';
        foreach ($arrPCat[$parent] as $arrC) {
            echo '<li>' . $arrC['name'] . '</li>';
            generateTree($arrC['id']);
        }
        echo '</ul>';
    }
}

// read all categories from the DB
$rs = mysql_query('SELECT  `cl`.`id`, `cl`.`name`, `c`.`position`, IFNULL(`c`.`parent_id`, 0) AS `parent_id`
    FROM  `categories_locale`  `cl`
    LEFT JOIN  `categories`  `c` ON  `cl`.`id` =  `c`.`id`
    ORDER BY  `c`.`parent_id` ,  `c`.`position`');
while ($r = mysql_fetch_assoc($rs)) {
    // store parent and its children into the $arrPCat Array
    $arrPCat[$r['parent_id']][] = Array (
                                    'id' => $r['id'],
                                    'name' => $r['name']
                                  );
}
generateTree (0); // now generate the HTML for the category tree
?>

Hope it helps!




回答2:


Try constructing the actual tree in PHP, then using depth-first search to generate the HTML.




回答3:


There is a slight error I come across with Abhay's answer. His solution does not make the UL nested within the LIs, atleast when I implement his solution. However, its a quick fix. You simply need to echo the closing li tag after the recursive call is made. This allows every list item to be fully created, even if it does not have any sub-items, before it is ended.

Abhay's code:

foreach ($arrPCat[$parent] as $arrC) {
        echo '<li>' . $arrC['name'] . '</li>';
        generateTree($arrC['id']);
    }

The correction:

foreach ($arrPCat[$parent] as $arrC) {
        echo '<li>' . $arrC['name'] ;
        generateTree($arrC['id']);
        echo '</li>';
    }


来源:https://stackoverflow.com/questions/8767846/building-a-tree-using-nested-unordered-lists

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!