├── CHANGELOG.md ├── README.md ├── js ├── buttons │ ├── add.js │ ├── ajax.js │ ├── ajaxBatch.js │ ├── csv.js │ ├── duplicate.js │ ├── duplicateSingle.js │ ├── excel.js │ ├── export.js │ ├── forceDelete.js │ ├── forceDeleteSingle.js │ ├── helper.js │ ├── pdf.js │ ├── plugins.js │ ├── print.js │ ├── reload.js │ ├── reset.js │ ├── restore.js │ ├── softDeletes.js │ ├── toggleScope.js │ └── url.js ├── dataTables.buttons.js ├── dataTables.renderers.js └── index.js ├── package.json └── publish.sh /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Laravel DataTables Vite CHANGELOG 2 | 3 | ## v0.6.1 - 2024-12-13 4 | 5 | - Fix reload button text #12 6 | 7 | ## v0.6.0 - 2024-11-14 8 | 9 | - Upgrade to DataTables 2 #11 10 | 11 | ## v0.5.3 - 2024-11-14 12 | 13 | - Improve ajaxBatch button confirmation message #10 14 | 15 | ## v0.5.2 - 2023-02-09 16 | 17 | - fix: editor modal error #51a126e 18 | - editor.bootstrap5.js:153 Uncaught TypeError: Cannot read properties of undefined (reading 'Modal') 19 | - possible fix for: #3 20 | 21 | ## v0.5.1 - 2022-02-09 22 | 23 | - fix: remove btn-secondary #a31b113 24 | 25 | ## v0.5.0 - 2022-11-10 26 | 27 | - Compatibility with DataTables 1.13's ES modules #2 28 | 29 | ## v0.4.0 - 2022-10-09 30 | 31 | - Fix installation of dependencies 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel, DataTables, Bootstrap and Vite 2 | 3 | Get started with Laravel, DataTables, Bootstrap and Vite in a few minutes. 4 | 5 | ## Installation 6 | 7 | `npm i laravel-datatables-vite --save-dev` 8 | 9 | ## Setup 10 | 11 | Add the following to your `resources/js/app.js` file: 12 | 13 | ```js 14 | import 'laravel-datatables-vite'; 15 | ``` 16 | 17 | Add the following to your `resources/sass/app.scss` file: 18 | 19 | ```css 20 | @import "bootstrap-icons/font/bootstrap-icons.min.css"; 21 | @import "datatables.net-bs5/css/dataTables.bootstrap5.min.css"; 22 | @import "datatables.net-buttons-bs5/css/buttons.bootstrap5.min.css"; 23 | @import "datatables.net-select-bs5/css/select.bootstrap5.min.css"; 24 | ``` 25 | 26 | ## Quick Starter 27 | 28 | A [quick starter guide](https://yajrabox.com/docs/laravel-datatables/quick-starter) is available at the official package docs. 29 | -------------------------------------------------------------------------------- /js/buttons/add.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables add button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('add')->text(' Add') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.add = { 11 | name: 'add', 12 | className: 'buttons-add btn-success', 13 | text: ' New', 14 | action: function (e, dt, button, config) { 15 | let uri = window.location.toString(); 16 | if (uri.indexOf("?") > 0) { 17 | uri = uri.substring(0, uri.indexOf("?")); 18 | } 19 | window.location = uri + '/create'; 20 | } 21 | }; 22 | }); 23 | -------------------------------------------------------------------------------- /js/buttons/ajax.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables Ajax button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * // Add DTE_AJAX column to response. 7 | * datatables($query) 8 | * ->addColumn('DTE_AJAX', '{{ $url }}') 9 | * ->addColumn('restore_url', '{{ $url }}') 10 | * ... 11 | * 12 | * Button::make('ajax') 13 | * ->text('Restore') 14 | * ->confirmation('Generic confirmation message.') // Optional if you want confirmation before proceeding. 15 | * ->onCancel('function(response) { alert('confirmation cancelled') }') 16 | * ->onSuccess('function(response) { alert('success') }') 17 | * ->onError('function(err) { alert('error') }') 18 | * ->method('POST') // default ajax method is POST. 19 | * 20 | * Button::make('ajax') 21 | * ->text('Restore') 22 | * ->data('restore_url') 23 | * ->onSuccess('function(response) { alert('success') }') 24 | * ->onError('function(err) { alert('error') }') 25 | * 26 | */ 27 | document.addEventListener('DOMContentLoaded', function () { 28 | DataTable.ext.buttons.ajax = { 29 | name: 'ajax', 30 | extend: 'selectedSingle', 31 | className: 'buttons-ajax', 32 | text: 'Ajax Action (Change Me)', 33 | action: function (e, dt, node, config) { 34 | let data = dt.row({selected: true}).data(); 35 | let url = data[(config.data || 'DTE_AJAX')] || ''; 36 | let method = config.method || 'POST'; 37 | 38 | if (config.hasOwnProperty('confirmation')) { 39 | if (! confirm(config.confirmation)) { 40 | if (config.hasOwnProperty('onCancel')) config.onCancel(); 41 | 42 | return false; 43 | } 44 | } 45 | 46 | $.ajax({ 47 | url: url, 48 | method: method, 49 | data: data 50 | }).done(response => { 51 | if (config.hasOwnProperty('onSuccess')) config.onSuccess(response) 52 | 53 | dt.draw(); 54 | }).fail(err => { 55 | if (config.hasOwnProperty('onError')) config.onError(err) 56 | }) 57 | } 58 | }; 59 | }); 60 | -------------------------------------------------------------------------------- /js/buttons/ajaxBatch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables Batch Ajax action button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('ajaxBatch') 7 | * ->text('Restore') 8 | * ->url(route('batch-restore-action-url')) 9 | * ->confirmation('Confirm restore _COUNT_ item_PLURAL_?') // Optional if you want confirmation before proceeding. 10 | * ->onCancel('function(response) { alert('confirmation cancelled') }') 11 | * ->onSuccess('function(response) { alert('success') }') 12 | * ->onError('function(err) { alert('error') }') 13 | * 14 | */ 15 | document.addEventListener('DOMContentLoaded', function () { 16 | DataTable.ext.buttons.ajaxBatch = { 17 | name: 'ajaxBatch', 18 | extend: 'selected', 19 | className: 'buttons-ajax', 20 | text: 'Ajax Batch Action (Change Me)', 21 | action: function (e, dt, node, config) { 22 | const selected = dt.rows({selected: true}).data(); 23 | const formData = { data: [] }; 24 | for (let i = 0; i < selected.count(); i++) { 25 | formData.data.push(selected[i]); 26 | } 27 | 28 | if (config.hasOwnProperty('confirmation')) { 29 | const confirmation = config.confirmation 30 | .replaceAll("_COUNT_", selected.length) 31 | .replaceAll("_PLURAL_", selected.length > 1 ? "s" : ""); 32 | if (! confirm(confirmation)) { 33 | if (config.hasOwnProperty('onCancel')) config.onCancel(); 34 | 35 | return false; 36 | } 37 | } 38 | 39 | const url = config.url || ''; 40 | const method = config.method || 'POST'; 41 | 42 | $.ajax({ 43 | url: url, 44 | method: method, 45 | data: formData 46 | }).done(response => { 47 | if (config.hasOwnProperty('onSuccess')) config.onSuccess(response); 48 | 49 | dt.draw(); 50 | }).fail(err => { 51 | if (config.hasOwnProperty('onError')) config.onError(err); 52 | }) 53 | } 54 | }; 55 | }); 56 | -------------------------------------------------------------------------------- /js/buttons/csv.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables csv button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('csv')->text(' Export to CSV') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.csv = { 11 | name: 'csv', 12 | className: 'buttons-csv btn-primary', 13 | titleAttr: 'Export as CSV', 14 | text: '', 15 | action: function (e, dt, button, config) { 16 | window.location = _buildUrl(dt, 'csv'); 17 | } 18 | }; 19 | }); 20 | -------------------------------------------------------------------------------- /js/buttons/duplicate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables duplicate button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('duplicate') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.duplicate = { 11 | name: 'duplicate', 12 | extend: 'selected', 13 | className: 'buttons-duplicate btn-success', 14 | text: ' Duplicate', 15 | action: function (e, dt, node, config) { 16 | // Start in edit mode, and then change to create 17 | let editor = config.editor || dt.editor(); 18 | editor.edit(dt.rows({selected: true}).indexes(), { 19 | title: config.formTitle || 'Duplicate Record', 20 | buttons: config.formButtons || [ 21 | { 22 | text: ' Duplicate', 23 | className: 'btn btn-success btn-editor-duplicate', 24 | action: function () { 25 | this.submit(); 26 | } 27 | }, 28 | { 29 | text: 'Cancel', className: 'btn ml-2', action: function () { 30 | this.close(); 31 | } 32 | } 33 | ] 34 | }).mode('create'); 35 | } 36 | }; 37 | }); 38 | -------------------------------------------------------------------------------- /js/buttons/duplicateSingle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables duplicateSingle button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('duplicateSingle') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.duplicateSingle = { 11 | name: 'duplicateSingle', 12 | extend: 'selectedSingle', 13 | className: 'buttons-duplicate btn-success', 14 | text: ' Duplicate', 15 | action: function (e, dt, node, config) { 16 | // Start in edit mode, and then change to create 17 | let editor = config.editor || dt.editor(); 18 | editor.edit(dt.rows({selected: true}).indexes(), { 19 | title: config.formTitle || 'Duplicate Record', 20 | buttons: config.formButtons || [ 21 | { 22 | text: ' Duplicate', 23 | className: 'btn btn-success btn-editor-duplicate', 24 | action: function () { 25 | this.submit(); 26 | } 27 | }, 28 | { 29 | text: 'Cancel', className: 'btn ml-2', action: function () { 30 | this.close(); 31 | } 32 | } 33 | ] 34 | }).mode('create'); 35 | } 36 | }; 37 | }); 38 | -------------------------------------------------------------------------------- /js/buttons/excel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables excel button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('excel') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.excel = { 11 | name: 'excel', 12 | className: 'buttons-excel btn-primary', 13 | titleAttr: 'Export as Excel', 14 | text: '', 15 | action: function (e, dt, button, config) { 16 | window.location = _buildUrl(dt, 'excel'); 17 | } 18 | }; 19 | }); 20 | -------------------------------------------------------------------------------- /js/buttons/export.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables export button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('export') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.export = { 11 | name: 'export', 12 | extend: 'collection', 13 | className: 'btn-primary', 14 | text: 'Export ', 15 | buttons: [ 16 | {extend: 'csv', text: 'CSV'}, 17 | {extend: 'excel', text: 'Excel'}, 18 | {extend: 'pdf', text: 'PDF'} 19 | ] 20 | }; 21 | }); 22 | -------------------------------------------------------------------------------- /js/buttons/forceDelete.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables forceDelete button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('forceDelete')->text('Permanently Delete Selected Records') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.forceDelete = { 11 | name: 'forceDelete', 12 | extend: 'selected', 13 | className: 'buttons-force-delete btn-danger', 14 | text: ' Force Delete', 15 | action: function (e, dt, node, config) { 16 | let editor = config.editor || dt.editor(); 17 | editor.remove(dt.rows({selected: true}).indexes(), { 18 | title: config.formTitle || 'Force Delete Record(/s)', 19 | message: function (e, dt) { 20 | let data = dt.rows(e.modifier()).data(); 21 | let rows = data[0].hasOwnProperty('DTE_Remove') ? data.pluck('DTE_Remove') : data.pluck('DT_RowId') 22 | return 'Are you sure you want to force delete the ' + 23 | 'following record(s)? '; 24 | }, 25 | buttons: [ 26 | { 27 | text: ' Delete', 28 | className: 'btn btn-danger btn-editor-remove', 29 | action: function () { 30 | this.submit(null, null, function (data) { 31 | data.action = 'forceDelete'; 32 | }); 33 | } 34 | }, 35 | { 36 | text: 'Cancel', className: 'btn ml-2', action: function () { 37 | this.close(); 38 | } 39 | } 40 | ] 41 | }); 42 | } 43 | }; 44 | }); 45 | -------------------------------------------------------------------------------- /js/buttons/forceDeleteSingle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables forceDeleteSingle button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('forceDeleteSingle')->text('Permanently Delete Selected Record') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.forceDeleteSingle = { 11 | name: 'forceDeleteSingle', 12 | extend: 'selectedSingle', 13 | className: 'buttons-force-delete btn-danger', 14 | text: ' Force Delete', 15 | action: function (e, dt, node, config) { 16 | let editor = config.editor || dt.editor(); 17 | editor.remove(dt.rows({selected: true}).indexes(), { 18 | title: config.formTitle || 'Force Delete Record', 19 | message: function (e, dt) { 20 | let row = dt.row({selected: true}).data(); 21 | let msg = row.DTE_Remove || 'Are you sure you want to force delete record # ' + row.DT_RowId + '?' 22 | return msg; 23 | }, 24 | buttons: [ 25 | { 26 | text: ' Delete', 27 | className: 'btn btn-danger btn-editor-remove', 28 | action: function () { 29 | this.submit(null, null, function (data) { 30 | data.action = 'forceDelete'; 31 | }); 32 | } 33 | }, 34 | { 35 | text: 'Cancel', className: 'btn ml-2', action: function () { 36 | this.close(); 37 | } 38 | } 39 | ] 40 | }); 41 | } 42 | }; 43 | }); 44 | -------------------------------------------------------------------------------- /js/buttons/helper.js: -------------------------------------------------------------------------------- 1 | window._buildUrl = function (dt, action) { 2 | let url = dt.ajax.url() || ''; 3 | let params = dt.ajax.params(); 4 | params.action = action; 5 | 6 | return url + '?' + $.param(params); 7 | }; 8 | -------------------------------------------------------------------------------- /js/buttons/pdf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables pdf button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('pdf')->text('Export to PDF') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.pdf = { 11 | name: 'pdf', 12 | className: 'buttons-pdf btn-primary', 13 | titleAttr: 'Export as PDF', 14 | text: '', 15 | action: function (e, dt, button, config) { 16 | window.location = _buildUrl(dt, 'pdf'); 17 | } 18 | }; 19 | }); 20 | -------------------------------------------------------------------------------- /js/buttons/plugins.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', function () { 2 | let oTable = $('table'); 3 | oTable.on('select.dt', function (e, dt, type, indexes) { 4 | dt.rows({selected: true}).every(function (rowIdx, tableLoop, rowLoop) { 5 | var data = this.data(); 6 | if (data.deleted_at == null) { 7 | dt.button('restore:name').disable(); 8 | dt.button('forceDelete:name').disable(); 9 | dt.button('forceDeleteSingle:name').disable(); 10 | } 11 | }); 12 | }); 13 | 14 | oTable.on('deselect.dt', function (e, dt, type, indexes) { 15 | dt.rows({selected: true}).every(function (rowIdx, tableLoop, rowLoop) { 16 | var data = this.data(); 17 | if (data.deleted_at == null) { 18 | dt.button('restore:name').disable(); 19 | dt.button('forceDelete:name').disable(); 20 | dt.button('forceDeleteSingle:name').disable(); 21 | } 22 | }); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /js/buttons/print.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables print button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('print') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.print = { 11 | name: 'print', 12 | className: 'buttons-print btn-primary', 13 | titleAttr: 'Print', 14 | text: '', 15 | action: function (e, dt, button, config) { 16 | window.location = _buildUrl(dt, 'print'); 17 | } 18 | }; 19 | }); 20 | -------------------------------------------------------------------------------- /js/buttons/reload.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables reload button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('reload') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.reload = { 11 | name: 'reload', 12 | className: 'btn-primary', 13 | titleAttr: 'Reload', 14 | text: '', 15 | action: function (e, dt, button, config) { 16 | dt.draw(false); 17 | }, 18 | init: function (dt, node, config) { 19 | let instance = this; 20 | dt.on('processing.dt', (e, settings, processing) => { 21 | let button = $(node); 22 | 23 | if (processing) { 24 | button.html('\n' + 25 | ' Loading...\n' + 26 | ''); 27 | } else { 28 | button.html(config.text); 29 | } 30 | 31 | button.attr('disabled', processing); 32 | }); 33 | }, 34 | }; 35 | }); 36 | -------------------------------------------------------------------------------- /js/buttons/reset.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables reset button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('reset') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.reset = { 11 | name: 'reset', 12 | className: 'btn-primary', 13 | titleAttr: 'Reset', 14 | text: '', 15 | action: function (e, dt, button, config) { 16 | $('.dataTable').find(':input').each(function () { 17 | $(this).val(''); 18 | }).each(function (e) { 19 | let val = DataTable.util.escapeRegex($(this).val()); 20 | dt.table().column($(this).closest('th').index()).search(val ? val : '', false, true); 21 | }); 22 | dt.search('').draw(); 23 | } 24 | }; 25 | }); 26 | -------------------------------------------------------------------------------- /js/buttons/restore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables restore button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Button::make('restore')->text('Restore Selected Records') 7 | * 8 | */ 9 | document.addEventListener('DOMContentLoaded', function () { 10 | DataTable.ext.buttons.restore = { 11 | name: 'restore', 12 | extend: 'selected', 13 | className: 'buttons-restore btn-success', 14 | text: ' Restore', 15 | action: function (e, dt, node, config) { 16 | let editor = config.editor || dt.editor(); 17 | editor.remove(dt.rows({selected: true}).indexes(), { 18 | title: config.formTitle || 'Restore Record', 19 | message: function (e, dt) { 20 | let row = dt.row({selected: true}).data(); 21 | let msg = row.DTE_Restore || 'Are you sure you want to restore record # ' + row.DT_RowId + '?' 22 | return msg; 23 | }, 24 | buttons: [ 25 | { 26 | text: ' Restore', 27 | className: 'btn btn-success btn-editor-restore', 28 | action: function () { 29 | this.submit(null, null, function (data) { 30 | data.action = 'restore'; 31 | }); 32 | } 33 | }, 34 | { 35 | text: 'Cancel', className: 'btn ml-2', action: function () { 36 | this.close(); 37 | } 38 | } 39 | ] 40 | }) 41 | } 42 | }; 43 | }); 44 | -------------------------------------------------------------------------------- /js/buttons/softDeletes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables withTrashed button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Note: toggle function currently depends on 'fa-square'. Be sure to include it when overriding the text. 7 | * 8 | * Button::make('withTrashed')->text(' Show Deleted') 9 | * 10 | * This will append the following data on ajax requests: 11 | * draw: 1, 12 | * ... 13 | * scopes[withTrashed] = 0 / 1 14 | * 15 | * -- Using custom data key -- 16 | * Button::make('withTrashed')->text(' Show Deleted')->key('filters') 17 | * 18 | * This will append the following data on ajax requests: 19 | * draw: 1, 20 | * ... 21 | * filters[withTrashed] = 0 / 1 22 | * 23 | */ 24 | document.addEventListener('DOMContentLoaded', function () { 25 | DataTable.ext.buttons.withTrashed = { 26 | name: 'withTrashed', 27 | className: 'buttons-toggle', 28 | text: ' Show Deleted', 29 | action: function (e, dt, node, config) { 30 | node.find('i').toggleClass('fa-check-square').toggleClass('fa-square'); 31 | 32 | let key = config.key || 'scopes'; 33 | dt.on('preXhr.withTrashed', (e, conf, data) => { 34 | data[key] = data[key] || {}; 35 | data[key].withTrashed = node.find('i.fa-check-square').length 36 | }); 37 | 38 | dt.draw(); 39 | } 40 | }; 41 | 42 | 43 | /** 44 | * DataTables onlyTrashed button. 45 | * 46 | * -- Laravel Integration -- 47 | * 48 | * Note: toggle function currently depends on 'fa-square'. Be sure to include it when overriding the text. 49 | * 50 | * Button::make('onlyTrashed')->text(' Only Deleted') 51 | * 52 | * This will append the following data on ajax requests: 53 | * draw: 1, 54 | * ... 55 | * scopes[onlyTrashed] = 0 / 1 56 | * 57 | * -- Using custom data key -- 58 | * Button::make('onlyTrashed')->text(' Only Deleted')->key('filters') 59 | * 60 | * This will append the following data on ajax requests: 61 | * draw: 1, 62 | * ... 63 | * filters[onlyTrashed] = 0 / 1 64 | * 65 | */ 66 | DataTable.ext.buttons.onlyTrashed = { 67 | name: 'onlyTrashed', 68 | className: 'buttons-toggle', 69 | text: ' Only Deleted', 70 | action: function (e, dt, node, config) { 71 | node.find('i').toggleClass('fa-check-square').toggleClass('fa-square'); 72 | 73 | let key = config.key || 'scopes'; 74 | dt.on('preXhr.onlyTrashed', (e, conf, data) => { 75 | data[key] = data[key] || {}; 76 | data[key].onlyTrashed = node.find('i.fa-check-square').length 77 | }); 78 | 79 | dt.draw(); 80 | } 81 | }; 82 | }); 83 | -------------------------------------------------------------------------------- /js/buttons/toggleScope.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables Toggle Scope button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * Note: toggle function currently depends on 'bi-square'. Be sure to include it when overriding the text. 7 | * 8 | * Button::make('toggleScope') 9 | * ->text(' Only Deleted') 10 | * ->scope('onlyDeleted') 11 | * 12 | * This will append the following data on ajax requests: 13 | * draw: 1, 14 | * ... 15 | * scopes[onlyDeleted] = 0 / 1 16 | */ 17 | document.addEventListener('DOMContentLoaded', function () { 18 | DataTable.ext.buttons.toggleScope = { 19 | name: 'toggleScope', 20 | className: 'buttons-toggle', 21 | text: ' Toggle', 22 | action: function (e, dt, node, config) { 23 | node.find('i').toggleClass('bi-check-square').toggleClass('bi-square'); 24 | 25 | let scope = config.scope; 26 | let key = config.key || 'scopes'; 27 | dt.on('preXhr.' + scope, (e, conf, data) => { 28 | data[key] = data[key] || {}; 29 | data[key][scope] = node.find('i.bi-check-square').length 30 | }); 31 | 32 | dt.draw(); 33 | } 34 | }; 35 | }); 36 | -------------------------------------------------------------------------------- /js/buttons/url.js: -------------------------------------------------------------------------------- 1 | /** 2 | * DataTables URL button. 3 | * 4 | * -- Laravel Integration -- 5 | * 6 | * // Add DTE_URL column to response. 7 | * datatables($query) 8 | * ->addColumn('DTE_URL', '{{ $url }}') 9 | * ->addColumn('edit_url', '{{ $url }}') 10 | * ... 11 | * 12 | * // Add URL button to open the row link. 13 | * Button::make('url')->text('Edit'), 14 | * Button::make('url')->data('edit_url')->text('Edit') 15 | * 16 | */ 17 | document.addEventListener('DOMContentLoaded', function () { 18 | DataTable.ext.buttons.url = { 19 | name: 'url', 20 | extend: 'selectedSingle', 21 | className: 'buttons-url', 22 | text: 'URL Action (change me)', 23 | action: function (e, dt, node, config) { 24 | let data = dt.row({selected: true}).data(); 25 | let key = config.data || 'DTE_URL'; 26 | let url = data[key] || '#'; 27 | 28 | if (config.target == '_blank') { 29 | window.open(url, '_blank') 30 | } else { 31 | window.location = url; 32 | } 33 | } 34 | }; 35 | }); 36 | -------------------------------------------------------------------------------- /js/dataTables.buttons.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | import './buttons/helper'; 4 | import './buttons/plugins'; 5 | 6 | // Buttons 7 | import './buttons/add'; 8 | import './buttons/export'; 9 | import './buttons/csv'; 10 | import './buttons/excel'; 11 | import './buttons/pdf'; 12 | import './buttons/print'; 13 | import './buttons/reset'; 14 | import './buttons/reload'; 15 | import './buttons/restore'; 16 | import './buttons/duplicate'; 17 | import './buttons/duplicateSingle'; 18 | import './buttons/forceDelete'; 19 | import './buttons/forceDeleteSingle'; 20 | import './buttons/url'; 21 | import './buttons/ajax'; 22 | import './buttons/ajaxBatch'; 23 | import './buttons/toggleScope'; 24 | import './buttons/softDeletes'; 25 | -------------------------------------------------------------------------------- /js/dataTables.renderers.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | document.addEventListener('DOMContentLoaded', function () { 4 | DataTable.render.badge = function (badgeType) { 5 | return function (d, type, row) { 6 | if (!badgeType) { 7 | badgeType = 'info'; 8 | } 9 | 10 | return '' + d + '' 11 | }; 12 | }; 13 | 14 | DataTable.render.boolean = function () { 15 | return function (d) { 16 | let mode = 'danger'; 17 | let label = "N"; 18 | if (d || "1" === d) { 19 | mode = 'success'; 20 | label = "Y"; 21 | } 22 | 23 | return '' + label + '' 24 | }; 25 | }; 26 | 27 | 28 | DataTable.render.suffix = function (suffix) { 29 | return function (d) { 30 | return d + ' ' + suffix; 31 | }; 32 | }; 33 | 34 | DataTable.render.prefix = function (prefix) { 35 | return function (d) { 36 | return prefix + ' ' + d; 37 | }; 38 | }; 39 | 40 | }); -------------------------------------------------------------------------------- /js/index.js: -------------------------------------------------------------------------------- 1 | import $ from 'jquery'; 2 | window.jQuery = window.$ = $; 3 | 4 | import * as Bootstrap from 'bootstrap'; 5 | window.bootstrap = Bootstrap; 6 | 7 | import DataTable from 'datatables.net-bs5'; 8 | window.DataTable = DataTable; 9 | 10 | import 'datatables.net-buttons-bs5'; 11 | import 'datatables.net-select-bs5'; 12 | import './dataTables.buttons.js'; 13 | import './dataTables.renderers.js'; 14 | 15 | $.extend(true, DataTable.Buttons.defaults, { 16 | dom: { 17 | button: { 18 | liner: { 19 | tag: "" 20 | } 21 | }, 22 | }, 23 | }); 24 | 25 | $.extend(DataTable.ext.classes, { 26 | sTable: "dataTable table table-striped table-bordered table-hover", 27 | }); 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel-datatables-vite", 3 | "version": "0.6.2", 4 | "description": "Laravel DataTables with jQuery, Bootstrap and Vite", 5 | "main": "js/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/yajra/laravel-datatables-vite.git" 12 | }, 13 | "keywords": [ 14 | "yajra", 15 | "laravel", 16 | "dataTables", 17 | "vitejs", 18 | "bootstrap", 19 | "jquery" 20 | ], 21 | "author": { 22 | "name": "Arjay Angeles", 23 | "url": "https://yajrabox.com" 24 | }, 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/yajra/laravel-datatables-vite/issues" 28 | }, 29 | "homepage": "https://github.com/yajra/laravel-datatables-vite#readme", 30 | "dependencies": { 31 | "bootstrap": "^5.2.2", 32 | "bootstrap-icons": "^1.9.1", 33 | "datatables.net": "^2.1.8", 34 | "datatables.net-bs5": "^2.1.8", 35 | "datatables.net-buttons-bs5": "^3.1.2", 36 | "datatables.net-select-bs5": "^2.1.0", 37 | "jquery": "^3.6.1" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | version=0.6.2 4 | 5 | echo "Publishing version $version" 6 | 7 | git add . 8 | git commit -am "chore: release $version :rocket:" 9 | npm version $version 10 | git push origin main && git push origin main --tags 11 | 12 | npm publish 13 | --------------------------------------------------------------------------------