What's the problem here? I get the search I want, but it doesn't redraw the table when using the exact match regex column. I'm using a single column to better filter a ranking value that is numeric.
<script>
jQuery(document).ready( function () {
// Setup - add a text input to each header cell
jQuery('#table1 thead tr#filterrow th').each( function () {
var title = jQuery('#table1 thead th').eq( jQuery(this).index() ).text();
jQuery(this).html( '<input type="text" onclick="stopPropagation(event);" placeholder="Search '+title+'" />' );
} );
// Setup - add a text input to each footer cell
jQuery('#table1 tfoot tr#filterrow th').each( function () {
var title = jQuery('#table1 tfoot th').eq( jQuery(this).index() ).text();
jQuery(this).html( '<input type="text" onclick="stopPropagation(event);" placeholder="Search '+title+'" />' );
} );
// DataTable
var table = jQuery('#table1').DataTable( {
orderCellsTop: true,
aLengthMenu: [[-1, 10, 25, 50, 100, 200, 300, 400, 500],[ "All", 10, 25, 50, 100, 200, 300, 400, 500]],
iDisplayLength: -1,
dom: 'B<"lb">lfrtip',
responsive: 'true',
buttons: [
{ extend: 'copy',
oSelectorOpts: {
filter: 'applied'
}
},
{ extend: 'csv',
oSelectorOpts: {
filter: 'applied'
}
},
{ extend: 'pdfHtml5',
oSelectorOpts: {
filter: 'applied'
}
},
{ extend: 'print',
autoPrint: false,
oSelectorOpts: {
filter: 'applied'
}
}
]
} );
// Apply the filter
jQuery("#table1 thead input").on( 'keyup change', function () {
table
.column( jQuery(this).parent().index()+':visible' )
.search(this.value)
.draw();
} );
jQuery("#table1 tfoot input").on( 'keyup change', function () {
table
.column( jQuery(this).parent().index()+':visible' )
.search(this.value)
.draw();
} );
jQuery("#table1 thead input").on( 'keyup change', function () {
table
.column(4)
.search("^" + this.value + "$", true, false, true)
.draw();
} );
jQuery("#table1 tfoot input").on( 'keyup change', function () {
table
.column(4)
.search("^" + this.value + "$", true, false, true)
.draw();
} );
function stopPropagation(evt) {
if (evt.stopPropagation !== undefined) {
evt.stopPropagation();
} else {
evt.cancelBubble = true;
}
}
} );
</script>
I feel like something in my code should be condensed.
The problem is that stopPropagation() method is defined inside ready event handler and is not visible outside of it.
Move definition stopPropagation() outside of ready event handler:
jQuery(document).ready( function () {
// ... skipped ...
});
function stopPropagation(evt) {
if (evt.stopPropagation !== undefined) {
evt.stopPropagation();
} else {
evt.cancelBubble = true;
}
}
NOTES
Since you're using jQuery you could rewrite the same with less code. And the click event handler could be placed inside ready event handler.
You're assigning keyup change twice for each input element in footer and header. Consider rewriting your code as shown in this example.
Related
Referring to the Individual column searching (text inputs) and Individual column searching (select inputs) to use multiple filters on jQuery DataTable, I mixed them up in order to allow text inputs searches on some columns and select inputs searching on others.
It almost works, but select inputs don't work correctly: the first select input on the third column shows values of the first column, the second select input shows the second column, and so on.
$( document ).ready(function() {
$('#wbe_table tfoot th.search_th').each( function () {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="Search '+title+'" />' );
} );
var oTable = $('#wbe_table').DataTable( {
orderCellsTop: true,
fixedHeader: true,
responsive: true,
lengthChange: true,
autoWidth: true,
pageLength: 50,
order: [[7, "desc"]],
columnDefs: [
{
targets: [4],
orderable: false
},
{
type: "currency",
targets: [7,8,9,10]
},
],
dom: 'Bfrtip',
buttons: [
'copy', 'csv', 'excel', 'pdf', 'print'
] ,
//Select input search
initComplete: function () {
var api = this.api();
$('.filterhead', api.table().footer()).each( function (i) {
var column = api.column(i);
var select = $('<select><option value=""></option></select>')
.appendTo( $(this).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>' );
} );
} );
}
});
// Text input 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();
}
} );
} );
});
I'm using jquery and used datatable library.
I created my datatable like this:
$datatable = $('#datatable-buttons').DataTable({
keys: true, searching: false, "paging": false, "info": false,
buttons: [
{
extend: 'copyHtml5',
text: '<i class="fa fa-files-o"></i>',
titleAttr: 'Copy'
},
{
extend: 'excelHtml5',
text: '<i class="fa fa-file-excel-o"></i>',
titleAttr: 'Excel'
},
{
extend: 'csvHtml5',
text: '<i class="fa fa-file-text-o"></i>',
titleAttr: 'CSV'
}
],
orderCellsTop: true,
fixedHeader: true,
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('keyup change', function (e) {
e.stopPropagation();
// 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();
$(this)
.focus()[0]
.setSelectionRange(cursorPosition, cursorPosition);
});
});
}
});
I have a submit button to get data from my server and draw data to datatable:
function refreshDataTable(result) {
rowDataTable = PER_PAG * (CURRENT_PAGE - 1)
var rows = []
result.forEach((item => {
++rowDataTable
var data = [rowDataTable, item.order_id, "item.shipping.mobile", item.shipping.first_name, item.shipping.last_name, item.shipping.state, item.shipping.city, item.shipping.address, item.shipping.title, item.shipping.cost, item.shipping.delivery_time]
console.log("data",data)
rows.push(data)
}))
$datatable.rows.add(rows).draw();
}
it shows some inputs above each columns. but when I typing some texts it doesn't to filter my rows.
Can someone help me to create a single script merging these two?
The first script is included in my menĂ¹ bar that is included in all pages of my site. Contains the buttons for Print, Excel and PDF, landscape print and Italian language for my bootstrap tables. The second that i would include into the first is for single column search into the tables.
<script>
$(document).ready(function() {
$('#example').DataTable({
responsive: true,
dom: 'Bfrtip',
buttons: [
// Stampa in orizzontale
{ extend: "print", text: ' Stampa', className: 'btn btn-warning glyphicon glyphicon-print',
customize: function(win)
{
var last = null;
var current = null;
var bod = [];
var css = '#page { size: landscape; }',
head = win.document.head || win.document.getElementsByTagName('head')[0],
style = win.document.createElement('style');
style.type = 'text/css';
style.media = 'print';
if (style.styleSheet)
{
style.styleSheet.cssText = css;
}
else
{
style.appendChild(win.document.createTextNode(css));
}
head.appendChild(style);
}
},
{ extend: 'excelHtml5', text: ' Esporta Excel', className: 'btn btn-primary glyphicon glyphicon-list-alt' },
{ extend: 'pdfHtml5', text: ' Esporta PDF', className: 'btn btn-primary glyphicon glyphicon-file' }
],
"language": {
"url": "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Italian.json"
}
});
});
</script>
<script>
$(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="Cerca '+title+'" />' );
} );
// DataTable
var table = $('#example').DataTable();
// Apply the search
table.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change clear', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
} );
} );
</script>
Just remove extra script tag and document ready function as below.
<script>
$(document).ready(function() {
$('#example').DataTable({
responsive: true,
dom: 'Bfrtip',
buttons: [
// Stampa in orizzontale
{ extend: "print", text: ' Stampa', className: 'btn btn-warning glyphicon glyphicon-print',
customize: function(win)
{
var last = null;
var current = null;
var bod = [];
var css = '#page { size: landscape; }',
head = win.document.head || win.document.getElementsByTagName('head')[0],
style = win.document.createElement('style');
style.type = 'text/css';
style.media = 'print';
if (style.styleSheet)
{
style.styleSheet.cssText = css;
}
else
{
style.appendChild(win.document.createTextNode(css));
}
head.appendChild(style);
}
},
{ extend: 'excelHtml5', text: ' Esporta Excel', className: 'btn btn-primary glyphicon glyphicon-list-alt' },
{ extend: 'pdfHtml5', text: ' Esporta PDF', className: 'btn btn-primary glyphicon glyphicon-file' }
],
"language": {
"url": "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Italian.json"
}
});
// Setup - add a text input to each footer cell
$('#example tfoot th').each( function () {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="Cerca '+title+'" />' );
} );
// DataTable
var table = $('#example').DataTable();
// Apply the search
table.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change clear', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
} );
} );
</script>
I am using DataTables 1.10.12. I implemented it using MVC framwork. My problem is I have 25 columns in the table which I can accomodate on the same page if I do not have the sorting images in the . To remove them I have tried the following:
<table id="datatable-buttons-por" class="table table-striped table-bordered">
<thead style="font-size:smaller; background:none">
<tr>
And following
$(document).ready(function () {
var handleDataTableButtons = function () {
if ($("#datatable-buttons-por").length) {
$("#datatable-buttons-por").DataTable({
dom: "Bfrtip",
buttons: [
{
extend: "copy",
className: "btn-sm"
},
{
extend: "csv",
className: "btn-sm"
},
{
extend: "excel",
className: "btn-sm"
},
{
extend: "pdfHtml5",
className: "btn-sm"
},
{
extend: "print",
className: "btn-sm"
},
],
responsive: true
});
}
};
TableManageButtons = function () {
"use strict";
return {
init: function () {
handleDataTableButtons();
}
};
}();
var $datatable = $('#datatable-checkbox');
$datatable.dataTable({
'order': [[1, 'asc']],
'columnDefs': [
{ orderable: false, targets: [0] }
]
});
$datatable.on('draw.dt', function () {
$('input').iCheck({
checkboxClass: 'icheckbox_flat-green'
});
});
TableManageButtons.init();
//$('#datatable-buttons-por thead').css('background-image', 'none');
var table = $('#datatable-buttons-por').DataTable();
table.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>')
});
});
});
$('#datatable-buttons-por thead th').css('background-image', 'none');
in Javascript.
Seems like none of these working. What I am doing wrong here? By the way, I still want to keep my sorting functionality enabled.
You need to target the th not the thead
try:
$('#datatable-buttons-por thead th.sorting').css('background-image', 'none');
I currently have a DataTable that has data download buttons in format that I'm looking for:
$(document).ready(function() {
$('#dataTables-example').DataTable( {
dom: 'Bfrtip',
buttons: [
'copyHtml5',
'excelHtml5',
'csvHtml5',
'pdfHtml5'
]
} );
} );
However, I want to be able to filter columns with a dropdown menu in the footer - exactly like in the example in this link:
https://datatables.net/examples/api/multi_filter_select.html
The initialization code for that is:
$(document).ready(function() {
$('#dataTables-example').DataTable( {
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>' )
} );
} );
}
} );
} );
What I want is to combine these two functionalities - column filter and data download options. I've tried moving around the button and dom snippet into the code above:
dom: 'Bfrtip',
buttons: [
'copyHtml5',
'excelHtml5',
'csvHtml5',
'pdfHtml5'
]
} );
But I've had no luck getting it to display correctly (or at all).
I had an engineering breakthrough and did the obvious thing, added the DOM settings before:
initComplete: function(){.......
And it worked.
Complete function:
$(document).ready(function() {
$('#dataTables-example').DataTable( {
dom: 'lBfrtip',
buttons: [
'copyHtml5',
'excelHtml5',
'csvHtml5',
'pdfHtml5'
],
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>' )
} );
} );
}
});
});