I am trying to apply Individual column searching (select inputs) for Datatables plugin in Jquery. I am using serverside processing, the data is loaded correctly from SQL Server into my table but when I want to select an input to filter a column based on that value, the filter is not working as you see here.
When I select a country for example Austria, the data is not filtered to Austria.
Here is my index page
<html>
<head>
<meta http-equiv="Content-Type" content="text/html" charset=utf-8" />
<title> Datatables Individual column searching using PHP Ajax Jquery </title>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/dataTables.bootstrap.min.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h1 align="center">Datatables</h1>
<div class="table-responsive">
<table id="example" class="table table-striped table-bordered" style="width:100%">
<thead>
<tr>
<th>Country</th>
<th>Territory</th>
<th>Market</th>
<th>Entname</th>
<th>MTM</th>
<th>Qty</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Country</th>
<th>Territory</th>
<th>Market</th>
<th>Entname</th>
<th>MTM</th>
<th>Qty</th>
</tr>
</tfoot>
</table>
</div>
</div>
</body>
</html>
<script type="text/javascript" language="javascript" >
$(document).ready(function() {
var dtable = $('#example').DataTable({
"processing": true,
"serverSide": true,
"deferRender": true,
"lengthMenu": [ [25, 50, 100, -1], [25, 50, 100, "All"] ],
"pageLength": -1,
"lengthChange": true,
"pagingType": "full_numbers",
"columns": [
{"data": "Country"},
{"data": "Territory"},
{"data": "Market"},
{"data": "Entname"},
{"data": "MTM"},
{"data": "Qty"}
],
"ajax": {
url: 'fetch.php',
type: 'POST'
},
initComplete: function () {
this.api().columns().every( function () {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo( $(column.footer()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
} );
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
} );
} );
}
});
$(".dataTables_filter input")
.unbind()
.bind("keyup change", function(e) {
if(this.value.length >= 1 && e.keyCode == 13) { dtable.search(this.value).draw(); }
if(this.value == "") { dtable.search("").draw(); }
return;
});
} );
</script>
and here is my fetch.php
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
if (!empty($_POST) ) {
$ser="*****";
$db="*****";
$user="*****";
$pass="*****";
$dbDB = new PDO("odbc:Driver=ODBC Driver 13 for SQL Server;Server=*****;Database=*****;Port=1456", $user, $pass);
$MyTable="*****";
function getData($sql){
global $dbDB ;
global $MyTable ;
$result = $dbDB->query($sql);
$data= $result->fetchAll(PDO::FETCH_ASSOC);
return $data; }
$res = $dbDB->query("SELECT COUNT(*) FROM ".$MyTable);
$recordsTotal = $res->fetchColumn();
$draw = $_POST["draw"];
$orderByColumnIndex = $_POST['order'][0]['column'];
$orderBy = $_POST['columns'][$orderByColumnIndex]['data'];
$orderType = $_POST['order'][0]['dir'];
$start = $_POST["start"];
if ($_POST['length'] == -1) {$length = $recordsTotal;}
else {$length = $_POST['length'];}
if(!empty($_POST['search']['value'])){
for($i=0 ; $i<count($_POST['columns']);$i++){
$column = $_POST['columns'][$i]['data'];
$where[]="$column like '%".$_POST['search']['value']."%'";
}
$where = "WHERE ".implode(" OR " , $where);
$sql = sprintf("SELECT COUNT(*) FROM %s %s", $MyTable , $where);
$r = $dbDB->query($sql);
$recordsFiltered = $r->fetchColumn();
$sql = sprintf("SELECT Country,Territory,Market,Entname,MTM,Qty FROM %s %s ORDER BY %s %s OFFSET %d ROWS FETCH NEXT %d ROWS ONLY", $MyTable , $where ,$orderBy, $orderType ,$start,$length);
$data = getData($sql);
}
else {
$sql = sprintf("SELECT Country,Territory,Market,Entname,MTM,Qty FROM %s ORDER BY %s %s OFFSET %d ROWS FETCH NEXT %d ROWS ONLY", $MyTable ,$orderBy, $orderType ,$start,$length);
$data = getData($sql);
$recordsFiltered = $recordsTotal;
}
$response = array(
"draw" => intval($draw),
"recordsTotal" => $recordsTotal,
"recordsFiltered" => $recordsFiltered,
"data" => $data );
echo json_encode($response);
}
else {
echo "NO POST Query from DataTable";
}
?>
I believe that the issue is somewhere in the javascript part not the php file but just to show an overview how the data is populated into the table.
Any idea please where is the issue?
Check below example
// Setup - add a text input to each footer cell
$('#item tfoot th').each( function () {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="Search '+title+'" />' );
} );
// DataTable
var otable = $('#item').DataTable();
// Apply the search
otable.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
} );
tfoot {
display: table-header-group;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://www.jqueryscript.net/demo/DataTables-Jquery-Table-Plugin/media/css/jquery.dataTables.css">
<table name="item" id="item" class="display" width="100%" cellspacing="0">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
<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>
</tbody>
</table>
what about datefilter search i.e enddate>startdate to this datatable.It would more convenient.
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 am using datatables plugin. I would like to ask, is there any way to expand/collapse all rows of the nested table. I tried to implement this below, but it doesn't work. I would like to expand/collapse rows like this example
https://www.gyrocode.com/articles/jquery-datatables-how-to-expand-collapse-all-child-rows/#regular.
Please help thanks
function fnFormatDetails(table_id, html) {
var sOut = "<table id=\"exampleTable_" + table_id + "\">";
sOut += html;
sOut += "</table>";
return sOut;
}
var iTableCounter = 1;
var oTable;
var oInnerTable;
var TableHtml;
//Run On HTML Build
$(document).ready(function () {
TableHtml = $('#exampleTable_2').html();
//Insert a 'details' column to the table
var nCloneTh = document.createElement('th');
var nCloneTd = document.createElement('td');
nCloneTd.innerHTML = '<img src="http://i.imgur.com/SD7Dz.png">';
nCloneTd.className = "center";
$('#exampleTable thead tr').each(function () {
this.insertBefore(nCloneTh, this.childNodes[0]);
});
$('#exampleTable tbody tr').each(function () {
this.insertBefore(nCloneTd.cloneNode(true), this.childNodes[0]);
});
//Initialse DataTables, with no sorting on the 'details' column
var oTable = $('#exampleTable').dataTable({
'bJQueryUI': true,
'sPaginationType': 'full_numbers',
'aoColumnDefs': [{
'bSortable': false,
'class': 'details-control',
'aTargets': [0]
}
],
'aaSorting': [[1, 'asc']]
});
/* Add event listener for opening and closing details
* Note that the indicator for showing which row is open is not controlled by DataTables,
* rather it is done here
*/
$('#exampleTable tbody tr img').on('click', function () {
var nTr = $(this).closest('tr');
if (oTable.fnIsOpen(nTr)) {
/* This row is already open - close it */
this.src = "http://i.imgur.com/SD7Dz.png";
oTable.fnClose(nTr);
} else {
/* Open this row */
this.src = "http://i.imgur.com/d4ICC.png";
oTable.fnOpen(nTr, fnFormatDetails(iTableCounter, TableHtml), 'details-control');
oInnerTable = $('#exampleTable_' + iTableCounter).dataTable({
'bJQueryUI': true,
'sPaginationType': 'full_numbers'
});
iTableCounter = iTableCounter + 1;
}
$('#btn-show-all-children').on('click', function () {
// Enumerate all rows
oTable.rows().every(function () {
// If row has details collapsed
if (!this.oTable.fnIsOpen(nTr)) {
/* Open this row */
this.src = "http://i.imgur.com/d4ICC.png";
this.oTable.fnOpen(nTr, fnFormatDetails(iTableCounter, TableHtml), 'details-control');
this.oInnerTable = $("#exampleTable_" + iTableCounter).dataTable({
'bJQueryUI': true,
'sPaginationType': 'full_numbers'
});
iTableCounter = iTableCounter + 1;
}
});
});
// Handle click on "Collapse All" button
$('#btn-hide-all-children').on('click', function () {
// Enumerate all rows
oTable.rows().every(function () {
// If row has details expanded
if (oTable.fnIsOpen(nTr)) {
/* This row is already open - close it */
this.src = "http://i.imgur.com/SD7Dz.png";
oTable.fnClose(nTr);
}
});
});
$('#btn-show-all-children').on('click', function () {
// Enumerate all rows
oTable.rows().every(function () {
// If row has details collapsed
if (!this.oTable.fnIsOpen(nTr)) {
/* Open this row */
this.src = "http://i.imgur.com/d4ICC.png";
this.oTable.fnOpen(nTr, fnFormatDetails(iTableCounter, TableHtml), 'details-control');
this.oInnerTable = $("#exampleTable_" + iTableCounter).dataTable({
'bJQueryUI': true,
'sPaginationType': 'full_numbers'
});
iTableCounter = iTableCounter + 1;
}
});
});
// Handle click on "Collapse All" button
$('#btn-hide-all-children').on('click', function () {
// Enumerate all rows
oTable.rows().every(function () {
// If row has details expanded
if (oTable.fnIsOpen(nTr)) {
/* This row is already open - close it */
this.src = "http://i.imgur.com/SD7Dz.png";
oTable.fnClose(nTr);
}
});
});
});
});
td.details-control {
background: url('https://cdn.rawgit.com/DataTables/DataTables/6c7ada53ebc228ea9bc28b1b216e793b1825d188/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('https://cdn.rawgit.com/DataTables/DataTables/6c7ada53ebc228ea9bc28b1b216e793b1825d188/examples/resources/details_close.png') no-repeat center center;
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables_themeroller.css">
<link rel="stylesheet" type="text/css" href="https://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/jquery.dataTables.min.js"></script>
<script type="text/javascript" charset="utf8" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<!-- Col reorder with resize-->
<script src="colreorderwithresize.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
</head>
<body>
<button id="btn-show-all-children" type="button">Expand All</button>
<button id="btn-show-all-children" type="button">Collapse All</button>
<table id="exampleTable">
<thead>
<tr>
<th>Year</th>
<th>Month</th>
<th>Savings</th>
</tr>
</thead>
<tbody>
<tr>
<td>2012</td>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>2012</td>
<td>February</td>
<td>$80</td>
</tr>
</tbody>
</table>
<div style="display:none">
<table id="exampleTable_2" class="display select" width="100%">
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
<th>Extn.</th>
<th>E-mail</th>
</tr>
</thead>
<tbody >
<tr>
<td>Tiger</td>
<td>Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
<td>5421</td>
<td>t.nixon#datatables.net</td>
</tr>
<tr>
<td>Garrett</td>
<td>Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011/07/25</td>
<td>$170,750</td>
<td>8422</td>
<td>g.winters#datatables.net</td>
</tr>
</tfoot>
</table>
</div>
</body>
</html>
PROBLEM
There are too many issues with the code to list them all. For example:
Multiple versions of jQuery DataTables included - 1.9 and 1.10
Multiple versions of jQuery included: 1.11 and 3.5
DataTables 1.10 API method such as rows() are called on DataTables 1.9 instance, see API for more details.
Event handlers are assigned multiple times in incorrect places.
SOLUTION
Please see below the corrected code and adjust to the libraries that you're using.
function fnFormatDetails(table_id, html) {
var sOut = "<table id=\"exampleTable_" + table_id + "\">";
sOut += html;
sOut += "</table>";
return sOut;
}
var iTableCounter = 1;
var oTable;
var oInnerTable;
var TableHtml;
//Run On HTML Build
$(document).ready(function () {
TableHtml = $('#exampleTable_2').html();
//Insert a 'details' column to the table
var nCloneTh = document.createElement('th');
var nCloneTd = document.createElement('td');
$('#exampleTable thead tr').each(function () {
this.insertBefore(nCloneTh, this.childNodes[0]);
});
//Initialse DataTables, with no sorting on the 'details' column
var oTable = $('#exampleTable').dataTable({
'bJQueryUI': true,
'sPaginationType': 'full_numbers',
'aoColumnDefs': [{
'bSortable': false,
'class': 'details-control',
'aTargets': [0]
}
],
'aaSorting': [[1, 'asc']]
});
/* Add event listener for opening and closing details
* Note that the indicator for showing which row is open is not controlled by DataTables,
* rather it is done here
*/
$('#exampleTable tbody tr td.details-control').on('click', function () {
var nTr = $(this).closest('tr');
if (oTable.fnIsOpen(nTr)) {
oTable.fnClose(nTr);
} else {
oTable.fnOpen(nTr, fnFormatDetails(iTableCounter, TableHtml), 'details-control');
oInnerTable = $('#exampleTable_' + iTableCounter).dataTable({
'bJQueryUI': true,
'sPaginationType': 'full_numbers'
});
iTableCounter = iTableCounter + 1;
}
});
// Handle click on "Collapse All" button
$('#btn-hide-all-children').on('click', function () {
// Enumerate all rows
oTable.$('tr').each(function(index, nTr){
// If row has details expanded
if (oTable.fnIsOpen(nTr)) {
oTable.fnClose(nTr);
$(nTr).removeClass('shown');
}
});
});
$('#btn-show-all-children').on('click', function () {
// Enumerate all rows
oTable.$('tr').each(function(index, nTr){
// If row has details collapsed
if (!oTable.fnIsOpen(nTr)) {
/* Open this row */
oTable.fnOpen(nTr, fnFormatDetails(iTableCounter, TableHtml), 'details-control');
$(nTr).addClass('shown');
}
});
});
});
td.details-control {
background: url('https://cdn.rawgit.com/DataTables/DataTables/6c7ada53ebc228ea9bc28b1b216e793b1825d188/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('https://cdn.rawgit.com/DataTables/DataTables/6c7ada53ebc228ea9bc28b1b216e793b1825d188/examples/resources/details_close.png') no-repeat center center;
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.21/datatables.min.css">
<script type="text/javascript" charset="utf8" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<!-- Col reorder with resize-->
<script src="colreorderwithresize.js"></script>
<script src="https://cdn.datatables.net/v/dt/dt-1.10.21/datatables.min.js"></script>
</head>
<body>
<button id="btn-show-all-children" type="button">Expand All</button>
<button id="btn-hide-all-children" type="button">Collapse All</button>
<table id="exampleTable" class="display">
<thead>
<tr>
<th>Year</th>
<th>Month</th>
<th>Savings</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>2012</td>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td></td>
<td>2012</td>
<td>February</td>
<td>$80</td>
</tr>
</tbody>
</table>
<div style="display:none">
<table id="exampleTable_2" class="display select" width="100%">
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
<th>Extn.</th>
<th>E-mail</th>
</tr>
</thead>
<tbody >
<tr>
<td>Tiger</td>
<td>Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
<td>5421</td>
<td>t.nixon#datatables.net</td>
</tr>
<tr>
<td>Garrett</td>
<td>Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011/07/25</td>
<td>$170,750</td>
<td>8422</td>
<td>g.winters#datatables.net</td>
</tr>
</tfoot>
</table>
</div>
</body>
</html>
LINK
Please see jQuery DataTables: How to expand/collapse all child rows for more information and examples.
I'm filtering the individual table column searching select inputs. It's working, but I wanted to be able to select more than one product.
Normal works, as I show:
initComplete: function () {
this.api().columns().every( function () {
var column = this;
var select = $('<select style="width: 350px;"><option value=""></option></select>')
.appendTo( $(column.footer()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
} );
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
} );
} );
}
But now how do I select more than one product, in the html of select I'm putting the multiple, but so does the filter no longer:
initComplete: function () {
this.api().columns().every( function () {
var column = this;
var select = $('<select style="width: 350px;" multiple><option value=""></option></select>')
.appendTo( $(column.footer()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
} );
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
} );
} );
}
Can you help?
In general, multiple values can be searched with OR. In regex, | is logical OR. So try joining the multiple values using join('|')
DEMO
var table = $('#example').DataTable({
initComplete: function() {
this.api().columns().every(function() {
var column = this;
var select = $('<select multiple><option value=""></option></select>')
.appendTo($(column.footer()).empty())
.on('change', function() {
column
.search($(this).val().map($.fn.dataTable.util.escapeRegex).join('|'), true, false)
.draw();
});
column.data().unique().sort().each(function(d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet" />
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Numero</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>155555</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>1</td>
<td>2009/01/12</td>
<td>$86,000</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>1</td>
<td>2009/01/12</td>
<td>$86,000</td>
</tr>
</tfoot>
</table>
I need to save all the data that is in my datatable
How could I add a general button that keeps everything in my datatable?
This in my current Project :
var table = $('#listaDocumentos').DataTable({
dom: 'Bfrtip',
buttons: [
'copy', 'csv', 'excel', 'pdf'
],
language: {
"decimal": "",
"emptyTable": "No hay información",
"info": "Mostrando _START_ a _END_ de _TOTAL_ Documentos",
"infoEmpty": "Mostrando 0 to 0 of 0 Documentos",
"infoFiltered": "(Filtrado de _MAX_ total entradas)",
"infoPostFix": "",
"thousands": ",",
"lengthMenu": "Mostrar _MENU_ Documentos",
"loadingRecords": "Cargando...",
"processing": "Procesando...",
"search": "Buscar:",
"zeroRecords": "Sin resultados encontrados",
"paginate": {
"first": "Primero",
"last": "Ultimo",
"next": "Siguiente",
"previous": "Anterior"
}
}
});
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.5.2/css/buttons.dataTables.min.css"> <script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.5.2/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.flash.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.html5.min.js"></script>
<table id="listaDocumentos" class="table table-striped table-bordered" 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>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>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
</table>
What i understand from your question is
you need to save data which is currently showing in the view(Html page) as tabular format.
In this case you can use jquery or javascript like below to get the data.
var table = $("table tbody");
table.find('tr').each(function (i) {
// comment loop through the tr and get value of every td within this tr tag
var tds = $(this).find('td');
var Name = $tds.eq(0).text();
var Position = $tds.eq(1).text();
var office = $tds.eq(2).text();
var age = $tds.eq(3).text();
var startPosition = $tds.eq(4).text();
var salary = $tds.eq(5).text();
});
Then bind a button in view like
<input type="button" id="btn_data_save" value="Save Data"/>
Then an ajax call to pass the data to server. WIthin that call you need to collect all the value and build an array of object.
$(document).on('click','#btn_data_save', function(){
var ary=[];
var table = $("table tbody");
table.find('tr').each(function (i) {
var obj={};
obj.tds = $(this).find('td');
obj.name = $tds.eq(0).text();
obj.position = $tds.eq(1).text();
obj.office = $tds.eq(2).text();
obj.age = $tds.eq(3).text();
obj.startPosition = $tds.eq(4).text();
obj.salary = $tds.eq(5).text();
ary.Push(obj);
});
$.ajax({
type: 'POST',
url: '',
data: { list: JSON.stringify(ary) },
dataType: 'json',
success: function (data) {
}
});
});
Finally in controller
[HttpPost]
public ActionResult SaveData(string list)
{
//comment do your work
}
Please comment if you do not understand the solution. i will describe if necessary.