-
-
Save breizhwave/59090a27f46e12accee8c422a149819c to your computer and use it in GitHub Desktop.
Backpack CRUD - Persistent Filters/Pages/Searches
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- DATA TABLES SCRIPT BREIZHWAVE20181009 from https://github.com/Laravel-Backpack/CRUD/issues/1457#issuecomment-404576891 --> | |
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js" type="text/javascript"></script> | |
<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap.min.js" type="text/javascript"></script> | |
<script src="https://cdn.datatables.net/responsive/2.2.1/js/dataTables.responsive.min.js"></script> | |
<script src="https://cdn.datatables.net/responsive/2.2.1/js/responsive.bootstrap.min.js"></script> | |
<script> | |
var crud = { | |
enablePersistance: true, | |
route: 'DataTables_{{ trim($crud->getRoute(), '/') }}', | |
tableEl: jQuery('#crudTable'), | |
table: null, | |
allFilters: @json(method_exists($crud->filters, 'pluck') ? $crud->filters->pluck('name') : []), | |
exportButtons: @json($crud->export_buttons), | |
functionsToRunOnDataTablesDrawEvent: [], | |
addFunctionToDataTablesDrawEventQueue: function (functionName) { | |
if (this.functionsToRunOnDataTablesDrawEvent.indexOf(functionName) == -1) { | |
this.functionsToRunOnDataTablesDrawEvent.push(functionName); | |
} | |
}, | |
responsiveToggle: function (dt) { | |
$(dt.table().header()).find('th').toggleClass('all'); | |
dt.responsive.rebuild(); | |
dt.responsive.recalc(); | |
}, | |
executeFunctionByName: function (str, args) { | |
var arr = str.split('.'); | |
var fn = window[arr[0]]; | |
for (var i = 1; i < arr.length; i++) { | |
fn = fn[arr[i]]; | |
} | |
fn.apply(window, args); | |
}, | |
getUrlFromState() { | |
var url = crud.table.ajax.url(); | |
url = url.replace(/=0/g, '="0"'); | |
return url; | |
}, | |
setUrl(url) { | |
if (!crud.enablePersistance) return; | |
window.history.replaceState({}, document.title, url.replace('/search?', '').replace('/search', '')); | |
}, | |
updateFilterMessage() { | |
var queryStrings = new URLSearchParams(window.location.search); | |
var count = Array.from(queryStrings).length; | |
var title = jQuery('.content-header h1 small'); | |
if (!title.attr('data-text')) { | |
title.attr('data-text', title.text()); | |
} | |
if (count) { | |
title.text(count + ' filter(s) are currently applied.'); | |
title.addClass('text-danger'); | |
$('#remove_filters_button').removeClass('hidden'); | |
} else { | |
title.text(title.attr('data-text')); | |
title.removeClass('text-danger'); | |
} | |
}, | |
mapQueryStringsToFilters() { | |
if (!crud.enablePersistance) return; | |
var queryStrings = new URLSearchParams(window.location.search); | |
crud.updateFilterMessage(); | |
$.each(crud.allFilters, function (key, property) { | |
if (!queryStrings.has(property)) return; | |
var value = JSON.parse(queryStrings.get(property)); | |
jQuery('[filter-name="' + property + '"]').addClass('active'); | |
if (!isNaN(value) || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { | |
jQuery('a[parameter="' + property + '"][key="' + value + '"]').parent().addClass('active'); | |
} | |
if (typeof value === 'object') { | |
var select = jQuery('#filter_' + property); | |
select.find('option').prop('selected', false); | |
$.each(value, function (k, v) { | |
select.find('option[value="' + v + '"]').prop('selected', true) | |
}); | |
select.select2('destroy'); | |
select.select2({ | |
allowClear: true, | |
closeOnSelect: false | |
}); | |
} | |
}); | |
} | |
}; | |
var baseUrl = '{{ url($crud->route) }}/search'; | |
var startingUrl = (baseUrl + '?{{ request()->getQueryString() }}').replace(/\?+$/,''); | |
if (crud.enablePersistance) { | |
try { | |
if (document.referrer) { | |
var savedData = JSON.parse(localStorage.getItem(crud.route) || '{}'); | |
startingUrl = savedData.lastSearchUrl || startingUrl; | |
} else if (!window.location.search) { | |
startingUrl = baseUrl; | |
} | |
} catch { | |
// Oh well. | |
} | |
} | |
crud.dataTableConfiguration = { | |
stateSave: crud.enablePersistance, | |
stateSaveCallback: function (settings, data) { | |
data.lastSearchUrl = crud.getUrlFromState(); | |
localStorage.setItem(crud.route, JSON.stringify(data)); | |
crud.updateFilterMessage(); | |
}, | |
stateLoadCallback: function (settings) { | |
var data = JSON.parse(localStorage.getItem(crud.route) || '{}'); | |
data.lastSearchUrl = (data.lastSearchUrl || '').replace(/&/g, '&'); | |
if (document.referrer && data.lastSearchUrl.indexOf('search?') !== -1) { | |
setTimeout(function () { | |
crud.setUrl(data.lastSearchUrl.replace('/search?', '?')); | |
crud.table.ajax.url(data.lastSearchUrl); | |
crud.mapQueryStringsToFilters(); | |
}); | |
} else if (!window.location.search) { | |
data.lastSearchUrl = baseUrl; | |
crud.setUrl(baseUrl.replace('/search', '')); | |
} | |
return data; | |
}, | |
initComplete: function () { | |
crud.responsiveToggle(crud.table); | |
crud.table.on('xhr.dt', function () { | |
if (!crud.enablePersistance) return; | |
crud.setUrl(crud.table.ajax.url().replace('/search?', '?')); | |
}); | |
}, | |
@if ($crud->getResponsiveTable()) | |
responsive: { | |
details: { | |
display: $.fn.dataTable.Responsive.display.modal({ | |
header: function (row) { | |
return row.data[0]; | |
} | |
}), | |
renderer: function (api, rowIdx, columns) { | |
var data = $.map(columns, function (col, i) { | |
return '<tr data-dt-row="' + col.rowIndex + '" data-dt-column="' + col.columnIndex + '">' + | |
'<td><strong>' + col.title.trim() + ':' + '<strong></td> ' + | |
'<td>' + col.data + '</td>' + | |
'</tr>'; | |
}).join(''); | |
return data ? | |
$('<table class="table table-striped table-condensed m-b-0">').append(data) : | |
false; | |
}, | |
} | |
}, | |
@else | |
responsive: false, | |
scrollX: true, | |
@endif | |
autoWidth: false, | |
pageLength: {{ $crud->getDefaultPageLength() }}, | |
lengthMenu: @json($crud->getPageLengthMenu()), | |
/* Disable initial sort */ | |
aaSorting: [], | |
language: { | |
emptyTable: "{{ trans('backpack::crud.emptyTable') }}", | |
info: "{{ trans('backpack::crud.info') }}", | |
infoEmpty: "{{ trans('backpack::crud.infoEmpty') }}", | |
infoFiltered: "{{ trans('backpack::crud.infoFiltered') }}", | |
infoPostFix: "{{ trans('backpack::crud.infoPostFix') }}", | |
thousands: "{{ trans('backpack::crud.thousands') }}", | |
lengthMenu: "{{ trans('backpack::crud.lengthMenu') }}", | |
loadingRecords: "{{ trans('backpack::crud.loadingRecords') }}", | |
processing: "<img src='{{ asset('vendor/backpack/crud/img/ajax-loader.gif') }}' alt='{{ trans('backpack::crud.processing') }}'>", | |
search: "{{ isset($crud->searchLabel) ? $crud->searchLabel : trans('backpack::crud.search') }}", | |
zeroRecords: "{{ trans('backpack::crud.zeroRecords') }}", | |
paginate: { | |
first: "{{ trans('backpack::crud.paginate.first') }}", | |
last: "{{ trans('backpack::crud.paginate.last') }}", | |
next: "<span class='hidden-xs hidden-sm'>{{ trans('backpack::crud.paginate.next') }}</span><span class='hidden-md hidden-lg'>></span>", | |
previous: "<span class='hidden-xs hidden-sm'>{{ trans('backpack::crud.paginate.previous') }}</span><span class='hidden-md hidden-lg'><</span>" | |
}, | |
aria: { | |
sortAscending: "{{ trans('backpack::crud.aria.sortAscending') }}", | |
sortDescending: "{{ trans('backpack::crud.aria.sortDescending') }}" | |
}, | |
buttons: { | |
copy: "{{ trans('backpack::crud.export.copy') }}", | |
excel: "{{ trans('backpack::crud.export.excel') }}", | |
csv: "{{ trans('backpack::crud.export.csv') }}", | |
colvis: "{{ trans('backpack::crud.export.column_visibility') }}" | |
} | |
}, | |
processing: true, | |
serverSide: true, | |
ajax: { | |
url: startingUrl, | |
type: "POST" | |
}, | |
dom: "<'row'<'col-sm-6 hidden-xs'l><'col-sm-6'f>>" + | |
"<'row table-wrapper'<'table-inner'tr>>" + | |
"<'row'<'col-sm-5'i><'col-sm-2'B><'col-sm-5'p>>", | |
}; | |
</script> | |
@include('crud::inc.export_buttons') | |
<script type="text/javascript"> | |
jQuery(document).ready(function ($) { | |
crud.table = crud.tableEl.DataTable(crud.dataTableConfiguration); | |
// override ajax error message | |
$.fn.dataTable.ext.errMode = 'none'; | |
crud.tableEl.on('error.dt', function (e, settings, techNote, message) { | |
new PNotify({ | |
type: 'error', | |
title: '{{ trans("backpack::crud.ajax_error_title") }}', | |
text: '{{ trans("backpack::crud.ajax_error_text") }}' | |
}); | |
}); | |
// make sure AJAX requests include XSRF token | |
$.ajaxPrefilter(function (options, originalOptions, xhr) { | |
var token = $('meta[name="csrf_token"]').attr('content'); | |
if (token) { | |
return xhr.setRequestHeader('X-XSRF-TOKEN', token); | |
} | |
}); | |
// on DataTable draw event run all functions in the queue | |
// (eg. delete and details_row buttons add functions to this queue) | |
crud.tableEl.on('draw.dt', function () { | |
crud.functionsToRunOnDataTablesDrawEvent.forEach(function (functionName) { | |
crud.executeFunctionByName(functionName); | |
}); | |
}); | |
// when columns are hidden by reponsive plugin, | |
// the table should have the has-hidden-columns class | |
crud.table.on('responsive-resize', function (e, datatable, columns) { | |
if (crud.table.responsive.hasHidden()) { | |
crud.tableEl.removeClass('has-hidden-columns').addClass('has-hidden-columns'); | |
} else { | |
crud.tableEl.removeClass('has-hidden-columns'); | |
} | |
}); | |
}); | |
</script> | |
@include('crud::inc.details_row_logic') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment