Bài 02: Đệ quy menu đa cấp với php và mysql - phần 2
Trước khi vào bài này bạn vui lòng đọc bài đệ quy menu với php và mysql phần 1 đã nhé.
Ở bài trước chúng ta đã xây dựng được dữ liệu database, xây dựng được layout hiển thị danh sách menu và một lớp Menu dùng để kết nối và lấy dữ liệu. Nhưng chúng ta chưa show dữ liệu ra dưới dạng đệ quy nên trong bài này tôi sẽ hướng dẫn các bạn sử dụng đệ quy để hiển thị danh sách menu nhé.
Trước khi vào vấn đề chính tôi xin quay lại bài cũ một xíu. Ở bài trước toi đã tạo một file danhsach.php và code javascript, css thẳng vào trong file luôn. Như vậy trông rất khó coi nên bây giờ tôi sẽ tách nó ra file css riêng và import nó vào. Bởi vậy những đoạn code tôi show sẽ không có những đoạn mã CSS nữa. Và tôi cũng xóa luôn những đoạn mã HTML của từng menu, chỉ chừa lại 1 cái để lặp và hiển thị. Nội dung file danhsach.php lúc này như sau:
<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link href="style.css" rel="stylesheet" type="text/css"/> <script language="javascript" src="http://code.jquery.com/jquery-2.0.0.min.js"></script> <script language="javascript"> $(document).ready(function() { $('#menu_wrapper ul div').hide(); $('#menu_wrapper ul li a').click(function() { var tmp = $(this).next('div'); if ($(tmp).is(':visible')) { $(tmp).hide(); } else { $(tmp).show(); } return false; }); }); </script> </head> <body> <div id="menu_wrapper"> <input type="button" class="button" value="Thêm"/> <br/> <br/> <hr/><br/> <ul> <li> <a href="">Nội dung menu</a> <div> <table border="0"> <tr> <td>Title</td> <td><input id="menu_title_{id_hien_tai}" name="" value="" /></td> </tr> <tr> <td>Link</td> <td><input id="menu_link_{id_hien_tai}" name="" value="" /></td> </tr> <tr> <td>Parent</td> <td> <select id="menu_parent_id_{id_hien_tai}"> <option>-TOP-</option> </select> <input type="button" data-id="{id_hien_tai}" name="" class="button menu-save" value="Lưu" /> </td> </tr> </table> </div> </li> </ul> </div> </body> </html>
Bài viết này được đăng tại [free tuts .net]
Trong mỗi ô tôi khoanh tròn các bạn thấy tôi có một đoạn code {id_hien_tai}. Mục đích là trong quá trình lặp tôi sẽ điền ID của menu hiện tại vào để khi click vào button EDIT ta có thể lấy đúng input của menu đó để lưu dữ liệu. ở button lưu tôi cố thêm một class tên là menu-save mục đích dùng để bắt sự kiện click và xử lý.
Đơn giản phải không nào, bây giờ ta tiến hành xây dựng hàm đệ quy php để hiển thị danh sách nhé.
1. Xây dựng hàm đệ quy php hiển thị danh sách
Trước tiên bạn tạo file dequy.php và copy nọi dung bên dưới vào:
/* * Hàm hiển thị danh sách menu dạng list * Tham số truyền vào: * - $menus: danh sách menu * - $id_parent: mặc định, không cần truyền vào */ function showMenuLi($menus, $id_parent = 0) { # BƯỚC 1: LỌC DANH SÁCH MENU VÀ CHỌN RA NHỮNG MENU CÓ ID_PARENT = $id_parent // Biến lưu menu lặp ở bước đệ quy này $menu_tmp = array(); foreach ($menus as $key => $item) { // Nếu có parent_id bằng với parrent id hiện tại if ((int) $item['menu_parent_id'] == (int) $id_parent) { $menu_tmp[] = $item; // Sau khi thêm vào biên lưu trữ menu ở bước lặp // thì unset nó ra khỏi danh sách menu ở các bước tiếp theo unset($menus[$key]); } } # BƯỚC 2: lẶP MENU THEO DANH SÁCH MENU Ở BƯỚC 1 // Điều kiện dừng của đệ quy là cho tới khi menu không còn nữa if ($menu_tmp) { echo '<ul>'; foreach ($menu_tmp as $item) { echo '<li>'; echo '<a href="' . $item['menu_link'] . '">' . $item['menu_title'] . '</a>'; echo '<div> <table border="0"> <tr> <td>Title</td> <td><input id="menu_title_' . $item['menu_id'] . '" value="' . $item['menu_title'] . '" /></td> </tr> <tr> <td>Link</td> <td><input id="menu_link_' . $item['menu_id'] . '" value="' . $item['menu_link'] . '" /></td> </tr> <tr> <td>Parent</td> <td> <select id="menu_parent_id_' . $item['menu_id'] . '"> </select> <input type="button" data-id="' . $item['menu_id'] . '" class="button menu-save" value="Lưu" /> </td> </tr> </table> </div>'; // Gọi lại đệ quy // Truyền vào danh sách menu chưa lặp và id parent của menu hiện tại showMenuLi($menus, $item['menu_id']); echo '</li>'; } echo '</ul>'; } }
Trong hàm này tôi đã lặp thẻ UL trong file danhsach.php, và ở mỗi lần lặp tôi đã thay giá trị {id_hien_tai} thành $item['menu_id'].
Bây giờ bạn thay đổi nội dung file danhsach.php như sau:
<?php require "menu.php"; require "dequy.php"; // Đối tượng menu $object = new Menu(); // Danh sách menu $menus = $object->getList(); ?> <!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link href="style.css" rel="stylesheet"/> <script language="javascript" src="http://code.jquery.com/jquery-2.0.0.min.js"></script> <script language="javascript"> $(document).ready(function(){ $('#menu_wrapper ul div').hide(); $('#menu_wrapper ul li a').click(function(){ var tmp = $(this).next('div'); if ($(tmp).is(':visible')){ $(tmp).hide(); } else{ $(tmp).show(); } return false; }); }); </script> </head> <body> <div id="menu_wrapper"> <input type="button" class="button" value="Thêm"/> <br/> <br/> <hr/><br/> <?php showMenuLi($menus); ?> </div> </body> </html>
2. Thêm dữ liệu vào menu
Các bạn thêm một số dòng dữ liệu để hiển thị menu. Copy và vào phpmyadmin chạy nhé.
INSERT INTO `menu` (`menu_id`, `menu_title`, `menu_link`, `menu_parent_id`) VALUES (1, 'PARENT1', NULL, 0), (2, 'PARENT2', NULL, 0), (3, 'SUB1', NULL, 1), (4, 'SUB2', NULL, 1), (5, 'SUB3', NULL, 1), (6, 'SUB4', NULL, 2), (7, 'SUB5', NULL, 2), (8, 'SUB6', NULL, 3);
3. Lời kết
Các bạn thấy trong bài này tôi mới chỉ hiển thị danh sách menu đệ quy chứ, và ở mỗi menu tôi đã truyền đầy đủ thông số vào các input. Tuy nhiên tôi chưa có sử lý sự kiện click LƯU. Và tôi cũng chưa hiển thị danh sách MENU PARENT để người dùng chọn. Những điều này tôi sẽ xử lý ở bài tiếp theo, mong các bạn theo dõi