Home

Byphunsanit

DataTables: ต้อนรับ jQuery 4.0

เพื่อเป็นการต้อนรับ jQuery 4.0.0 เลยเอา DataTables มาใช้กับ Vite ดูว่าตัว jQuery จะสามารถเข้าสู่ยุค modern JavaScript, TypeScript ได้จริง ๆ มั๋ย


  1. ติดตั้ง Dependencies
    npm install [email protected] datatables.net datatables.net-dt
    • datatables.net: คือตัว Library หลัก
    • datatables.net-dt: คือตัว Default Styling (CSS)
  2. data
    data.json
    [
    	{
    		"POST_CODE": "10160",
    		"SUB_DISTRICT_NAME": "Bang Wa",
    		"PROVINCE_NAME": "Bangkok",
    		"DISTRICT_NAME": "Phasi Charoen",
    		"enable": "1"
    	},
    	{
    		"POST_CODE": "10160",
    		"SUB_DISTRICT_NAME": "Bang Duan",
    		"PROVINCE_NAME": "Bangkok",
    		"DISTRICT_NAME": "Phasi Charoen",
    		"enable": "1"
    	},
    	{
    		"POST_CODE": "10160",
    		"SUB_DISTRICT_NAME": "Bang Chak",
    		"PROVINCE_NAME": "Bangkok",
    		"DISTRICT_NAME": "Phasi Charoen",
    		"enable": "1"
    	},
    	{
    		"POST_CODE": "10160",
    		"SUB_DISTRICT_NAME": "Bang Waek",
    		"PROVINCE_NAME": "Bangkok",
    		"DISTRICT_NAME": "Phasi Charoen",
    		"enable": "1"
    	},
    	{
    		"POST_CODE": "10160",
    		"SUB_DISTRICT_NAME": "Khlong Khwang",
    		"PROVINCE_NAME": "Bangkok",
    		"DISTRICT_NAME": "Phasi Charoen",
    		"enable": "1"
    	},
    	{
    		"POST_CODE": "10160",
    		"SUB_DISTRICT_NAME": "Pak Khlong Phasi Charoen",
    		"PROVINCE_NAME": "Bangkok",
    		"DISTRICT_NAME": "Phasi Charoen",
    		"enable": "1"
    	},
    	{
    		"POST_CODE": "10160",
    		"SUB_DISTRICT_NAME": "Khuha Sawan",
    		"PROVINCE_NAME": "Bangkok",
    		"DISTRICT_NAME": "Phasi Charoen",
    		"enable": "1"
    	}
    ]
    
  3. โครงสร้างไฟล์ HTML
    index.html
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>DataTables: jQuery 4 + Vite + TypeScript</title>
    </head>
    <body>
        <div class="container mt-4">
            <button class="btn btn-info" id="searchBtn" type="button">Search</button>
            <hr>
            <table class="table table-bordered table-hover table-striped" id="DataTablesA" width="100%"></table>
        </div>
    
        <script type="module" src="/src/main.ts"></script>
    </body>
    </html>
    
  4. ไฟล์ package.json
    {
      "author": "Pitt Phunsanit",
      "dependencies": {
        "bootstrap": "^5.3.8",
        "bootstrap-icons": "^1.13.1",
        "datatables.net-dt": "^2.3.7",
        "jquery": "^4.0.0"
      },
      "description": "DataTables: jQuery 4 + Vite + TypeScript",
      "devDependencies": {
        "@types/jquery": "^3.5.33",
        "typescript": "^5.9.3",
        "vite": "^7.3.1"
      },
      "keywords": [
        "Bootstrap",
        "DataTables",
        "jQuery",
        "TypeScript",
        "Vite"
      ],
      "license": "ISC",
      "main": "DataTables.js",
      "name": "datatables",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "type": "commonjs",
      "version": "1.0.0"
    }
    
  5. ไฟล์ TypeScript
    /src/main.ts
    import 'bootstrap/dist/css/bootstrap.min.css';
    import 'bootstrap-icons/font/bootstrap-icons.css';
    import 'datatables.net-dt/css/dataTables.dataTables.css';
    
    import $ from 'jquery';
    import DataTable from 'datatables.net-dt';
    
    // --- Remove or Comment out this line ---
    // DataTable(window, $);
    
    interface LocationData {
        POST_CODE: string;
        SUB_DISTRICT_NAME: string;
        DISTRICT_NAME: string;
        PROVINCE_NAME: string;
        enable: string;
    }
    
    // In new DataTables versions used with Vite/ESM
    // We usually call via DataTable.DataTable or call directly if already bound
    let dataTableInstance: any;
    
    $(() => {
        // Use this command instead of calling directly via jQuery Prototype for safety
        dataTableInstance = new DataTable('#DataTablesA', {
    		ajax: {
            	type: "GET",
            	url: "data.json",
        	},
            columns: [
                {
                    orderable: true,
                    render: (_data: any, _type: any, _row: any, meta: any) => meta.row + 1,
                    title: 'No.',
                    width: "40px",
                },
                {
                    orderable: false,
                    render: (_data: any, _type: any, row: LocationData) =>
                        `<input type="checkbox" value="${row.SUB_DISTRICT_NAME}">`,
                    title: '<input class="checkAll" type="checkbox">',
                    width: "30px",
                },
                {
                    orderable: true,
                    render: (_data: any, _type: any, row: LocationData) => {
                        const isEnabled = row.enable === '1';
                        return `<span class="bi bi-${isEnabled ? 'check-circle-fill text-success' : 'x-circle-fill text-danger'}"></span>`;
                    },
                    title: "Status",
                    width: "60px",
                },
                { data: "POST_CODE", title: "Zip Code", width: "80px" },
                { data: "SUB_DISTRICT_NAME", title: "Sub District" },
                { data: "DISTRICT_NAME", title: "District" },
                { data: "PROVINCE_NAME", title: "Province" }
            ],
            data: [],
    		processing: true,
    		serverSide: false
        });
    
        // The Search and AJAX parts remain the same
        $('#searchBtn').on('click', () => {
            $.ajax({
                dataType: "json",
                method: "GET",
                success: (data: LocationData[]) => {
                    dataTableInstance.clear().rows.add(data).draw();
                },
                url: "/data.json"
            });
        });
    });
    
  6. รันคำสั่ง
    npx vite
  7. เปิด Browser ไปที่ URL ที่ที่เห็น (เช่น http://localhost:5173)
  8. เมื่อกดปุ่ม Search ตัว jQuery จะยิง AJAX ไปดึงไฟล์จาก public/data.json มาแสดงในตารางครับ

ข้อควรระวังและการใช้ประโยชน์จาก jQuery 4.0

เมื่อใช้ร่วมกับ Vite และ jQuery 4.0 คุณจะได้ประโยชน์ดังนี้

  • Tree Shaking: Vite จะช่วยกำจัดโค้ดที่ไม่ได้ใช้ออกไปได้ดีขึ้น เพราะ jQuery 4.0 เป็น ESM
  • No Global $: ใน Vite ตัวแปร $ จะไม่เป็น Global โดยอัตโนมัติ (ยกเว้นคุณจะตั้งค่าเพิ่ม) ช่วยลดโอกาสเกิด Conflict กับ Library อื่น
  • Content Security Policy (CSP): หากคุณโหลดข้อมูลผ่าน AJAX ใน DataTables ตัว jQuery 4.0 จะจัดการเรื่อง Trusted Types ให้โดยอัตโนมัติ ทำให้เว็บของคุณปลอดภัยขึ้น

ข้อดีของการใช้ร่วมกับ TypeScript

  • ES Modules: การใช้ import $ from 'jquery' เป็นมาตรฐานใหม่ของ jQuery 4.0 ที่ทำงานร่วมกับ Vite ได้ทันที
  • Type Safety: มีการใช้ interface DistrictData เพื่อช่วยเช็คโค้ดตอนเขียน ไม่ให้เรียกชื่อ Property ผิด
  • Event Delegation: เปลี่ยนจาก $('.checkAll').click(...) มาเป็น $tableElement.on('click', ...) ซึ่งทำงานได้เสถียรกว่าเมื่อข้อมูลในตารางมีการเปลี่ยนแปลง
  • Modern Syntax: ใช้ Arrow Functions (=>) และ Template Literals (backticks `) ทำให้โค้ดอ่านง่ายขึ้น
  • Data Update: การใช้ dataTableInstance.rows.add(data).draw() เป็นวิธีมาตรฐานของ DataTables API ที่ดีกว่าการเข้าไปแก้ไขค่าใน settings() โดยตรงครับ

อ่านเพิ่มเติม