Multi-level array to a table
I am trying to convert a multi-level array to a table. However my code does not output what I want. It shows the last child, but not other child and grandchild.
DB table
CREATE TABLE IF NOT EXISTS `menus` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`shortdesc` varchar(255) NOT NULL,
`status` enum('active','inactive') NOT NULL,
`parentid` int(11) NOT NULL,
`order` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=71 ;
--
-- Dumping data for table `menus`
--
INSERT INTO `menus` (`id`, `name`, `shortdesc`, `status`, `parentid`, `order`) VALUES
(24, 'Main menu', 'mainmenu', 'active', 0, 0),
(25, 'Galleri 1', 'galleri1', 'active', 0, 0),
(69, 'Main 2-2', '', 'active', 62, 0),
(68, 'Main 2-1', '', 'active', 62, 0),
(65, 'Main 4', '', 'active', 24, 0),
(64, 'Main 3', '', 'active', 24, 0),
(67, 'Main 1-2', '', 'active', 59, 0),
(62, 'Main 2', '', 'active', 24, 0),
(59, 'Main 1', '', 'active', 24, 0),
(66, 'Main 1-1', '', 'active', 59, 0),
(70, 'Manu 4-1', '', 'active', 65, 0);
View
if (count($navlist)){
echo "<table border='1' cellspacing='0' cellpadding='3' width='800'>\n";
echo "<thead>\n<tr valign='top'>\n";
echo "<th>ID</th>\n<th>Name</th><th>Status</th><th>parentid</th><th>Actions</th>\n";
echo "</tr>\n</thead>\n<tbody>\n";
foreach ($navlist as $key => $menu){
echo "<tr valign='top'>\n";
echo "<td>".$menu['id']."</td>\n";
echo '<td><a href="'. site_url(). '/admin/menus/submenus/' . $menu['id'] . '">' .$menu['name']."</a></td>\n";
echo "<td align='center'>".$menu['status']."</td>\n";
echo "<td align='center'>".$menu['parentid']."</td>\n";
echo "<td align='center'>";
echo anchor('admin/menus/editMenu/'.$menu['id'],'edit');
echo " | ";
echo anchor('admin/menus/deleteMenu/'.$menu['id'],'delete', array('class' => 'delete_link'));
echo "</td>\n";
echo "</tr>\n";
if (count($menu['children'])){
foreach ($menu['children'] as $subkey => $submenu){
echo "<tr class='child' valign='top'>\n";
echo "<td>".$submenu['id']."</td>\n";
echo '<td><a href="'. site_url(). '/admin/menus/submenus/' . $submenu['id'] . '">' .$submenu['name']."</a></td>\n";
echo "<td align='center'>".$submenu['status']."</td>\n";
echo "<td align='center'>".$submenu['parentid']."</td>\n";
echo "<td align='center'>";
echo anchor('admin/menus/editMenu/'.$submenu['id'],'edit');
echo " | ";
echo anchor('admin/menus/deleteMenu/'.$submenu['id'],'delete', array('class' => 'delete_link'));
echo "</td>\n";
echo "</tr>\n";
}
if (count($submenu['children'])){
foreach ($submenu['children'] as $subkey => $subsubname){
echo "<tr class='grandchild' valign='top'>\n";
echo "<td>". $subsubname['id']."</td>\n";
echo '<td><a href="'. site_url(). '/admin/menus/submenus/' . $subsubname['id'] . '">' . $subsubname['name']."</a></td>\n";
echo "<td align='center'>". $subsubname['status']."</td>\n";
echo "<td align='center'>". $subsubname['parentid']."</td>\n";
echo "<td align='center'>";
echo anchor('admin/menus/editMenu/'. $subsubname['id'],'edit');
echo " | ";
echo anchor('admin/menus/deleteMenu/'. $subsubname['id'],'delete', array('class' => 'delete_link'));
echo "</td>\n";
echo "</tr>\n";
}
}
}
}
echo "</tbody>\n</table>";
}
HTML Output
<table border='1' cellspacing='0' cellpadding='3' width='800'>
<thead>
<tr valign='top'>
<th>ID</th>
<th>Name</th><th>Status</th><th>parentid</th><th>Actions</th>
</tr>
</thead>
<tbody>
<tr valign='top'>
<td>24</td>
<td><a href="http://127.0.0.1/ci/index.php/admin/menus/submenus/24">Main menu</a></td>
<td align='center'>active</td>
<td align='center'>0</td>
<td align='center'><a href="http://127.0.0.1/ci/index.php/admin/menus/editMenu/24">edit</a> | <a href="http://127.0.0.1/ci/index.php/admin/menus/deleteMenu/24" class="delete_link">delete</a></td>
</tr>
<tr class='child' valign='top'>
<td>65</td>
<td><a href="http://127.0.0.1/ci/index.php/admin/menus/submenus/65">Main 4</a></td>
<td align='center'>active</td>
<td align='center'>24</td>
<td align='center'><a href="http://127.0.0.1/ci/index.php/admin/menus/editMenu/65">edit</a> | <a href="http://127.0.0.1/ci/index.php/admin/menus/deleteMenu/65" class="delete_link">delete</a></td>
</tr>
<tr class='child' valign='top'>
<td>64</td>
<td><a href="http://127.0.0.1/ci/index.php/admin/menus/submenus/64">Main 3</a></td>
<td align='center'>active</td>
<td align='center'>24</td>
<td align='center'><a href="http://127.0.0.1/ci/index.php/admin/menus/editMenu/64">edit</a> | <a href="http://127.0.0.1/ci/index.php/admin/menus/deleteMenu/64" class="delete_link">delete</a></td>
</tr>
<tr class='child' valign='top'>
<td>62</td>
<td><a href="http://127.0.0.1/ci/index.php/admin/menus/submenus/62">Main 2</a></td>
<td align='center'>active</td>
<td align='center'>24</td>
<td align='center'><a href="http://127.0.0.1/ci/index.php/admin/menus/editMenu/62">edit</a> | <a href="http://127.0.0.1/ci/index.php/admin/menus/deleteMenu/62" class="delete_link">delete</a></td>
</tr>
<tr class='child' valign='top'>
<td>59</td>
&l开发者_StackOverflowt;td><a href="http://127.0.0.1/ci/index.php/admin/menus/submenus/59">Main 1</a></td>
<td align='center'>active</td>
<td align='center'>24</td>
<td align='center'><a href="http://127.0.0.1/ci/index.php/admin/menus/editMenu/59">edit</a> | <a href="http://127.0.0.1/ci/index.php/admin/menus/deleteMenu/59" class="delete_link">delete</a></td>
</tr>
<tr class='grandchild' valign='top'>
<td>67</td>
<td><a href="http://127.0.0.1/ci/index.php/admin/menus/submenus/67">Main 1-2</a></td>
<td align='center'>active</td>
<td align='center'>59</td>
<td align='center'><a href="http://127.0.0.1/ci/index.php/admin/menus/editMenu/67">edit</a> | <a href="http://127.0.0.1/ci/index.php/admin/menus/deleteMenu/67" class="delete_link">delete</a></td>
</tr>
<tr class='grandchild' valign='top'>
<td>66</td>
<td><a href="http://127.0.0.1/ci/index.php/admin/menus/submenus/66">Main 1-1</a></td>
<td align='center'>active</td>
<td align='center'>59</td>
<td align='center'><a href="http://127.0.0.1/ci/index.php/admin/menus/editMenu/66">edit</a> | <a href="http://127.0.0.1/ci/index.php/admin/menus/deleteMenu/66" class="delete_link">delete</a></td>
</tr>
<tr valign='top'>
<td>25</td>
<td><a href="http://127.0.0.1/ci/index.php/admin/menus/submenus/25">Galleri 1</a></td>
<td align='center'>active</td>
<td align='center'>0</td>
<td align='center'><a href="http://127.0.0.1/ci/index.php/admin/menus/editMenu/25">edit</a> | <a href="http://127.0.0.1/ci/index.php/admin/menus/deleteMenu/25" class="delete_link">delete</a></td>
</tr>
</tbody>
</table>
This solution involves recursion. If you are not familiar with the term or have a hard time following along, please refer to this IBM entry entitled "Mastering recursive programming" to familiarize yourself. It seems as though you only plan on having three levels of navigation. With that being said, this code only handles the classnames parent/child/grandchild for those three levels. You can easily add more by adding new array entries to $depthClassMapping
.
/**
* @param array $level The current navigation level array
* @param string $output The output to be added to
* @param int $depth The current depth of the tree to determine classname
*/
function generateRowsByLevel($level, &$output, $depth = 0) {
$depthClassMapping = array(0 => 'parent', 1 => 'child', 2 => 'grandchild');
foreach ($level as $row) {
$output .= "<tr class=\"" . $depthClassMapping[$depth] . "\" valign='top'>\n";
$output .= "<td>". $row['id']."</td>\n";
$output .= '<td><a href="'. site_url(). '/admin/menus/submenus/' . $row['id'] . '">' . $row['name']."</a></td>\n";
$output .= "<td align='center'>". $row['status']."</td>\n";
$output .= "<td align='center'>". $row['parentid']."</td>\n";
$output .= "<td align='center'>";
$output .= anchor('admin/menus/editMenu/'. $row['id'],'edit');
$output .= " | ";
$output .= anchor('admin/menus/deleteMenu/'. $row['id'],'delete', array('class' => 'delete_link'));
$output .= "</td>\n";
$output .= "</tr>\n";
// if the row has any children, parse those to ensure we have a properly
// displayed nested table
if (!empty($row['children'])) {
generateRowsByLevel($row['children'], $output, $depth + 1);
}
}
}
//==================
// RUN THE GENERATOR
//==================
if (count($navlist)){
// begin table
$output = "<table border='1' cellspacing='0' cellpadding='3' width='800'>\n";
$output .= "<thead>\n<tr valign='top'>\n";
$output .= "<th>ID</th>\n<th>Name</th><th>Status</th><th>parentid</th><th>Actions</th>\n";
$output .= "</tr>\n</thead>\n<tbody>\n";
// generate all table rows
generateRowsByLevel($navlist, $output);
// close up the table
$output .= "</tbody>\n</table>";
// display table
echo $output;
}
You need to implement a recursive function or use a function like array_map with a callback function to process multi-array while sending back appropriate data, you can see more info about that function at php.net site.
Your logic is too flat and flawed. Make use of functions and recursion. You may find this blog useful as well: http://crisp.tweakblogs.net/blog/317/formatting-a-multi-level-menu-using-only-one-query.html
精彩评论