disable pagination if there is only one page in datatables - javascript

I am implementing datatbales and according to my requirement, most of the things have been resolved except the pagination issue. In my case for every time pagination navigation is displaying. I want to disable the pagination navigation if there is only one page at all.How to do that? My code is like:
JS
<script>
function fnFilterColumn(i) {
$('#example').dataTable().fnFilter(
$("#col" + (i + 1) + "_filter").val(),
i
);
}
$(document).ready(function() {
$('#example').dataTable({
"bProcessing": true,
"sAjaxSource": "datatable-interestdb.php",
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"sDom": 'T<"clear">lfrtip',
"oTableTools": {
"aButtons": [
{
"sExtends": "csv",
"sButtonText": "Save to CSV"
}
]
},
"oLanguage": {
"sSearch": "Search all columns:"
}
});
$("#example").dataTable().columnFilter({
aoColumns: [
null,
null,
null,
null
]
});
$("#col1_filter").keyup(function() {
fnFilterColumn(0);
});
});
</script>
HTML
<table cellpadding="3" cellspacing="0" border="0" class="display userTable" aria-describedby="example_info">
<tbody>
<tr id="filter_col1">
<td>Interest:</td>
<td>
<input type="text" name="col1_filter" id="col1_filter">
</td>
</tr>
</tbody>
</table>
<table width="100%" border="0" align="center" cellpadding="2" cellspacing="1" class="form_table display" id="example">
<thead>
<tr>
<th class="sorting_asc" width="25%">Interest</th>
<th width="25%">Name</th>
<th width="25%">Email</th>
<th width="25%">Contact No</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="4" class="dataTables_empty">Loading data from server</td>
</tr>
</tbody>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>

Building off of Nicola's answer, you can use the fnDrawCallback() callback and the oSettings object to hide the table pagination after it's been drawn. With oSettings, you don't need to know anything about the table settings (records per page, selectors specific to the table, etc.)
The following checks to see if the per-page display length is greater than the total records and hides the pagination if it is:
$('#your_table_selector').dataTable({
"fnDrawCallback": function(oSettings) {
if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
$(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
} else {
$(oSettings.nTableWrapper).find('.dataTables_paginate').show();
}
}
});
Documentation
fnDrawCallback()
oSettings

You must hide them dynamically I think, you can use fnDrawCallback()
$('#example').dataTable({
"fnDrawCallback": function(oSettings) {
if ($('#example tr').length < 11) {
$('.dataTables_paginate').hide();
}
}
});​
EDIT - another way found here could be
"fnDrawCallback":function(){
if ( $('#example_paginate span span.paginate_button').size()) {
$('#example_paginate')[0].style.display = "block";
} else {
$('#example_paginate')[0].style.display = "none";
}
}

This is the correct approach when working in V1.10+ of JQuery Datatables. The process is generally the same as in previous versions but the event names and API methods are slightly different:
$(table_selector).dataTable({
preDrawCallback: function (settings) {
var api = new $.fn.dataTable.Api(settings);
var pagination = $(this)
.closest('.dataTables_wrapper')
.find('.dataTables_paginate');
pagination.toggle(api.page.info().pages > 1);
}
});
Documentation
https://datatables.net/reference/option/preDrawCallback
https://datatables.net/reference/api/page.info()

See my feature plugin conditionalPaging.
Usage:
$('#myTable').DataTable({
conditionalPaging: true
});
or
$('#myTable').DataTable({
conditionalPaging: {
style: 'fade',
speed: 500 // optional
}
});

Add this code to your datatables initialisation request.
JQUERY
Apply to single datatable:
"fnDrawCallback": function (oSettings) {
var pgr = $(oSettings.nTableWrapper).find('.dataTables_paginate')
if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
pgr.hide();
} else {
pgr.show()
}
}
Apply to all datatables:
"fnDrawCallback": null
Edit datatables.js to apply the code site wide.

I'm doing following to achieve this goal, as it is more dynamic solution that is not expressed above. as first it is getting total number of pages and then decide to show/hide pagination.
Beauty of this code is only if user change page length then it will not effected.
jQuery('#example').DataTable({
fnDrawCallback: function(oSettings) {
var totalPages = this.api().page.info().pages;
if(totalPages == 1){
jQuery('.dataTables_paginate').hide();
}
else {
jQuery('.dataTables_paginate').show();
}
}
});

jQuery
- I tried with the following options, it worked for me
$("#your_tbl_selector").dataTable({
"pageLength": 3,
"autoWidth": false,
"fixedHeader": {"header": false, "footer": false},
"columnDefs": [{ "width": "100%", "targets": 0 }],
"bPaginate": true,
"bLengthChange": false,
"bFilter": true,
"bInfo": false,
"bAutoWidth": false,
"oLanguage": {
"oPaginate": {
"sNext": "",
"sPrevious": ""
}
},
"fnDrawCallback": function(oSettings) {
if (oSettings._iDisplayLength >= oSettings.fnRecordsDisplay()) {
$(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
}
}
});
DataTable Output View

I prefer #sina's solution. Good job.
But my one comes with some neccessary improvements.
#sina forgot the else part to show the pagination again if neccesary. And I added the possibility to define the all option in the lengthMenu like following:
jQuery('#your_table_selector').dataTable({
"lengthMenu": [[10, 25, 50, 100, 250, 500, -1], [10, 25, 50, 100, 250, 500, "All"]],
"fnDrawCallback": function(oSettings) {
if (oSettings._iDisplayLength == -1
|| oSettings._iDisplayLength > oSettings.fnRecordsDisplay())
{
jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
} else {
jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').show();
}
}
});

This callback function works generically with any datatable without having to hardcode the table ID:
$('.data-table').dataTable({
fnDrawCallback: function(oSettings) {
if(oSettings.aoData.length <= oSettings._iDisplayLength){
$(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
}
}
});

Just add the following to your stylesheet:
.dataTables_paginate .paginate_button.disabled {
display: none;
}

I know this is an old post but for those of us that will be using this, and have OCD just like me, a change is needed.
Change the if statement,
if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay())
to
if (oSettings._iDisplayLength >= oSettings.fnRecordsDisplay())
With this little change you will see the pagination buttons for records lengths greater than 10, 25, 50, 100 instead of presenting the pagination buttons with only 10 records, technically 10, 25, etc records is still a one page view.

You can follow this way also.
"fnDrawCallback":function(){
if(jQuery('table#table_id td').hasClass('dataTables_empty')){
jQuery('div.dataTables_paginate.paging_full_numbers').hide();
} else {
jQuery('div.dataTables_paginate.paging_full_numbers').show();
}
}
This worked for me.

I tried to make sPaginationType as Dynamic in datatable for every entry but i can't find proper solution for that but what i did was
"fnDrawCallback": function(oSettings) {
$('select[name="usertable_length"]').on('change', function(e) {
var valueSelected = this.value;
if ( valueSelected < 10 ) {
$('.dataTables_paginate').hide();
} else {
$('.dataTables_paginate').show();
}
});
},

$('#dataTable_ListeUser').DataTable( {
//usual pager parameters//
"drawCallback": function ( settings ) {
/*show pager if only necessary
console.log(this.fnSettings());*/
if (Math.ceil((this.fnSettings().fnRecordsDisplay()) / this.fnSettings()._iDisplayLength) > 1) {
$('#dataTable_ListeUser_paginate').css("display", "block");
} else {
$('#dataTable_ListeUser_paginate').css("display", "none");
}
}
});

This isn't directly possible as DataTables doesn't support enabling and disabling features are run time. However, what you could do is make use of the fnDrawCallback() function to check to see if there is only one page, and if so hide the pagination controls.

If your data is not dynamic, i.e., server generates HTML table which is then enhanced by DataTables you can render the paging option on the server (I am using razor).
$("#results").dataTable({
paging: #(Model.ResultCount > Model.PageSize ? "true" : "false"),
// more ...
});

Here is my solution, it works also if you have multiple tables on the same page. It prevents the colision for example (table A must have pagination, and B must not).
tableId in my code is never undefined. If you haven't defined an ID for your table, dataTable will do it for you by adding something like 'DataTables_Table_0'
fnDrawCallback: function (oSettings) {
if ($(this).DataTable().column(0).data().length <= oSettings._iDisplayLength) {
var tableId = $(this).attr('id');
$('#' + tableId + '_paginate').hide();
}
}

This Solved my issues:
.dataTables_paginate .disabled {
display:none;
}
dataTables_paginate .disabled + span {
display:none;
}
Hope it helps you all

$("#datatable").DataTable({
"fnDrawCallback": function (oSettings) {
if ($(oSettings.nTBody).find("tr").length < $(oSettings.nTableWrapper).find("select[name=fileList_length]").val()) {
$(oSettings.nTableWrapper).children(".dataTables_paginate").hide();
}
}
});

this worked for me:
if ($('#dataTableId_paginate').find('li').length < 4) {
$('#segment-list_paginate').html('');
}

Related

How to detect empty table when selecting a row in a jQuery Datatable

Giving a simple table like this
<table id="exampleTable" class="table hover nowrap">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead></table>
Also, using the jQuery Datatable plugin and making the rows selectable, like in this example. The Javascript goes like this:
var exampleTable = $("#exampleTable").DataTable(
{
"bDestroy": true,
"lengthChange": false,
"bPaginate": false
});
$('#exampleTable tbody').on( 'click', 'tr', function () {
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
}
else {
$('#exampleTable tr.selected').removeClass('selected');
$(this).addClass('selected');
}
} );
So, when the table is empty, it shows a selectable row which says something like:
No data available in table
How to detect the table is empty and not allow selection on that kind of "message rows"?
Here is a fiddle with the code.
you can check if there is td with the class dataTables_empty like this:
$('#exampleTable tbody').on( 'click', 'tr', function () {
if ( $(this).hasClass('selected')) {
$(this).removeClass('selected');
}
else if(! $(this).find('td.dataTables_empty').length){
$('#exampleTable').DataTable().rows().nodes().each(function(){
$(this).removeClass('selected');
});
$(this).addClass('selected');
}
} );
You can use the - .row().data() method to see if there is data. if this returns undefined, you can disable selection of the row.
i also think this would be an ideal solution instead of dom traversal which is more expensive. what do you guys think ?
below is the updated fiddle. you can comment the tbody from the html to test it.
Let me know if this helps.
Modified Fiddle
inside your click method, add before everything
if($('#exampleTable tbody tr td').length == 1){
return;
}

DataTables - Create Custom Pagination Style (Load More Style)

I would like to use a pagination style for DataTable's that is mobile friendly, I'd just like a button to load more rows when clicked which will append rows under the current visible rows.
I know this isn't available as a default option in DataTables but I believe it shouldn't be to difficult to create. Has anyone created this pagination method or seen it in use on a DataTable's table?
If not how can I modify the code of my table at https://jsfiddle.net/6k0bshb6/16/ to use this pagination style to make my table mobile friendly.
// This function is for displaying data from HTML "data-child-value" tag in the Child Row.
function format(value) {
return '<div>Hidden Value: ' + value + '</div>';
}
// Initialization of dataTable and settings.
$(document).ready(function () {
var dataTable = $('#example').DataTable({
bLengthChange: false,
"pageLength": 5,
"pagingType": "simple",
"order": [[ 7, "asc" ]],
"columnDefs": [
{
"targets": [ 5 ],
"visible": false,
"searchable": true
},
{
"targets": [ 6 ],
"visible": false,
"searchable": true
},
{
"targets": [ 7 ],
"visible": false,
"searchable": true
}
],
// Dropdown filter function for dataTable from hidden column number 5 for filtering gifts.
initComplete: function () {
this.api().columns(5).every(function () {
var column = this;
var select = $('<select><option value="">Show all</option></select>')
.appendTo($("#control-panel").find("div").eq(1))
.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>')
});
});
}
});
// This function is for handling Child Rows.
$('#example').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = dataTable.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(format(tr.data('child-value'))).show();
tr.addClass('shown');
}
});
// Checkbox filter function below is for filtering hidden column 6 to show Free Handsets only.
$('#checkbox-filter').on('change', function() {
dataTable.draw();
});
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var target = '£0.00';
var position = data[6]; // use data for the position column
if($('#checkbox-filter').is(":checked")) {
if (target === position) {
return true;
}
return false;
}
return true;
}
);
});
UPDATE: I have found some information on how to do this on the DataTables website although I don't fully understand how to integrate it into my table.
https://datatables.net/forums/discussion/3920/twitter-facebook-style-pagination
What you could possibly do (I've not tried it, but I can't think of why it wouldn't work...) is to set the scroll loading gap (the number of pixels before the bottom of the scroll for when the new data is loaded) to a negative number ( http://datatables.net/usage/options#iScrollLoadGap ) and then add a little button at the bottom of the table (might need to use fnDrawCallback for that) which when clicked will load the next data set (fnPageChange('next') should do that).
Anyone know how I can make this work with my table? Could someone show me how to do this on jsfiddle?
UPDATE 2: Response from datatables admin https://datatables.net/forums/discussion/35148/load-more-style-twitter-style-pagination-custom#latest
The iScrollLoadGap option you mention isn't available in 1.10 -
infinite scrolling was removed in 1.10 and that option with it.
However the basic principle still remains - you can either have a
button the user needs to press to load more rows (either increase the
page size or use rows.add() to add more rows) or use a scroll
detection to do the same thing.
Allan
Solved..
<button id="button" type="button">Page +5</button>
//Alternative pagination
$('#button').on( 'click', function () {
var VisibleRows = $('#example>tbody>tr:visible').length;
var i = VisibleRows + 5;
dataTable.page.len( i ).draw();
} );
you could use something like:
$(window).on("swipeleft", $("#example_next").click());
$(window).on("swiperight", $("#example_previous").click());
it will only work on mobile and uses your existing functionality...

Button click function not working on datatable toolbar custom button

As continuation to this question,
Myself added the toggle button to datatable toolbar dom element as
"dom": "T<'clear'><'row DatatableRow'<'col-xs-3'l><'col-xs-3'><'col-xs-3'<'#ToggleButton'>><'col-xs-3 text-right'f>r>t<'row DatatableRow'<'col-xs-3'i><'col-xs-3'><'col-xs-3'><'col-xs-3 text-right'p>>"
and button is added as
$("div#ToggleButton").html('<br/><button type="button" class="btn btn-primary btn-sm" id="ToggleColumns">Toggle</button>');
But in this case, the click function is not working?
It was not working because you were trying to bind a button that is not yet existed on DOM. And you are recreating the table to change the fixed column index. I cant say this is a good way but i couldnt find to change fixed column of rendered datatable on documentations.
but i fixed your fiddle on your way.
the idea is to bind the button on init of datatable right after adding the custom button html like.
$(document).ready(function () {
foo(2);
function foo(columnNumber) {
table = $('#example').on('init.dt', function () {
$("div#ToggleButton").html('<br/><button type="button" class="btn btn-primary btn-sm" id="ToggleColumns">Toggle</button>');
$('#ToggleColumns').click(function () {
table.destroy();
debugger;
if (columnNumber == 2) {
columnNumber = 0;
} else {
columnNumber = 2;
}
foo(columnNumber);
});
}).DataTable({
scrollY: "300px",
scrollX: true,
scrollCollapse: true,
paging: false,
"dom": "T<'clear'><'row DatatableRow'<'col-xs-3'l><'col-xs-3'><'col-xs-3'<'#ToggleButton'>><'col-xs-3 text-right'f>r>t<'row DatatableRow'<'col-xs-3'i><'col-xs-3'><'col-xs-3'><'col-xs-3 text-right'p>>",
});
new $.fn.dataTable.FixedColumns(table, {
leftColumns: columnNumber
// rightColumns: 1
});
}
});
If you can find a way to change the fixedColumn number...
$('#ToggleColumns').click(function () {
// replace the following codes with changing fixedColumn columns
table.destroy();
if (columnNumber == 2) {
columnNumber = 0;
} else {
columnNumber = 2;
}
foo(columnNumber);
});

Strange checkbox click function issue

Using datatables. The problem is $('.checkbox') click function only works on first page of datatables, nowhere else. Note that, $('#check_all') works on every page.
JS looks like that:
function changeQt(){
if($('#quantity').is(':hidden'))
$('#quantity').fadeIn("slow");
$('#quantity').animate({
borderColor: "#00a9e0"
}, 'fast').text(totalqt).delay(400).animate({
borderColor: "#fff"
}, 'fast');
}
function doIt(obj) {
if ($(obj).is(":checked")) {
$(obj).closest("tr").not('#hdr').addClass("row_selected");
totalqt=totalqt + parseInt($(obj).closest("tr").find("#qt").text(), 10);
}
else {
$(obj).closest("tr").not('#hdr').removeClass("row_selected");
totalqt=totalqt - parseInt($(obj).closest("tr").find("#qt").text(), 10);
if(totalqt<0) totalqt=0;
}
}
function checkAllCheckboxes(isChecked) {
if(isChecked ){
totalqt=0;
}
$('.checkbox').each(function(){
$(this).prop('checked', isChecked);
doIt(this);
});
changeQt();
}
$(document).delegate('td.item_id', 'click', function(e){
e.stopPropagation();
});
$(document).delegate('#list > tbody > tr', 'click', function(){
window.open($(this).attr("url"));
});
$(document).ready(function() {
$("input:submit, input:reset").button();
$.datepicker.regional[""].dateFormat = 'dd.mm.yy';
$.datepicker.setDefaults($.datepicker.regional['']);
$('select[name=list_length]').change(function(){
if ($('#check_all').is(':checked'))
$('#check_all').click();
});
var oTable= $('#list').dataTable( {
"bJQueryUI": true,
"iDisplayLength": 25,
"aaSorting": [],
"aoColumns": [
{
"bSortable": false
},
null, null, null,null,null, null, null
]
} ).columnFilter({
sPlaceHolder: "head:before",
aoColumns: [ null, null, null,null,null, null, null,
{
type: "date-range"
}
]
});
$('.checkbox').click(function(e) {
e.stopPropagation();
doIt(this);
changeQt()
});
$('select[name=list_length]').change(function(){
if($('#check_all').is(':checked')){
$('#check_all').prop('checked', false);
checkAllCheckboxes(false);
}
});
$('#check_all').click(function(){
checkAllCheckboxes(this.checked);
});
});
Here is 1 row from this table:
<tr url="?page=item&id=1411">
<td class="item_id"><input type="checkbox" name="checkbox[]" method="post" value="1411" class="checkbox"/> 1411</td>
<td> 9814</td>
<td style="text-align:center">BK</td>
<td style="text-align:center">36</td>
<td style="text-align:center" id="qt">1</td>
<td style="text-align:center">15</td>
<td style="text-align:center">12</td>
<td>15.02.2012</td>
</tr>
If someone want to see page in action, please join discussion: Here.
I assume dataTables is adding/removing elements from the DOM, and with them will go the event handlers attached to them.
Instead of attaching events by the shortcuts (eg click(), or blur()) which will only work when the element in question is available on page load, use delegate() (or on() in jQuery 1.7+)
$("#list").delegate('.checkbox', 'click', function(e) {
e.stopPropagation();
doIt(this);
changeQt()
});
jQ 1.7+
$("#list").on('click', '.checkbox', function(e) {
e.stopPropagation();
doIt(this);
changeQt()
});
The FAQ about events will be of some use to you here: http://datatables.net/faqs#events . It also includes examples of how to apply the solution. In this case I would suggest using:
table.$('.checkbox').click(function(e) {
where table is the DataTables instance. The $ API method will give you a jQuery object that will operate on all rows in the table, regardless of current paging.

jQuery datatables and jScrollPane - table header doesn't scroll

I tried to have jquery datatables and jScrollpane work together, it went well but one thing..
when I scroll the table to the right, the header doesn't seem to get along.
here's my code snippet on my html:
$("#my-table").dataTables({
// ...
"sScrollX": "100%",
"sScrollXInner": "150%",
"fnDrawCallback": function(){
$('.dataTables_scrollBody').jScrollPane();
}
});
does anyone have an idea?
any help would be appreciated :)
thanks..
This answer is already a bit old, but I just had the same problem. I solved it using the jScrollPane events that are fired. When the table body scrolls, this event is noticed and the table header is manually set to the correct position.
$('table.selection_list').dataTable({
sScrollY: '300px',
sScrollX: '100%',
sScrollXInner: '320%',
bPaginate: false,
bInfo: false,
bFilter: false,
"fnInitComplete": function() {
var table_header,
_this = this;
table_header = $('.dataTables_scrollHeadInner').css('position', 'relative');
$('body.admin.selections_index').find('.dataTables_scrollBody').bind('jsp-scroll-x', function(event, scrollPositionX, isAtLeft, isAtRight) {
table_header.css('right', scrollPositionX);
}).jScrollPane();
}
});
I am using bScrollInfinite and changed little bit your code:
fnDrawCallback: function() {
table_header = $('.dataTables_scrollHeadInner').css('position', 'relative');
$('body').find('.dataTables_scrollBody').bind('jsp-scroll-y',
function(event, scrollPositionY, isAtTop, isAtBottom) {
table_header.css('bottom', scrollPositionY);
}).jScrollPane({
verticalDragMinHeight: 15,
verticalDragMaxHeight: 15,
autoReinitialise: true
});
}
But dont know how to tell the table, that I am on the end of table and want to load another data set:(

Categories