Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save breizhwave/59090a27f46e12accee8c422a149819c to your computer and use it in GitHub Desktop.
Save breizhwave/59090a27f46e12accee8c422a149819c to your computer and use it in GitHub Desktop.
Backpack CRUD - Persistent Filters/Pages/Searches
<!-- 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(/&amp;/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