I have 2 tables that are using DataTable jQuery Plug-in.
I wondering if there is a way to hide my pagination on the bottom right of my table.
Note:
Only show the pagination when I need one.
Hide the pagination when the query results is less than 10.
Use drawCallback option to handle DT draw event and show/hide pagination control based on available pages:
$('#table_id').dataTable({
drawCallback: function(settings) {
var pagination = $(this).closest('.dataTables_wrapper').find('.dataTables_paginate');
pagination.toggle(this.api().page.info().pages > 1);
}
})
$('#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");
}
}
});
Use 'drawCallback' to solve this problem.
1.On the webpage, use developer tool to inspect the 'previous' button, then you will find a div element that wraps both the 'previous' and 'next' buttons. DataTables automatically assigned an id to this div based on your html table element's id.
For example, I have a table with id 'Atable'. In this table, DataTables automatically created a div element with id called 'Atable_paginate' to wrap the previous and next buttons.
2.For drawCallback, we write a function which checks if there is less than 1 page, if so, we hide element by utilising id.
For example, you have set there are 20 records on one page by
pageLength: 20,
which means if there are less then 20 records, we don't need to display 'previous' and 'next' buttons. So we write like below,
drawCallback: function(settings){
if($(this).find('tbody tr').length <= 20){
$('#Atable_paginate').hide();
}
}
3.The initialization of Atable should be like below
var table = $('#Atable').DataTable({
pageLength: 20,
lengthChange: false,
drawCallback: function(settings){
if($(this).find('tbody tr').length <= 20){
$('#Atable_paginate').hide();
}
}
});
4.If there are more than one table on the webpage, apply this method on each table.
You can use fnDrawCallback() method to hide the pagination in dataTable.
var oTable = $('#datatable_sample').dataTable({
"iDisplayLength": 10,
"fnDrawCallback": function(oSettings) {
if ($('#datatable_sample tr').length < 10) {
$('.dataTables_paginate').hide();
}
}
});
The length which you can define as per the row you want to display in the listing.
$(this) did not work for me, probably because I am using TypeScript. So I used a different approach to get the JQuery element for the table wrapper and the DataTables API. This has been inspired by the answer of BitOfUniverse and tested with DataTables 1.10.
TypeScript:
'drawCallback': (settings: any) => {
// hide pager and info if the table has NO results
const api = new $.fn.dataTable.Api(settings);
const pageCount = api.page.info().pages;
const wrapper = $('#' + settings.sTableId).closest('.dataTables_wrapper');
const pagination = wrapper.find('.dataTables_paginate');
const info = wrapper.find('.dataTables_info');
pagination.toggle(pageCount > 0);
info.toggle(pageCount > 0);
}
You can give options when you create your datables on Javascript
$('.examples').DataTable({
"paging": false
});
All options are listed here:
http://www.datatables.net/reference/option/
Related
I have a Datatable which if 1 page is returned i want to hide the 'Items per pages' dropdown list and also the pagination. This also needs to work when filtering the table.
I am using the:
.DataTable().page.info()
Below is the code i have
"fnDrawCallback": function () {
var accountSearchDataTableInfo = $('#accountSearchDataTable').DataTable().page.info();
if (accountSearchDataTableInfo.pages == '1') {
console.log(accountSearchDataTableInfo.pages == '1')
$('#accountSearchDataTable_length').hide();
$('#accountSearchDataTable_paginate').hide();
}
if (accountSearchDataTableInfo.pages == 1) {
console.log(accountSearchDataTableInfo.pages == 1)
$('#accountSearchDataTable_length').hide();
$('#accountSearchDataTable_paginate').hide();
}
}
And this gives...
Initial table load table info
Filtered table info
As you can see from my IF i have tried a number and string but when i do console.log on these it comes back true but the items are still displayed.
I have tried .hide() and also .css('display', 'none') but nothing seems to be working and i'm at a loss what else to try.
When i look at the element in Dev tools the style attribute is added but nothing after it:
Initial table load
Filtered table
Found the solution. I was looking for the parent DIV but it appear that if i used each individual identifier i can hide them. so my IF now look like
if (accountSearchDataTableInfo.pages == '1') {
$('.mb-2').hide(); // Items per page DD
$('#accountSearchDataTable_previous').hide(); // Pagintator 'Previous' button
$('#accountSearchDataTable_next').hide(); // Pagintator 'Next' button
$('.paginate_button').hide(); // Pagintator page '1' button
}
You can use below api to determine pages number
table.api().page.info().pages
As stated in documentation:
https://datatables.net/reference/api/page.info()
And use drawCallback() after table is draw As documented here:
https://datatables.net/reference/option/drawCallback
Example how to hide pagination when page is 1 or less:
$('#example').dataTable( {
"drawCallback": function( settings ) {
var api = this.api();
var pagination = $(this).closest('.dataTables_wrapper').find('.dataTables_paginate');
pagination.toggle(api.page.info().pages > 1);
}
} );
I am sorting my tablesorter table successfully from a link outside the table, using var sorting = [[2,"n"]];. Clicking that link does sort the table the opposite way (from ASC to DESC, for example).
How can I sort the table by the 3rd column ascending, without losing the ability to sort in the opposite direction by clicking the link again? var sorting = [[2,"a"]]; does sort the table ascending, but I cannot click that link again to sort in the opposite direction!
Thanks for your help!
These are my lines:
$("#trigger-tg").click(function() {
// set sorting column and direction, this will sort on the first and third column the column index starts at zero
var sorting = [[2,"n"]];
// sort on the first column
$("table").trigger("sorton",[sorting]);
// return false to stop default link action
return false;
});
The tablesorter link in your question is pointing to the original tablesorter, but the code links and example are from my fork of tablesorter which does include the ability to pass an "n" to sort the column in the "next" direction.
The code example you shared does work - see demo.
$(function() {
var $table = $("table");
$table.tablesorter();
$("#trigger-tg").click(function() {
$table.trigger("sorton", [[[2, "n"]]]);
return false;
});
});
Here is the documentation page showing all possible settings - https://mottie.github.io/tablesorter/docs/example-trigger-sort.html
If you must use the original tablesorter, try the code from this demo.
Update: To notify the user that additional clicks will change the sort, try this code (demo)
HTML
<p>Sort Animals column from <a id="trigger-tg" href="#">A-Z</a>.</p>
Script
$(function() {
var $table = $("table"),
targetColumn = 2;
$table
.on("sortEnd", function() {
var c = this.config;
if (c.sortList[0][0] === targetColumn) {
$("#trigger-tg").text(c.sortList[0][1] === 0 ? "Z-A" : "A-Z");
}
})
.tablesorter();
$("#trigger-tg").click(function() {
$table.trigger("sorton", [[[targetColumn, "n"]]]);
return false;
});
});
I have a tooltip in Kendo UI which I'm trying to filter cells based on their column name, because the standard td:nthchild won't work (users can move columns around). I want to engage the tooltip based on if someone hovers over MY COLUMN NAME'S CELLS. How do I accomplish that in the filter field? Or should I do it in the show function?
this.$el.kendoTooltip({
filter: "th:contains('MY COLUMN NAME')",
show: function (e) {
if (this.content.text().length > 0) {
this.content.parent().css("visibility", "visible");
}
},
hide: function(e) {
this.content.parent().css("visibility", "hidden");
},
content: function (e) {
var target = e.target;
return $(target).siblings().first().text();
}
});
Like this ?
this.$el.kendoTooltip({
filter: "thead th:contains('ColumnA')"
});
Demo
UPDATE
As you want to show the tooltip on the row cell based on the column's title, you can't use filter parameter for that, it is meant to be used to filter only the target element, which is not your case. You will need some programming there, e.g:
show: function(e) {
let index = this.target().index(), // Get hovered element's column index
columns = grid.getOptions().columns, // Get grid's columns
column = columns[index]; // Get current column
// If target TD is not under 'ColumnA', prevent tooltip from being showed
if (column.title != "ColumnA") {
this.hide();
}
}
Demo
Thanks to kendo, you can't prevent their own events, so using hide() works but the tooltips still opens blinking before it is hidden again, it's possible to catch it opening. Tried using e.preventDefault() and return false that would a reasonable way to say "cancel the widget showing" but with no luck. This was the best I could do.
I d like to be able to hide/display the filters while using tablesorter.
Using table sorter just went fine but when i added a button to execute :
function display_hide_filter() {
var filters = document.getElementsByClassName('tablesorter-filter-row');
for (var i = 0; i < filters.length; i++) {
var filter = filters[i];
if (filter.style.display == 'none') {
filter.style.display='inline';
} else {
filter.style.display='none';
}
}
}
I then get a weird answer. Hiding the filter is fine but re displaying turn into having all filter cells under the first header cell.
Since i got poor english and css/js skills, I just hope I didnt miss something about it in the documentation but i tried to get trough it a thousant times with no success.
Thanks for any help
There is a filter_hideFilters option that minimizes the filter row until the user hovers over it. It is also accessible friendly in that the user can use the tab key gain access the filter inputs (demo).
If you just want to hide/show the filter row, then this basic code would work (demo):
HTML
<button type="button">Toggle Filter Row</button>
Script
$(function () {
$('table').tablesorter({
theme: 'blue',
widthFixed: true,
widgets: ['zebra', 'filter']
});
$('button').click(function(){
$('.tablesorter-filter-row').toggle();
});
});
As Andreas pointed out, I used 'inline' where i should have used ''
I have an editable Kendo Grid that may have a column with a checkbox to change a boolean value. I have used this solution proposed by OnaBai that is working perfectly!
The only problem is that the checkbox value change is too slow. When user clicks it, it takes about 1 second to change. I realize that the dataItem.set() method is responsible by this delay.
My grid has a considerable amount of data. About 30-40 columns and 300+ lines. It is defined as follows:
$("#mainGrid").kendoGrid({
dataSource: dataSource,
pageable: false,
sortable: true,
scrollable: true,
editable: true,
autoBind: false,
columnMenu: true, // Cria o menu de exibição de colunas
height: getGridHeight(),
toolbar: [/* hide for brevity */],
columns: [/* hide for brevity */],
dataBound: function() { /* hide for brevity. */},
edit: function() { /* hide for brevity. */}
});
Another detail is that, when dataItem.set() is called, it calls dataBound() event but that is not causing the delay. Grid's edit() method is not being called on this process. I don't know if worths to post dataSource code.
I would suggest using the approach from this code library article when it comes to use checkboxes. It does not use the set methods of the model and still works the same way. Even with 2000 records on a single page CheckAll will work flawlessly.
I have found an alternative way for doing what OnaBai proposed and it's working better.
// This is the grid
var grid = $("#mainGrid").data("kendoGrid");
// .flag is a class that is used on the checkboxes
grid.tbody.on("change", ".flag", function (e)
{
// Get the record uid
var uid = grid.dataItem($(e.target).closest("tr")).uid;
// Find the current cell
var td = $(e.target).parent().parent();
// This opens the cell to edit(edit mode)
grid.editCell(td);
// This ones changes the value of the Kendo's checkbox, that is quickly shown,
// changed and then hidden again. This marks the cell as 'dirty' too.
$(td.find("input")[0]).prop("checked", $(e.target).is(":checked") ? "checked" : null).trigger("change").trigger("blur");
}
Should try something like this:
I'll set the column with the Edit button to look like this:
columns.Command(command => {command.Edit().HtmlAttributes(new { id = "btnEdit_" + "${Id}" }); }).Width(100).Hidden(true);
And have it where clicking into the first column (I have an image with a hyperlink) uses an onclick function to programmatically click the Edit button, click the checkbox, then click the Update button. Probably more "old school", but I like knowing it is following the order I would be doing if I were updating it, myself.
I pass in the object ("this"), so I can get the row and checkbox when it appears, the new status as 0 or 1 (I have some code that uses it, not really necessary for this demo, though, so I'm leaving that part out of my function for simplicity), and the ID of that item:
columns.Bound(p => p.IsActive).Title("Active").Width(100).ClientTemplate("# if (IsActive == true ) {# <a href=javascript:void(0) id=btnActive_${Id} onclick=changeCheckbox(this, '0', ${Id}) class='k-button k-button-icontext k-grid-update'><img style='border:1px solid black' id=imgActive src=../../Images/active_1.png /></a> #} else {# <a href=javascript:void(0) id=btnActive_${Id} onclick=changeCheckbox(this, '1', ${Id}) class='k-button k-button-icontext k-grid-update'><img style='border:1px solid black' id=imgActive src=../../Images/active_0.png /></a> #}#");
function changeCheckbox(obj, status, id) {
var parentTr = obj.parentNode.parentNode;
$('[id="btnEdit_' + id + '"]').click();
parentTr.childNodes[5].childNodes[0].setAttribute("id", "btnUpdate_" + id); // my Update button is in the 6th column over
parentTr.childNodes[0].childNodes[0].setAttribute("id", "chkbox_" + id);
$('[id=chkbox_' + id + ']').click().trigger("change");
$('[id=chkbox_' + id + ']').blur();
var btnUpdate = $('[id="btnUpdate_' + id + '"]');
$('[id="btnUpdate_' + id + '"]').click();
}
Code above assumes, of course, the checkbox is in the first column. Otherwise, adjust the first childNodes[0] on that chkbox setAttribute line to the column it sits in, minus one because it starts counting from zero.
I did a solution much like #DontVoteMeDown. But I have a nested grid (master / detail) so I get the parent grid from the event parameter. Also I just trigger a click-event on the checkbox.
$("#grid .k-grid-content").on("change", "input.chkbx", function (e) {
// Get the parent grid of the checkbox. This can either be the master grid or the detail grid.
var parentGrid = $(e.target).closest('div[data-role="grid"]').data("kendoGrid");
// Get the clicked cell.
var td = $(e.target).closest("td");
// Enter the cell's edit mode.
parentGrid.editCell(td);
// Find the checkbox in the cell (which now is in "edit-mode").
var checkbox = td.children("input[type=checkbox]");
// Trigger a click (which will toggle check/uncheck).
checkbox.trigger("click");
});