Datatable Fixed column is not working
Scrollbody width and table widths are coming as equal. So I am not getting the horizontal scroll bar for the fxed columns.
we are using " jquery.dataTables.min-1.9.4.js" and Fixedcolumns (3.0.1).js.
html and javascript:
<html>
<head>
<script src="datatables/jquery-1.8.3.min.js" type="text/javascript"></script>
<script src="datatables/jquery.dataTables.min-1.9.4.js" type="text/javascript"></script>
<script src="datatables/extras/FixedColumns.js" type="text/javascript"></script>
<link href="datatables/css/dataTables.fixedColumns.css" rel="stylesheet" type="text/css" />
<link href="datatables/css/jquery.dataTables-1.9.4.css" rel="stylesheet" type="text/css" />
<link href="datatables/css/dataTables.fixedHeader.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<table id="example" class="stripe row-border order-column" cellspacing="0" width="100%">
<thead>
<tr>
<th rowspan="2">Name</th>
<th colspan="2">HR Information</th>
<th colspan="3">Contact</th>
</tr>
<tr>
<th>Position</th>
<th>Salary</th>
<th>Office</th>
<th>Extn.</th>
<th>E-mail</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Salary</th>
<th>Office</th>
<th>Extn.</th>
<th>E-mail</th>
</tr>
</tfoot>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>$320,800</td>
<td>Edinburgh</td>
<td>5421</td>
<td>t.nixon#datatables.net</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>$170,750</td>
<td>Tokyo</td>
<td>8422</td>
<td>g.winters#datatables.net</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>$86,000</td>
<td>San Francisco</td>
<td>1562</td>
<td>a.cox#datatables.net</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>$433,060</td>
<td>Edinburgh</td>
<td>6224</td>
<td>c.kelly#datatables.net</td>
</tr>
<tr>
<td>Airi Satou</td>
<td>Accountant</td>
<td>$162,700</td>
<td>Tokyo</td>
<td>5407</td>
<td>a.satou#datatables.net</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
$(document).ready(function () {
var datatables_options =
{
"bAutoWidth": true,
"sDom": '<"top"i>rt<"bottom"flp><"clear">', //determine render order for datatables.net items, http://datatables.net/ref#sDom
"bPaginate": false, // paging
"sPaginationType": "full_numbers", // http://datatables.net/release-datatables/examples/basic_init/alt_pagination.html
"iDisplayLength": 10, // page row size
"bSort": true, //sorting
"bFilter": false, // "search" box
"aaSorting": [], // default sort
"bInfo": false, // "Showing x to y of z entries" message
"bStateSave": false, // save state into a cookie
"iCookieDuration": 0, // save state cookie duration
"bScrollAutoCss": true, // datatables.net auto styling of scrolling styles, http://datatables.net/forums/discussion/comment/15072
"bProcessing": true, // "processing" message while sorting .. doesn't appear to be doing anything
"bJQueryUI": false // css classes for jQueryUI themes?
//"asStripeClasses": [], // remove odd/even row css classes (they will be assigned elsewhere)
};
datatables_options["sScrollY"] = "450px";
datatables_options["sScrollX"] = "100%";
datatables_options["bScrollCollapse"] = true;
var $datatable = $(".example").dataTable(datatables_options);
new $.fn.dataTable.FixedColumns($datatable,
{
"iLeftColumns": 1,
//"sLeftWidth": 'relative',
//"iLeftWidth": 20,
"sHeightMatch": "none", /* if there aren't any rows that have wrapping text this would be best because it is much faster in IE8 */
//"sHeightMatch": "semiauto",
//"sHeightMatch": "auto",
});
});
</script>
</body>
<style type="text/css">
th, td {
white-space: nowrap;
padding-left: 40px !important;
padding-right: 40px !important;
}
div.dataTables_wrapper {
width: 800px;
margin: 0 auto;
}
</style>
</html>
screenshot:
You just have the table width set to 100% and sScrollX set to 100%. You lack to define sScrollXInner :
This property can be used to force a DataTable to use more width than
it might otherwise do when x-scrolling is enabled. (...)
add
datatables_options["sScrollXInner"] = '150%';
or whatever width you want the table to have, to your options object. Your example as above in a demo -> http://jsfiddle.net/PEN7T/
Related
I am looking for ways to search in DataTable. this is what is found. I want search boxes to be on top under the header. I tried some thing like this bur failed
can some one help how can I make search boxes on top of data table to filter data.
html field
<table id="tabular_datas" class="table table-bordered table-striped">
<thead>
<tr>
<th>Time</th>
<th>CPU Load</th>
<th>Memory Utilization</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td>Time</td>
<td>CPU Load</td>
<td>Memory Utilization</td>
</tr>
</tfoot>
</table>
JavaScript field
$('#tabular_datas th').append('<tr><td>Time</td><td>CPU Load</td><td>Memory Utilization</td></tr>');
$('#tabular_datas thead th[1]').each(function () {
console.log('data searching in datatable');
var title = $(this).text();
$(this).html('<input type="text" placeholder="Search ' + title + '" />');
});
and then I populate the data table
$('#tabular_datas').DataTable({
destroy: true,
lenChange:true,
dom: 'Bfrtip',
// "searching": false,
buttons: [{
extend: 'excelHtml5',
title: 'Activity Log',
text: 'Export to Excel'
},
{
extend: 'pdfHtml5',
title: 'Activity Log',
text: 'Export to PDF'
},
{
extend: 'colvis',
text: 'Column Visibility'
},
],
"info": true,
"data": data,
"lengthMenu": [
[50, 100, -1],
[50, 100, "All"]
],
initComplete: function () {
// Apply the search
this.api()
.columns()
.every(function () {
console.log('obj 1 ');
var that = this;
console.log('that : ', that);
console.log('this.footer() : ', this.footer());
$('input', this.footer()).on('keyup change clear', function () {
console.log('obj 2 ');
if (that.search() !== this.value) {
that.search(this.value).draw();
console.log('obj 3 ');
}
});
});
},
});
To do what you require, you can take the example in the link you provided and change the jQuery to place the inputs in the thead, and attach the events using this.header():
jQuery($ => {
$('#example thead th').each(function() {
var title = $(this).text();
$(this).html(`<h4>${title}</h4><input type="text" placeholder="Search..." />`);
});
// DataTable
var table = $('#example').DataTable({
initComplete: function() {
// Apply the search
this.api()
.columns()
.every(function() {
var that = this;
$('input', this.header()).on('input', function(e) {
if (that.search() !== this.value) {
that.search(this.value).draw();
}
}).on('click', e => e.stopPropagation());
});
},
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css" />
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011-04-25</td>
<td>$320,800</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011-07-25</td>
<td>$170,750</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009-01-12</td>
<td>$86,000</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>2012-03-29</td>
<td>$433,060</td>
</tr>
</tbody>
</table>
I have a small problem. I am creating a table with datatable and bootstrap 4 and the truth is that it works great, but I have the following problem: I am trying to put a totalizer so that the total of one (or several) columns appears at the end. The code works fine (Because it calculates the total) the problem is that it places it in the header instead of in the footer. Do you know why? Thanks.
echo '<div class="card-body"><table id="html5-extension" class="table table-hover table-striped " style="width:100%">';
echo '<thead class=""><tr role="row">
<th >'.$palabra['numeroor'].'</th>
<th >'.$palabra['serieano'].'</th>
<th >'.$palabra['taller'].'</th>
<th >'.$palabra['fecha'].'</th>
<th >'.$palabra['matricula'].'</th>
<th >'.$palabra['vehiculo'].'</th>
<th >'.$palabra['cristalroto'].'</th>
<th >'.$palabra['compania'].'</th>
<th ></th>
<th></th>
</tr> </thead>';
echo ' <tfoot>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tfoot>
<tbody>';
echo '<tr role="row">
<td scope="row">'.$lisc['or_interna'].'</td>
<td scope="row">'.$lisc['serie_or'].'/'.$lisc['ano_or'].'</td>
<td >'.$datostaller->nombre.'</td>
<td >'.cfecha($lisc['fecha_entrada']).'</td>
<td >'.$lisc['matricula'].'</td>
<td >'.$marca.$espacio.$modelo.'</td>
<td >'.$arraydano['nombre'].'</td>
<td >'.$cia->nombre_comercial.'</td>
';
my js code:
<script>
//#html5-extension
$(document).ready(function () {
$('#html5-extension tfoot td').each(function () {
var title = $(this).text();
$(this).html('<input type="text" placeholder="Filtrar.." />');
});
var table = $('#html5-extension').DataTable({
"dom": 'B<"float-left"i><"float-right"f>t<"float-left"l><"float-right"p><"clearfix">',
"responsive": false,
"language": {
"url": "https://cdn.datatables.net/plug-ins/1.10.19/i18n/Spanish.json"
},
"initComplete": function () {
this.api().columns().every(function () {
var that = this;
$('input', this.footer()).on('keyup change', function () {
if (that.search() !== this.value) {
that
.search(this.value)
.draw();
}
});
})
},
footerCallback: function (row, data, start, end, display) {
var api = this.api();
// Remove the formatting to get integer data for summation
var intVal = function (i) {
return typeof i === 'string' ? i.replace(/[\$,]/g, '') * 1 : typeof i === 'number' ? i : 0;
};
// Total over all pages
total = api
.column(0)
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
// Total over this page
pageTotal = api
.column(0, { page: 'current' })
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
// Update footer
$(api.column(0).footer()).html('<th>€' + pageTotal + ' ( €' + total + ' en total)</th>');
},
"ordering": false,
buttons: [
{
extend: 'copyHtml5',
footer: true,
text: 'Copiar',
exportOptions: {
columns: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
},
text: '<i class="glyphicon glyphicon-floppy-disk"></i><span> Copiar</span>'
},
{
extend: 'excelHtml5',
footer: true,
autoFilter: true,
sheetName: 'Ordenes de Trabajo',
exportOptions: {
columns: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
},
text: '<i class="glyphicon glyphicon-download-alt"></i><span> Generar Excel</span>',
filename: 'Listado de Ordenes de Trabajo',
},
{
extend: 'pdfHtml5',
footer: true,
exportOptions: {
columns: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
},
text: '<i class="glyphicon glyphicon-save-file"></i><span> Generar PDF</span>',
filename: 'Listado de Ordenes de Trabajo',
},
{
extend: 'print',
footer: true,
exportOptions: {
columns: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
},
text: '<i class="glyphicon glyphicon-print"></i><span> Imprimir</span>',
}
],
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "Todos"]]
});
});
</script>
I edit. I have the following code so that the search engines appear at the top (instead of at the bottom). I know that's why the total comes out at the top, what I don't know is how to fix the total at the bottom and the search engines at the top
<style>
#html5-extension tfoot input {
width: 100% !important;
}
#html5-extension tfoot {
display: table-header-group !important;
}
</style>
I think you would be better off using this example as your starting point, because it places filters in the heading correctly.
The linked example creates a second header row so that the sorting controls can be kept separate from the filtering controls. The orderCellsTop: true option tells DataTables that the first header row is the one to be used for sorting.
(The linked example also uses FixedHeader, which I think you do not need, so you can ignore that piece.)
That leaves you free to place your totals in your footer - which is not used when building the filter controls.
So, now you can handle your totals logic in the footerCallback section of the DataTable, similar to this example, which I think is what you are using already in your DataTable.
Here is a runnable demo with it all combined into one DataTable. My sample data is from the DataTables web site so I use the "age" data for summing (just to show how the code works).
You would still need to change the data, and add back in the Bootstrap library. But this approach does not require you to use your custom CSS to try to manage where controls are placed. And it does not need to use !important anywhere.
$(document).ready(function () {
// Setup - add a text input to each footer cell
$('#example thead tr')
.clone(true)
.addClass('filters')
.appendTo('#example thead');
var table = $('#example').DataTable({
orderCellsTop: true,
fixedHeader: true,
footerCallback: function ( row, data, start, end, display ) {
var api = this.api(), data;
// Remove the formatting to get integer data for summation
var intVal = function ( i ) {
return typeof i === 'string' ?
i.replace(/[\$,]/g, '')*1 :
typeof i === 'number' ?
i : 0;
};
// Total over all pages
total = api
.column( 3 )
.data()
.reduce( function (a, b) {
return intVal(a) + intVal(b);
}, 0 );
// Total over this page
pageTotal = api
.column( 3, { page: 'current'} )
.data()
.reduce( function (a, b) {
return intVal(a) + intVal(b);
}, 0 );
// Update footer
$( api.column( 3 ).footer() ).html(
'€'+pageTotal +' (€'+ total +' total)'
);
},
initComplete: function () {
var api = this.api();
// For each column
api
.columns()
.eq(0)
.each(function (colIdx) {
// Set the header cell to contain the input element
var cell = $('.filters th').eq(
$(api.column(colIdx).header()).index()
);
var title = $(cell).text();
$(cell).html('<input type="text" placeholder="' + title + '" />');
// On every keypress in this input
$(
'input',
$('.filters th').eq($(api.column(colIdx).header()).index())
)
.off('keyup change')
.on('change', function (e) {
// Get the search value
$(this).attr('title', $(this).val());
var regexr = '({search})'; //$(this).parents('th').find('select').val();
var cursorPosition = this.selectionStart;
// Search the column for that value
api
.column(colIdx)
.search(
this.value != ''
? regexr.replace('{search}', '(((' + this.value + ')))')
: '',
this.value != '',
this.value == ''
)
.draw();
})
.on('keyup', function (e) {
e.stopPropagation();
$(this).trigger('change');
$(this)
.focus()[0]
.setSelectionRange(cursorPosition, cursorPosition);
});
});
},
});
});
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
</style>
</head>
<body>
<div style="margin: 20px;">
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011-04-25</td>
<td>$320,800</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011-07-25</td>
<td>$170,750</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009-01-12</td>
<td>$86,000</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>2012-03-29</td>
<td>$433,060</td>
</tr>
<tr>
<td>Airi Satou</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>33</td>
<td>2008-11-28</td>
<td>$162,700</td>
</tr>
<tr>
<td>Brielle Williamson</td>
<td>Integration Specialist</td>
<td>New York</td>
<td>61</td>
<td>2012-12-02</td>
<td>$372,000</td>
</tr>
<tr>
<td>Herrod Chandler</td>
<td>Sales Assistant</td>
<td>San Francisco</td>
<td>59</td>
<td>2012-08-06</td>
<td>$137,500</td>
</tr>
<tr>
<td>Rhona Davidson</td>
<td>Integration Specialist</td>
<td>Tokyo</td>
<td>55</td>
<td>2010-10-14</td>
<td>$327,900</td>
</tr>
<tr>
<td>Colleen Hurst</td>
<td>Javascript Developer</td>
<td>San Francisco</td>
<td>39</td>
<td>2009-09-15</td>
<td>$205,500</td>
</tr>
<tr>
<td>Sonya Frost</td>
<td>Software Engineer</td>
<td>Edinburgh</td>
<td>23</td>
<td>2008-12-13</td>
<td>$103,600</td>
</tr>
<tr>
<td>Jena Gaines</td>
<td>Office Manager</td>
<td>London</td>
<td>30</td>
<td>2008-12-19</td>
<td>$90,560</td>
</tr>
<tr>
<td>Quinn Flynn</td>
<td>Support Lead</td>
<td>Edinburgh</td>
<td>22</td>
<td>2013-03-03</td>
<td>$342,000</td>
</tr>
<tr>
<td>Donna Snider</td>
<td>Customer Support</td>
<td>New York</td>
<td>27</td>
<td>2011-01-25</td>
<td>$112,000</td>
</tr>
</tbody>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th>123</th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
</div>
</body>
</html>
I was wondering is there way to improve search in data table?
I have a numeric column in a datatable. Is it possible to return back just the number being searched on?
So for example: 100
210
310
1
and if I search for 1
I want to show only :1 but not the others that contain 1
jQuery(document).ready(function ($) {
var db = $('#min-table').DataTable({
"dom": '<"pull-left"f><"pull-right"l>tip',
"bJQueryUI": true,
"bSort": true,
"bSearchable": true,
"bPaginate": true,
"lengthMenu": [[20, 35, 50, -1], [20, 35, 50, "All"]],
"iDisplayLength": 20
});
});
You can make use of datatable plugins to override some of the features. In your case, you can add your custom function to $.fn.dataTable.ext.search.push
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
const searchTerm = $("[type=search]").val();
if(searchTerm){
return data[3] === searchTerm
}else{
return true;
}
}
);
In the above code, I'm using a full text search on fourth column for each row. Row will be included or excluded based on the return value of the function (true or false).
Ref: https://datatables.net/examples/plug-ins/
Try the below snippet. Full text search enabled on age column.
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
const searchTerm = $("[type=search]").val();
if(searchTerm){
return data[3] === searchTerm
}else{
return true;
}
}
);
var table = $('#example').DataTable();
<link href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.19/js/jquery.dataTables.min.js"></script>
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011/07/25</td>
<td>$170,750</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009/01/12</td>
<td>$86,000</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>2012/03/29</td>
<td>$433,060</td>
</tr>
</tbody>
</table>
I have created a datatable which has a multi search feature in the footer and I would like to have a feature which adds up all the salaries of what is currently displayed or searched. I am not sure how to do that.
Here is my HTML code for the table
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="./search.js"></script>
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011/07/25</td>
<td>$170,750</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009/01/12</td>
<td>$86,000</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>2012/03/29</td>
<td>$433,060</td>
</tr>
<tr>
<td>Airi Satou</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>33</td>
<td>2008/11/28</td>
<td>$162,700</td>
</tr>
<tr>
<td>Brielle Williamson</td>
<td>Integration Specialist</td>
<td>New York</td>
<td>61</td>
<td>2012/12/02</td>
<td>$372,000</td>
</tr>
<tr>
<td>Herrod Chandler</td>
<td>Sales Assistant</td>
<td>San Francisco</td>
<td>59</td>
<td>2012/08/06</td>
<td>$137,500</td>
</tr>
<tr>
<td>Rhona Davidson</td>
<td>Integration Specialist</td>
<td>Tokyo</td>
<td>55</td>
<td>2010/10/14</td>
<td>$327,900</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
</table>
Here is my search.js Code
$(document).ready(function() {
// Setup - add a text input to each footer cell
$('#example tfoot th').each( function () {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="Search '+title+'" />' );
} );
// DataTable
var table = $('#example').DataTable();
// Apply the search
table.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
} );
} );
I am trying to add a sum feature to this code where it adds up the total of the salary column, can someone please help me? im not sure how to do this
That topic has been raised multiple times over here at SO, you may inquiry my earlier post in that regard.
The trick here is to use selector-modifier {search:'applied'} together with methods .column() (if you need to summarize single column) or .rows() for multi-column totals.
Another helpful method .data() may be used to extract the data into array (1, 2).
In order to refresh your totals upon each table re-draw, you may employ drawCallback option, to specify callback function that re-calculates totals for visible rows and puts the result into desired node.
Check out following live demo of that approach:
//format number as currency (not essential within current context)
const num2curr = num => '$'+num.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
//datatables initialization
const dataTable = $('#example').DataTable({
dom: 't',
//append individual filter inputs
initComplete: function(){
this.api().columns().every(function(){
$(this.footer()).html(`<input colindex="${this.index()}" placeholder="${$(this.header()).text()}"></input>`)
})
},
//calculate total salary and put that into span#totalsalary
drawCallback: function(){
const totalSalary = this
.api()
.column(5,{search:'applied'})
.data()
.toArray()
//remove '$',',', keep decimal separator '.', summarize
.reduce((total,salary) => total+=Number(salary.replace(/[^0-9\.]/g,'')),0);
//insert result into the <span> text
$('#totalsalary').text(`Total salary for filtered rows is: ${num2curr(totalSalary)}`);
}
});
//individual filtering
$('#example').on('keyup', 'tfoot input', function(){
dataTable.column($(this).attr('colindex')).search($(this).val()).draw()
});
<!doctype html><html><head><link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.18/rg-1.1.0/datatables.min.css" /><script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script><script type="text/javascript" src="https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.18/rg-1.1.0/datatables.min.js"></script><script src="test.js"></script></head><body><table id="example" class="display" style="width:100%"><thead><tr><th>Name</th><th>Position</th><th>Office</th><th>Age</th><th>Start date</th><th>Salary</th></tr></thead><tbody><tr><td>Tiger Nixon</td><td>System Architect</td><td>Edinburgh</td><td>61</td><td>2011/04/25</td><td>$320,800</td></tr><tr><td>Garrett Winters</td><td>Accountant</td><td>Tokyo</td><td>63</td><td>2011/07/25</td><td>$170,750</td></tr><tr><td>Ashton Cox</td><td>Junior Technical Author</td><td>San Francisco</td><td>66</td><td>2009/01/12</td><td>$86,000</td></tr><tr><td>Cedric Kelly</td><td>Senior Javascript Developer</td><td>Edinburgh</td><td>22</td><td>2012/03/29</td><td>$433,060</td></tr><tr><td>Airi Satou</td><td>Accountant</td><td>Tokyo</td><td>33</td><td>2008/11/28</td><td>$162,700</td></tr><tr><td>Brielle Williamson</td><td>Integration Specialist</td><td>New York</td><td>61</td><td>2012/12/02</td><td>$372,000</td></tr><tr><td>Herrod Chandler</td><td>Sales Assistant</td><td>San Francisco</td><td>59</td><td>2012/08/06</td><td>$137,500</td></tr><tr><td>Rhona Davidson</td><td>Integration Specialist</td><td>Tokyo</td><td>55</td><td>2010/10/14</td><td>$327,900</td></tr></tbody><tfoot><tr><th>Name</th><th>Position</th><th>Office</th><th>Age</th><th>Start date</th><th>Salary</th></tr></tfoot></table><span id="totalsalary"></span></body></html>
Use the code below for summation
jQuery.fn.dataTable.Api.register( 'sum()', function ( ) {
return this.flatten().reduce( function ( a, b ) {
if ( typeof a === 'string' ) {
a = a.replace(/[^\d.-]/g, '') * 1;
}
if ( typeof b === 'string' ) {
b = b.replace(/[^\d.-]/g, '') * 1;
}
return a + b;
}, 0 );
} );
Then, you can get the sum after you draw with
that.column(5, {"filter": "applied"}).data().sum();
Also, omit the comma and $. You can refer to here for more information.
Any idea why the buttons (csv, excel, pdf, print etc) are not showing when using this code for bootstrap?
https://datatables.net/extensions/buttons/examples/styling/bootstrap4.html
I have this for styles:
<link href="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
<link href="//cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css" rel="stylesheet">
<link href="//cdn.datatables.net/buttons/1.5.6/css/buttons.bootstrap4.min.css" rel="stylesheet">
This for scripts:
<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="//cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
<script src="//cdn.datatables.net/buttons/1.5.6/js/dataTables.buttons.min.js"></script>
<script src="//cdn.datatables.net/buttons/1.5.6/js/buttons.bootstrap4.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script src="//cdn.datatables.net/buttons/1.5.6/js/buttons.html5.min.js"></script>
<script src="//cdn.datatables.net/buttons/1.5.6/js/buttons.print.min.js"></script>
<script src="//cdn.datatables.net/buttons/1.5.6/js/buttons.colVis.min.js"></script>
And this JS:
$(document).ready(function(){
var table = $('#reminders').DataTable({
"lengthMenu": [[50, 100, 1000, -1], [50, 100, 1000, "All"]],
"initComplete": function(){
$("#reminders").show();
},
buttons: ['copy', 'csv', 'excel', 'pdf', 'print', 'colvis']
});
table.buttons().container().appendTo( '#example_wrapper .col-md-6:eq(0)' );
});
But the buttons are not showing... If I uncomment the dom and use Blfrtip the buttons do show, but I am curious as why the method in the example (without dom) isn't working...
Using dom parameter
"dom": 'Blfrtip'
B - Buttons
l - length changing input control
f - filtering input
r - processing display element
t - The table
i - Table information summary
p - pagination control
Direct insertion
The selector would be #reminders_wrapper or
table.buttons().container()
.appendTo( $('.col-md-6:eq(0)', table.table().container()) );
$(document).ready(function() {
var table = $('#reminders').DataTable({
//"dom": 'Blfrtip',
"lengthMenu": [
[50, 100, 1000, -1],
[50, 100, 1000, "All"]
],
"initComplete": function() {
$("#reminders").show();
},
"buttons": ['copy', 'csv', 'excel', 'pdf', 'print', 'colvis']
});
table.buttons().container().appendTo('#reminders_wrapper .col-md-6:eq(0)');
});
<link href="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
<link href="//cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css" rel="stylesheet">
<link href="//cdn.datatables.net/buttons/1.5.6/css/buttons.bootstrap4.min.css" rel="stylesheet">
<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="//cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
<script src="//cdn.datatables.net/buttons/1.5.6/js/dataTables.buttons.min.js"></script>
<script src="//cdn.datatables.net/buttons/1.5.6/js/buttons.bootstrap4.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script src="//cdn.datatables.net/buttons/1.5.6/js/buttons.html5.min.js"></script>
<script src="//cdn.datatables.net/buttons/1.5.6/js/buttons.print.min.js"></script>
<script src="//cdn.datatables.net/buttons/1.5.6/js/buttons.colVis.min.js"></script>
<table id="reminders" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Unity Butler</td>
<td>Marketing Designer</td>
<td>San Francisco</td>
<td>47</td>
<td>2009/12/09</td>
<td>$85,675</td>
</tr>
<tr>
<td>Howard Hatfield</td>
<td>Office Manager</td>
<td>San Francisco</td>
<td>51</td>
<td>2008/12/16</td>
<td>$164,500</td>
</tr>
<tr>
<td>Hope Fuentes</td>
<td>Secretary</td>
<td>San Francisco</td>
<td>41</td>
<td>2010/02/12</td>
<td>$109,850</td>
</tr>
<tr>
<td>Zenaida Frank</td>
<td>Software Engineer</td>
<td>New York</td>
<td>63</td>
<td>2010/01/04</td>
<td>$125,250</td>
</tr>
<tr>
<td>Zorita Serrano</td>
<td>Software Engineer</td>
<td>San Francisco</td>
<td>56</td>
<td>2012/06/01</td>
<td>$115,000</td>
</tr>
</table>
I just checked, and the DOM for the wrapper is not ready yet right after the DataTable() call. I'm using AJAX to get the data. But adding the call in the initComplete property worked:
$(document).ready(function() {
var table = $('#reminders').DataTable({
//"dom": 'Blfrtip',
"lengthMenu": [
[50, 100, 1000, -1],
[50, 100, 1000, "All"]
],
"initComplete": function() {
table.buttons().container().appendTo('#reminders_wrapper .col-md-6:eq(0)');
$("#reminders").show();
},
"buttons": ['copy', 'csv', 'excel', 'pdf', 'print', 'colvis']
// Rest of configuration.
});
});
The dom option isn't just a set of flags to turn on/off features in datatables. It's also the html templates to use to render the those features. datatables-bootstrap-4.js overrides the default dom option to include some wrappers (but doesn't add the buttons as you found out). By setting dom to Blrtip you are wiping out the bootstrap templates. That's why it looks fine without the dom option (but no buttons) and setting the dom option to Blrtip gives you buttons but the wrappers go away. Instead of leaving out the dom option and inserting the buttons later (which works fine I suppose), you can also set dom to a modified version of the template datatables-bootstrap-4 uses, including the B option for buttons.
bootstrap-datatables-4.js sets this:
'dom' : "<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>"
So you can modify that to add the B flag like this:
'dom' : "<'row'<'col-sm-12 col-md-6'Bl><'col-sm-12 col-md-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>"