Bài 02: Đệ quy menu đa cấp với php và mysql - phần 2

DOWNLOAD

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é.

Thông báo: Serie này đã được biên soạn và quay video nên bạn hãy xem video để dễ hình dung hơn. Xem tại đây.

Ở 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>
Các bạn để ý rằng các thẻ input tôi có đặt ID theo một quy luật như hình dưới đây:

đệ quy menu

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>
Đơn giản không nào, đoạn code đầu file mục đích lấy danh sách menu và import thư viện dequy vào. Ở đoạn giữa file tôi xóa đi những đoạn mã HTML hiển thị menu và thay vào đó là gọi hàm đệ quy menu.

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);
Chạy lên ta sẽ có giao diện như bên dưới.

đệ quy menu hình 2

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

Hãy để lại link bài viết gốc khi chia sẻ bài viết này, mình sẽ report DMCA với những website lấy nội dung mà không để nguồn hoặc copy bài với số lượng lớn.

Nguồn: freetuts.net

Profile photo of adminTheHalfHeart

TheHalfHeart

Có sở thích viết tuts nên đã từng tham gia viết ở một số diễn đàn, đến năm 2014 mới có điều kiện sáng lập ra freetuts.net. Sinh năm 90 và có 1 vợ 2 con, thích ca hát và lập trình.

ĐĂNG BÌNH LUẬN: Đăng câu hỏi trên Facebook để được hỗ trợ nhanh nhất.