آموزش جامع DataTables
jQuery Plugin قدرتمند برای جداول پیشرفته — جستجو، مرتبسازی، صفحهبندی، فیلتر و Ajax.
📦معرفی و نصب
DataTables یک jQuery plugin است که جداول HTML ساده را به جداول پیشرفته با جستجو، مرتبسازی، صفحهبندی و فیلتر تبدیل میکند — فقط با یک خط کد!
نصب
<!-- ۱. jQuery (اجباری، باید قبل از DataTables باشد) --> <script src="jquery.min.js"></script> <!-- ۲. DataTables CSS --> <link rel="stylesheet" href="css/jquery.dataTables.min.css"> <!-- ۳. DataTables JS --> <script src="js/jquery.dataTables.min.js"></script>
فعالسازی — یک خط کد
// هر table با id="myTable" را به DataTable تبدیل میکند $(document).ready(function() { $('#myTable').DataTable(); });
jquery.min.js را قبل از jquery.dataTables.min.js لود کنید. همچنین جدول HTML شما باید <thead> و <tbody> داشته باشد.
📋جدول پایه — دمو زنده
جدول زیر کاملاً فعال است — جستجو کنید، روی هدرها کلیک کنید، تعداد نمایش را تغییر دهید:
| نام | شغل | شهر | سن | حقوق (تومان) |
|---|---|---|---|---|
| علی محمدی | مهندس نرمافزار | تهران | 28 | ۱۵,۰۰۰,۰۰۰ |
| فاطمه رضایی | طراح UI/UX | اصفهان | 25 | ۱۲,۰۰۰,۰۰۰ |
| حسن کریمی | مدیر پروژه | مشهد | 35 | ۲۵,۰۰۰,۰۰۰ |
| زهرا احمدی | دادهکاو | شیراز | 30 | ۱۸,۰۰۰,۰۰۰ |
| محمد حسینی | مهندس DevOps | تهران | 32 | ۲۰,۰۰۰,۰۰۰ |
| مریم نوری | مهندس Frontend | کرج | 27 | ۱۴,۰۰۰,۰۰۰ |
| رضا صادقی | مهندس Backend | تبریز | 29 | ۱۶,۰۰۰,۰۰۰ |
| نگار موسوی | محقق هوش مصنوعی | تهران | 31 | ۲۲,۰۰۰,۰۰۰ |
| امیر قاسمی | مهندس امنیت | اهواز | 33 | ۲۱,۰۰۰,۰۰۰ |
| سارا ملکی | مهندس موبایل | اصفهان | 26 | ۱۳,۰۰۰,۰۰۰ |
| پیمان خانی | مشاور فناوری | تهران | 40 | ۳۵,۰۰۰,۰۰۰ |
| شیرین باقری | تحلیلگر داده | مشهد | 28 | ۱۷,۰۰۰,۰۰۰ |
<!-- ساختار جدول HTML --> <table id="myTable" class="display" style="width:100%"> <thead> <tr><th>نام</th><th>شغل</th><th>شهر</th></tr> </thead> <tbody> <tr><td>علی محمدی</td><td>مهندس</td><td>تهران</td></tr> <!-- ... --> </tbody> </table> // JavaScript — یک خط $('#myTable').DataTable();
⚙گزینههای اصلی
$('#myTable').DataTable({ // صفحهبندی pageLength: 10, lengthMenu: [[5, 10, 25, 50, -1], ['۵', '۱۰', '۲۵', '۵۰', 'همه']], // نمایش/مخفی کنترلها searching: true, // نوار جستجو ordering: true, // مرتبسازی با کلیک paging: true, // صفحهبندی info: true, // متن "نمایش X از Y" // مرتبسازی پیشفرض: ستون 0، صعودی order: [[0, 'asc']], // چیدمان المانهای DataTables dom: 'lfrtip', // l=length, f=filter, r=processing, t=table, i=info, p=pagination // اسکرول به جای صفحهبندی // scrollY: '300px', scrollCollapse: true, // بهینهسازی deferRender: true, // render فقط وقتی نیاز است (برای دادههای زیاد) });
| کتاب | نویسنده | ژانر | سال | صفحه |
|---|---|---|---|---|
| بوف کور | صادق هدایت | رمان | ۱۳۱۵ | ۱۱۰ |
| شازده کوچولو | سنت اگزوپری | داستان | ۱۹۴۳ | ۹۶ |
| کیمیاگر | پائولو کوئلیو | فلسفی | ۱۹۸۸ | ۲۰۸ |
| صد سال تنهایی | گابریل مارکز | رمان | ۱۹۶۷ | ۴۲۰ |
| جنایت و مکافات | داستایوفسکی | روانشناختی | ۱۸۶۶ | ۵۶۰ |
| پیرمرد و دریا | ارنست همینگوی | داستان | ۱۹۵۲ | ۱۲۷ |
| داستان ندیمه | مارگارت اتوود | دیستوپیا | ۱۹۸۵ | ۳۱۱ |
🏳زبان فارسی و RTL
DataTables بهصورت کامل از فارسی و RTL پشتیبانی میکند. دو کار باید انجام دهید: تنظیم language و تنظیم CSS برای RTL.
تنظیم language فارسی
var persianLang = { search: 'جستجو:', searchPlaceholder: 'جستجو در جدول...', lengthMenu: 'نمایش _MENU_ رکورد', info: 'نمایش _START_ تا _END_ از _TOTAL_ رکورد', infoEmpty: 'رکوردی برای نمایش وجود ندارد', infoFiltered: '(فیلتر از _MAX_ رکورد کل)', zeroRecords: 'نتیجهای یافت نشد', emptyTable: 'جدول خالی است', loadingRecords: 'در حال بارگذاری...', processing: 'در حال پردازش...', paginate: { first: 'اول', last: 'آخر', next: '›', previous: '‹' }, aria: { sortAscending: ': مرتبسازی صعودی', sortDescending: ': مرتبسازی نزولی' } }; $('#myTable').DataTable({ language: persianLang });
CSS برای RTL
/* اجباری برای RTL */ .dataTables_wrapper { direction: rtl; text-align: right; } /* تنظیم margin input جستجو */ .dataTables_filter input { margin-right: 0.5em; margin-left: 0; } /* تنظیم margin select تعداد */ .dataTables_length select { margin: 0 0 0 0.5em; }
cdn.datatables.net/plug-ins/1.10.21/i18n/Persian.json بارگذاری کنید یا همان آبجکت فارسی بالا را یک بار در پروژه تعریف و در همه جداول استفاده کنید.
📄تنظیم ستونها
columnDefs — تنظیم بر اساس index
$('#myTable').DataTable({ columnDefs: [ { orderable: false, targets: 0 }, // ستون 0: مرتبسازی غیرفعال { visible: false, targets: 3 }, // ستون 3: مخفی { width: '120px', targets: 4 }, // ستون 4: عرض ثابت { className: 'text-center', targets: [1,2] }, // ستونهای 1 و 2: وسطچین // رنگبندی شرطی با render { targets: 2, render: function(data, type, row) { if (type !== 'display') return data; // sort/filter با مقدار اصلی var color = data >= 90 ? '#27ae60' : data >= 60 ? '#f39c12' : '#e74c3c'; return '<b style="color:' + color + '">' + data + '</b>'; } }, // نمایش دکمه عملیات { targets: -1, // آخرین ستون orderable: false, searchable: false, render: function(data, type, row) { return '<button onclick="editRow(' + row[0] + ')">ویرایش</button>'; } } ] });
| دانشجو | درس | نمره | پیشرفت | وضعیت | عملیات |
|---|
🌐Ajax و داده JavaScript
بارگذاری از URL (Ajax)
$('#myTable').DataTable({ ajax: { url: '/api/users', type: 'GET', data: { department: 'IT', status: 'active' } }, columns: [ { data: 'name', title: 'نام' }, { data: 'email', title: 'ایمیل' }, { data: 'city', title: 'شهر' } ] }); // آرایه تودرتو از JSON (dataSrc) $('#myTable').DataTable({ ajax: { url: '/api/data', dataSrc: 'users' // response.users } });
بارگذاری از آرایه JavaScript
$('#myTable').DataTable({ data: [ { name: 'علی', email: 'ali@ex.com', city: 'تهران', score: 92 }, { name: 'فاطمه', email: 'f@ex.com', city: 'اصفهان', score: 85 } ], columns: [ { data: 'name', title: 'نام' }, { data: 'email', title: 'ایمیل' }, { data: 'city', title: 'شهر' }, { data: 'score', title: 'امتیاز' } ] });
| نام | ایمیل | شهر | امتیاز |
|---|
⚡API و کنترل برنامهای
// ذخیره instance در متغیر var table = $('#myTable').DataTable(); // جستجوی برنامهای table.search('تهران').draw(); // مرتبسازی: ستون 1، نزولی table.order([[1, 'desc']]).draw(); // رفتن به صفحه 2 (از 0) table.page(1).draw('page'); // اضافه کردن ردیف table.row.add(['نام', 'شغل', 'شهر']).draw(); // اضافه کردن ردیف از object table.row.add({ name: 'علی', city: 'تهران' }).draw(); // حذف ردیف با node $('#myTable tbody').on('click', 'tr', function() { table.row(this).remove().draw(); }); // دریافت داده همه ردیفها var allData = table.rows().data().toArray(); // آپدیت سلول table.cell(0, 1).data('مقدار جدید').draw(); // reload Ajax table.ajax.reload(); // reload بدون reset صفحه table.ajax.reload(null, false);
| نام | شهر | سن |
|---|---|---|
| علی رضایی | تهران | 28 |
| سارا محمدی | اصفهان | 24 |
| رضا کریمی | تهران | 31 |
| نرگس احمدی | مشهد | 26 |
| محسن نوری | شیراز | 35 |
| گلنار باقری | تبریز | 29 |
👉Row Events و انتخاب ردیف
با گوش دادن به رویدادهای ردیف میتوانید جزئیات ردیف را نمایش دهید، ردیف را انتخاب کنید یا عملیاتی انجام دهید.
var table = $('#myTable').DataTable(); // کلیک روی ردیف $('#myTable tbody').on('click', 'tr', function() { var rowData = table.row(this).data(); console.log('ردیف انتخاب شد:', rowData); // toggle کلاس selected $(this).toggleClass('selected'); }); // Hover روی ردیف $('#myTable tbody') .on('mouseenter', 'tr', function() { $(this).css('background', '#e8f5d9'); }) .on('mouseleave', 'tr', function() { $(this).css('background', ''); }); // دریافت داده ردیفهای انتخابشده var selected = table.rows('.selected').data().toArray(); // رویداد draw — بعد از هر آپدیت جدول table.on('draw', function() { console.log('جدول رسم شد — صفحه:', table.page.info().page); });
روی هر ردیف کلیک کنید تا انتخاب شود. کلیک مجدد = لغو انتخاب
| نام | شغل | شهر | سن | حقوق |
|---|---|---|---|---|
| علی محمدی | مهندس نرمافزار | تهران | 28 | ۱۵ میلیون |
| فاطمه رضایی | طراح UI | اصفهان | 25 | ۱۲ میلیون |
| حسن کریمی | مدیر پروژه | مشهد | 35 | ۲۵ میلیون |
| زهرا احمدی | دادهکاو | شیراز | 30 | ۱۸ میلیون |
| محمد حسینی | DevOps | تهران | 32 | ۲۰ میلیون |
| مریم نوری | Frontend | کرج | 27 | ۱۴ میلیون |
🔍فیلتر ستونها
DataTables بهصورت پیشفرض یک جستجوی سراسری دارد. برای فیلتر جداگانه هر ستون، باید inputهای اختصاصی اضافه کنید.
// اضافه کردن input به هر ستون در tfoot $('#myTable tfoot th').each(function() { var title = $(this).text(); $(this).html('<input type="text" placeholder="' + title + '" class="col-filter">'); }); var table = $('#myTable').DataTable(); // اعمال فیلتر ستون table.columns().every(function() { var col = this; $('input', this.footer()).on('keyup change', function() { if (col.search() !== this.value) { col.search(this.value).draw(); } }); }); // فیلتر با select dropdown var col = table.column(2); // ستون 2 col.data().unique().sort().each(function(val) { select.append('<option value="' + val + '">' + val + '</option>'); }); select.on('change', function() { col.search( $(this).val() ).draw(); });
در هر ستون جداگانه جستجو کنید:
| نام | شغل | شهر | سن |
|---|---|---|---|
| نام | شغل | شهر | سن |
| علی محمدی | مهندس نرمافزار | تهران | 28 |
| فاطمه رضایی | طراح UI | اصفهان | 25 |
| حسن کریمی | مدیر پروژه | مشهد | 35 |
| زهرا احمدی | دادهکاو | شیراز | 30 |
| محمد حسینی | مهندس DevOps | تهران | 32 |
| مریم نوری | مهندس Frontend | کرج | 27 |
| رضا صادقی | مهندس Backend | تبریز | 29 |
| نگار موسوی | هوش مصنوعی | تهران | 31 |
⚖Server-Side و Performance
Server-Side Processing
برای جداول با بیش از ۱۰,۰۰۰ رکورد، Server-Side processing توصیه میشود. DataTables پارامترهای جستجو، مرتبسازی و صفحهبندی را به سرور میفرستد.
// Client: فعالسازی Server-Side $('#myTable').DataTable({ serverSide: true, ajax: { url: '/api/table-data', type: 'POST' }, columns: [ { data: 'name' }, { data: 'email' }, { data: 'city' } ] }); // Server: پارامترهای ارسالشده توسط DataTables // { // draw: 1, // شماره request // start: 0, // شروع از رکورد n // length: 10, // تعداد رکورد // search: { value: '' }, // متن جستجو // order: [{ column:0, dir:'asc' }] // } // Server: فرمت پاسخ // { // draw: 1, // recordsTotal: 1000, // کل رکوردها // recordsFiltered: 850, // بعد از فیلتر // data: [...] // رکوردهای این صفحه // }
بهینهسازی Performance
| گزینه | کاربرد | کی استفاده کنیم |
|---|---|---|
deferRender: true | render فقط وقتی نمایش داده میشود | بیش از ۱۰۰۰ رکورد |
scrollY: '400px' | اسکرول به جای صفحهبندی | جدولهای بلند |
serverSide: true | پردازش روی سرور | بیش از ۱۰,۰۰۰ رکورد |
stateSave: true | ذخیره وضعیت در localStorage | حفظ فیلتر بعد از refresh |
destroy: true | destroy قبل از re-init | آپدیت دادههای Ajax |
processing: true | نمایش indicator بارگذاری | همراه serverSide |
نمونههای کاملتر
// ذخیره state و scroll $('#myTable').DataTable({ stateSave: true, // localStorage scrollY: '400px', scrollCollapse: true, deferRender: true, language: persianLang }); // چک کردن آیا DataTable شده if ($.fn.dataTable.isDataTable('#myTable')) { $('#myTable').DataTable().destroy(); } $('#myTable').DataTable({ /* ... */ }); // فیلتر با regex (جستجوی دقیق) table.search('^تهران$', true, false).draw(); // regex regex smart
- زیر ۵۰۰۰ رکورد: بارگذاری همه در client +
deferRender - ۵۰۰۰ تا ۵۰,۰۰۰ رکورد: بارگذاری همه +
scrollYبه جای pagination - بیشتر از ۵۰,۰۰۰ رکورد:
serverSide: trueاجباری است
🚀زمین بازی کد (Playground)
یک جدول HTML بساز و با یک خط $('#tbl').DataTable() آن را به جدول حرفهای (جستجو، مرتبسازی، صفحهبندی) تبدیل کن. گزینهها و زبان فارسی را تغییر بده و ▶ اجرا را بزن. jQuery و DataTables نسخهٔ ۱.۱۰.۲۱ آفلاین بارگذاری میشوند.