Witam serdecznie,
Mam tabelkę https://datatables.net w swoim projekcie:
require('datatables.net');
require('datatables.net-bs4');
//require('datatables.net-responsive');
require('./../../vendor/dataTables.responsive');
require('datatables.net-responsive-bs4');
import langpacks from './_langs';
(function ( $ ) {
if( typeof $.fn.DataTable !== 'function' )
{
throw new Error('Datatables not defined!');
}
if(typeof $.fn.purgetText !== 'function')
{
$.fn.purgeText = function() {
var $html = $(this).children();
$(this).text(null).html( $html );
return this;
};
}
var initComplete = function() {},
preXhr = function(e, settings, data) {
const contextSelector = isArray(window.dtables) && window.dtables.length > 1 ? this.id : '';
const selector = contextSelector ? [
`#${contextSelector}_filter_content [data-action~="table-filter"]`,
`#${contextSelector}_filter [data-action~="table-filter"]`
].join(', ') : '[data-action~="table-filter"]';
document.querySelectorAll(selector).forEach(filter => {
if( ! filter.value.length || inArray(filter.type, ['radio', 'checkbox']) && !filter.checked) {
return;
}
_.set(data, 'filters.' + filter.name, filter.value);
});
let tLength = $('[data-action~="table-length"]');
if( tLength && tLength.value ) {
_.set(data, 'length', tLength.value);
}
},
draw = function(e, settings) {
var dtable = $('#' + this.id + '_wrapper');
if( parseInt(lastReceivedJSON.drawedCount) === 0)
{
return dtable.find('.dataTables_info').text( _.get(langpacks, document.querySelector('html').getAttribute('lang') + '.zeroRecords', 'No records found.') );
}
dtable.find('.dataTables_info').text(
_.get(langpacks, document.querySelector('html').getAttribute('lang') + '.info', 'Positions from _START_ to _END_ from _TOTAL_ total.')
.replace('_START_', (lastReceivedJSON.start + 1))
.replace('_END_', (lastReceivedJSON.start + lastReceivedJSON.drawedCount ))
.replace('_TOTAL_', (lastReceivedJSON.filteredCount))
+ (
lastReceivedJSON.totalCount !== lastReceivedJSON.filteredCount
? ' ' + _.get(langpacks, document.querySelector('html').getAttribute('lang') + '.infoFiltered', '(filtered out of _MAX_)').replace('_MAX_', lastReceivedJSON.totalCount)
: ''
)
);
highlightRow();
},
highlightRow = function() {
let url = new URL(document.location);
let highlightRow = url.searchParams.get('highlight');
if(highlightRow != undefined)
{
var target = $('tr[data-id="' + highlightRow + '"]');
if(target.length) {
$('html, body').animate({
'scrollTop': target.offset().top - $(window).height()/2
}, 750);
target.addClass('blink');
}
}
url.searchParams.delete('highlight');
history.replaceState({}, null, url);
},
placeFilters = function(e, settings) {
let _id = this.id;
let dtable = $('#' + _id + '_wrapper');
let contextSelector = isArray(window.dtables) && window.dtables.length > 1 ? '#' + this.id + '_filter_content' : '';
let filtersSource = $(contextSelector + '[data-content="table-filters"]');
let filterTarget = dtable.find('.dataTables_filter');
if( filtersSource.length === 0 || filtersSource.is(':empty') )
{
return dtable.find('.row').first().children().last().addClass('text-right');
}
if( !filterTarget.length || filtersSource.data('filter-type') === 'nomove' )
{
return filtersSource.removeClass('d-none')
.find('input, select, textarea').each(function() {
this.dataset.filterFor = _id;
});
}
filterTarget.prepend( filtersSource.html() )
.parent().removeClass('col-md-6').addClass('col-md-12 col-xl-9')
.prev().removeClass('col-md-6').addClass('col-md-12 col-xl-3');
if(typeof $.fn.datepickerWrapper === 'function')
{
dtable.find('[data-picker="datepicker"]').datepickerWrapper();
}
filtersSource.empty();
},
reloadTable = function(e, data) {
if(typeof window.dtables !== 'undefined' && Array.isArray(window.dtables))
{
var $instance = _.get(data, 'instance', null) !== null
? _.get(window, 'dtables.' + _.get(data, 'instance'), null)
: null;
if( $instance !== null )
{
return $instance.ajax.reload();
}
// fallback...
$.each(window.dtables, function(k, instance) {
instance.ajax.reload();
});
}
},
applyFilter = function() {
let $filterTarget = this.dataset.filterFor ? $('#' + this.dataset.filterFor) : $(this).closest('.dataTables_wrapper');
$(document).trigger('dtables:reload', {
instance: $filterTarget.prop('id').replace(/(DataTables_Table_|_wrapper)/g,'')
});
},
applyLength = function() {
$(document).trigger('dtables:reload', {
instance: $(this).prop('name').replace(/(DataTables_Table_|_length)/g,'')
});
},
rowCallback = function(row, data) {
if( data._popover )
{
row.dataset.popover = data._popover;
}
if(data.id)
{
row.dataset.id = data.id;
}
row.dataset.md5 = data._md5;
},
footerCallback = function(row, data, start, end, display) {
var api = this.api();
var rcnt=0;
api.columns('.sum', {
page: 'current'
}).every(function() {
var sum = this
.data()
.reduce(function(a, b) {
var x = parseFloat(a) || 0;
var y = parseFloat(b) || 0;
return x + y;
}, 0);
console.log(sum); //alert(sum);
if(rcnt==0){
$("#foot").append('<td style="background:#a1eaed;color:black; text-align: center;">Total</td>');
}else{
$("#foot").append('<td style="background:#a1eaed;color:black; text-align: center;">'+sum+'</td>');
}
rcnt++;
//$(this.footer()).html(sum);
});
},
buildOpts = (context) => {
return {
processing: true,
serverSide: true,
responsive: true,
searching: false,
iDisplayLength: typeof context.data('def-length') !== 'undefined' ? context.data('def-length') : 50,
order: [],
columns: [],
ajax: {
url: context.data('url'),
method: 'POST',
data: {},
dataSrc: function(data) {
lastReceivedJSON = $.extend({}, data);
/*
* Little hack to make pagination work as expected
* while having proper count of filtered objects;;
*/
data.iTotalDisplayRecords = data.filteredCount;
return data.data;
},
error: (xhr) => {
$(document).trigger('bs-swal:error', [{
title: 'Błąd pobierania danych tabeli',
text: _.get(xhr, 'responseJSON.message')
}]);
try {
document.querySelector('#' + context.get(0).id + '_processing').style.display = 'none';
} catch(e) {}
}
},
initComplete: initComplete,
rowCallback: rowCallback,
footerCallback: footerCallback
};
},
lastReceivedJSON = null;
$.fn.esDataTable = function() {
var $this = this;
if( typeof this.data('url') === 'undefined' )
{
throw new Error('Invalid esDtables url!');
return this;
}
let opts = buildOpts(this);
let documentLang = document.querySelector('html').getAttribute('lang');
if( documentLang && documentLang in langpacks )
{
opts.language = langpacks[documentLang];
}
if( typeof $(this).data('ajax-items') !== 'undefined')
{
let items = $(this).data('ajax-items');
$.each(items.split(';'), function(k,v) {
var i = v.split(':');
if(i.length === 2)
{
opts.ajax.data[ i[0] ] = i[1];
}
});
}
let contextSelector = isArray(window.dtables) && window.dtables.length > 1 ? '#' + this.id + '_filter ' : '';
document.querySelectorAll(contextSelector + '[data-action~="table-filter"]').forEach(filter => {
if( ! filter.value.length || inArray(['radio', 'checkbox'], filter.type) && !filter.checked) {
return;
}
_.set(opts.ajax.data, 'filters.' + filter.name, filter.value);
});
this.find('th[data-column]').each(function(k,v) {
let $this = $(this);
var title = $this.text().length > 0 ? $this.text() : '';
var colData = typeof $this.data('column') !== 'undefined' ? $this.data('column') : null;
if( colData === null )
{
throw new Error('Insuficient column [' + k +'] data!');
}
var col = {
title: title,
data: colData,
searchable: typeof $this.data('searchable') !== 'undefined' ? $this.data('searchable') : false,
orderable: typeof $this.data('orderable') !== 'undefined' ? $this.data('orderable'): false,
width: typeof $this.data('width') !== 'undefined'
? $this.data('width')
: colData === 'actions'
? '59px'
: 'auto',
className: typeof $this.data('class') !== 'undefined' ? $this.data('class') : ''
};
opts.searching = opts.searching || col.searchable;
opts.columns.push(col);
if( col.orderable !== false && this.hasAttribute('data-default-direction') )
{
opts.order.push([k, this.getAttribute('data-default-direction')]);
}
});
if( ! opts.order.length )
{
this.find('th[data-column]').each(function(idx, col) {
if( opts.columns[idx].orderable ) {
opts.order = [[idx, "asc"]];
return false;
}
});
}
if( ! isArray(window.dtables) )
{
window.dtables = [];
}
window.dtables.push( this.DataTable(opts) );
// Register events only once.
if( ! window.jQueryEventRegistered(document, 'dtables:reload', null, reloadTable) )
{
$(document).on('dtables:reload', reloadTable);
}
if( ! window.jQueryEventRegistered(document, 'change', '[data-action~="table-filter"]', applyFilter) )
{
$(document).on('change', '[data-action~="table-filter"]', applyFilter);
}
this.on('preXhr.dt', preXhr);
this.on('draw.dt', draw);
this.one('init.dt', placeFilters);
return this;
};
$('table[data-url]').each(function() {
$(this).esDataTable();
});
}( jQuery ));
Działa poprawnie,
Html z tabelką:
<table id="work_time_dt" class="table table-striped table-bordered table-hover" cellspacing="0" width="100%"
data-url="{{ get_lockdown_href('cases.worktime', $caseInstance) }}">
<thead>
<tr>
<th data-column="_natural_order" data-width="20px" data-class="text-right">LP</th>
<th data-column="user">Pracownik</th>
<th data-column="name">Nazwa</th>
<th data-column="date">Data</th>
<th data-column="elapsed_time">Przepracowany czas</th>
<th data-column="description">Opis</th>
<th data-column="actions" data-width="59px"></th>
</tr>
</thead>
<tbody></tbody>
<tfoot data-column="summary" data-id="4" id="foot">
1234.6
</tfoot>
</table>
Chciałbym dodać w DataTables takie podsumowanie 4 kolumny: https://datatables.net/examples/advanced_init/footer_callback.html
W jaki sposób mogę to zrobić?
Mój powyższy kod nie działa :(