สร้างการเรียงเมนูด้วย SortableJS

วันที่: 19 ก.พ. 2567 10:57 น.

สร้างการเรียงเมนูด้วย SortableJS

SortableJS นั้นเป็นไลบรารี JavaScript ที่ช่วยในการสร้างลิสต์หรือตารางที่สามารถลากและวางได้ (drag-and-drop) อย่างง่ายดาย โดยมันช่วยให้ผู้พัฒนาสามารถสร้างอินเทอร์เฟซที่ให้ผู้ใช้สามารถจัดเรียงองค์ประกอบต่างๆ ในลำดับที่ต้องการได้อย่างง่ายดาย มันเป็นเครื่องมือที่นิยมใช้ในการพัฒนาเว็บแอปพลิเคชันที่มีการจัดเรียงข้อมูลเป็นลำดับตามลำดับที่ผู้ใช้ต้องการ การใช้ SortableJS ช่วยลดเวลาในการพัฒนาและเพิ่มประสิทธิภาพของการทำงานได้มาก ๆ ด้วยการให้ผู้ใช้สามารถจัดเรียงข้อมูลได้โดยไม่ต้องมีการโหลดหน้าใหม่หรือมีการส่งคำขอไปยังเซิร์ฟเวอร์ เพียงแค่ลากและวางได้ทันทีบนหน้าเว็บไซต์โดยตรง ด้วยความสะดวกและประสิทธิภาพที่สูง

ในบทความนี้จะพาสร้างเมนู โดยสามารถรองรับเมนูย่อยแบบไม่จำกัด (ถึงแม้ในชีวิตจริง เมนูก็ไม่น่าจะเกิน 2 ระดับอ่ะนะ) แต่ในบทความนี้ จะพาทำแบบไม่จำกัดเลย และสามารถสร้างเป็น json ออกมาเพื่อนำไปบันทึกในฐานข้อมูลต่อได้ด้วย ที่สำคัญคือไม่ต้องใช้ jquery ด้วยนะ นี่คือโค้ดทั้งหมดครับ

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body {
            margin-top: 60px;
            background-color: #f1f2f7;
        }

        .list-group .list-group-item > .list-group div:first-child {
            margin-top: 0.5rem;
        }
    </style>
</head>

<body>

    <div class="container">
        <div id="nestedDemo" class="list-group col nested-sortable">
            <div data-id="1" class="list-group-item nested-1">
                <span>เกี่ยวกับเรา</span>
                <div class="list-group nested-sortable">
                    <div data-id="2" class="list-group-item nested-2">
                        <span>ประวัติหน่วยงาน</span>
                        <div class="list-group nested-sortable"></div>
                    </div>
                    <div data-id="3" class="list-group-item nested-2">
                        <span>วิสัยทัศน์/พันธกิจ</span>
                        <div class="list-group nested-sortable"></div>
                    </div>
                    <div data-id="4" class="list-group-item nested-2">
                        <span>โครงสร้างหน่วยงาน</span>
                        <div class="list-group nested-sortable"></div>
                    </div>
                    <div data-id="5" class="list-group-item nested-2">
                        <span>ผู้บริหาร</span>
                        <div class="list-group nested-sortable"></div>
                    </div>
                    <div data-id="6" class="list-group-item nested-2">
                        <span>อำนาจหน้าที่</span>
                        <div class="list-group nested-sortable"></div>
                    </div>
                </div>
            </div>
            <div data-id="7" class="list-group-item nested-1">
                <span>ข่าวสารหน่วยงาน</span>
                <div class="list-group nested-sortable">
                    <div data-id="8" class="list-group-item nested-2">
                        <span>ข่าวประชาสัมพันธ์</span>
                        <div class="list-group nested-sortable"></div>
                    </div>
                    <div data-id="9" class="list-group-item nested-2">
                        <span>ข่าวจัดซื้อ/จัดจ้าง</span>
                        <div class="list-group nested-sortable"></div>
                    </div>
                    <div data-id="10" class="list-group-item nested-2">
                        <span>ข่าวรับสมัครงาน</span>
                        <div class="list-group nested-sortable"></div>
                    </div>
                    <div data-id="11" class="list-group-item nested-2">
                        <span>ข่าวอื่นๆ ที่เกี่ยวข้อง</span>
                        <div class="list-group nested-sortable"></div>
                    </div>
                </div>
            </div>
            <div data-id="12" class="list-group-item nested-1">
                <span>ติดต่อเรา</span>
                <div class="list-group nested-sortable"></div>
            </div>
        </div>

        <div class="mt-4">
            <textarea name="result" id="result" rows="4" class="form-control"></textarea>
        </div>
    </div>

    <script src="https://sortablejs.github.io/Sortable/Sortable.js"></script>
    <script>
        // Nested demo
        const nestedQuery = '.nested-sortable';
        const identifier = 'id';
        const root = document.getElementById('nestedDemo');
        var nestedSortables = [].slice.call(document.querySelectorAll('.nested-sortable'));

        let arr = serialize(root);
        let myJSON = JSON.stringify(arr);
        document.getElementById('result').value = myJSON;

        // Loop through each nested sortable element
        for (var i = 0; i < nestedSortables.length; i++) {
            new Sortable(nestedSortables[i], {
                group: 'nested',
                animation: 150,
                fallbackOnBody: true,
                swapThreshold: 0.65,
                onEnd: function (evt) {
                    let arr = serialize(root);
                    let myJSON = JSON.stringify(arr);
                    document.getElementById('result').value = myJSON;
                }
            });
        }

        function serialize(sortable) {
            var serialized = [];
            var children = [].slice.call(sortable.children);
            for (var i in children) {
                var nested = children[i].querySelector(nestedQuery);
                serialized.push({
                    id: children[i].dataset[identifier],
                    children: nested ? serialize(nested) : []
                });
            }
            return serialized
        }

    </script>
</body>

</html>

ลิงก์ที่เกี่ยวข้อง

เรื่องอื่น ๆ ที่เกี่ยวข้อง