Changing the way table is sorted jquery tablesorter - javascript

I'm using jquery tablesorter to sort my table. I've tried to google my question, didn't find what I was looking for.
I've got a table which content changes dynamically so I want to change the way items are sorted.
One case I've got table populated with text which can be sorter with default .tablesorter() and I've got another case where digits are in table so I need to invoke tablesorter like this :
$('table').tablesorter({
headers : {
0 : {sorter:'digit'},
1 : {sorter:'digit'},
2 : {sorter:'digit'},
3 : {sorter:'digit'}
}
});
I have a method that does reload to table switching between numbers/text in table content, how can I change the way table is sorted.
In the example (pseudocode):
function reloadTableData
if table contains numbers user this tablesorter (I have a way to know if table contains numbers)
$('table').tablesorter({
headers : {
0 : {sorter:'digit'},
1 : {sorter:'digit'},
2 : {sorter:'digit'},
3 : {sorter:'digit'}
}
});
if table contains text use ordinary table sorter
$('table').tablesorter();
end
I can reload table data n times with either text/numbers.
I've tried the following :
function initTablesorter(n) {
switch(n)
{
case "number":
digitTableSorter();
break;
case "text":
defaultTableSorter();
break;
default:
}
}
function digitTableSorter(){
$('table').tablesorter({
headers : {
0 : {sorter:'digit'},
1 : {sorter:'digit'},
2 : {sorter:'digit'},
3 : {sorter:'digit'}
}
});
}
function defaultTableSorter(){
$('table').tablesorter();
}
Needless to say it's not working, I hope someone did something like this before, I'm stuck for some time now.

So is it not working because you are reinitialising tablesorter on a table? You may try to unbind tablesorter before rebinding it.
$('table')
.unbind('appendCache applyWidgetId applyWidgets sorton update updateCell')
.removeClass('tablesorter')
.find('thead th')
.unbind('click mousedown')
.removeClass('header headerSortDown headerSortUp');
Have a look at Remove jQuery tablesorter from table.

I think you are looking for this - You will need MetatData plugin to get the th classes to like "{sorter: 'digit'}"
http://tablesorter.com/docs/example-trigger-sort.html
$("#trigger-link").click(function() {
// set sorting column and direction, this will sort on the first and third column the column index starts at zero
var sorting = [[0,0],[2,0]];
// sort on the first column
$("table").trigger("sorton",[sorting]);
// return false to stop default link action
return false;
});

Related

Cant hide items per page and pagination in datatable when less then number displayed

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);
}
} );

Tablesorter sort clicking link outside

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;
});
});

DataTable : How to hide the pagination and only show it as need?

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/

tablesorter does not work when i add more columns

I have a table where i sort on the second column. by default i have 8 columns
and the rows can vary, depending on how many things i add.
The sorting works when i have the standard 8 columns but when i mark a checkbox and save which indicates that more info will be generated dynamiclly in my table then the sorting does not work anymore.
code:
$.tablesorter.addParser({
id: 'input_text',
is: function (s) {
// return false so this parser is not auto detected
return false;
},
format: function (s) {
return s;
},
type: 'text'
});
// Tablesorter
if ($(".attendanceList tbody tr").length > 0) {
$(".attendanceList").tablesorter({ headers: { 1: { sorter: false },
2: { sorter: 'input_text' },
3: { sorter: false },
4: { sorter: false },
5: { sorter: false },
6: { sorter: false },
7: { sorter: false },
8: { sorter: false },
9: { sorter: false },
10: { sorter: false }
},
sortList: [[2, 0], [0, 0]]
});
}
I used firebug to see what the problem was and my "s" paramater(check above) is allways an empty string ("").
step by step:
i mark a checkbox and press a save button. when that is done i press on another button that triggers a popup and gets me my table, now the table has 10 columns but the second column will no longer perform the sort as it did before.
Have i missed something? I have read up on the tablesorter plugin and I have not found anyone with similar issues,
Thanks!
I see two issues with what you are describing; and hopefully you're using my fork of tablesorter.
1) To get the value of a checkbox, you'll need to search the cell for an input and check for updates. Note this parser will work with the original tablesorter, but it won't update (using the updateCell method) properly. Note this code is from the parser-input-select.js file, and can be seen working in this demo.
// Custom parser for including checkbox status if using the grouping widget
// updated dynamically using the "change" function below
$.tablesorter.addParser({
id: "checkbox",
is: function(){
return false;
},
format: function(s, table, cell) {
// using plain language here because this is what is shown in the group headers widget
// change it as desired
var $c = $(cell).find('input');
return $c.length ? $c.is(':checked') ? 'checked' : 'unchecked' : s;
},
type: "text"
});
// update select and all input types in the tablesorter cache when the change event fires.
// This method only works with jQuery 1.7+
// you can change it to use delegate (v1.4.3+) or live (v1.3+) as desired
// if this code interferes somehow, target the specific table $('#mytable'), instead of $('table')
$(window).load(function(){
// resort the column after the input/select was modified?
var resort = true,
// this flag prevents the updateCell event from being spammed
// it happens when you modify input text and hit enter
alreadyUpdating = false;
$('table').find('tbody').on('change', 'select, input', function(e){
if (!alreadyUpdating) {
var $tar = $(e.target),
$table = $tar.closest('table');
alreadyUpdating = true;
$table.trigger('updateCell', [ $tar.closest('td'), resort ]);
// updateServer(e, $table, $tar);
setTimeout(function(){ alreadyUpdating = false; }, 10);
}
});
});
2) The only thing that isn't clear from the question is if the table is being built dynamically within the popup, or if the table with the checkbox is being modified, then copied to a popup?
Note that the above method only updates the state of the checkbox within the table. It won't include any dynamically added columns to an already initialized table. In that case, you'll need to use the updateAll method, but it will need to be triggered after the table contents have been updated.
$table.trigger('updateAll', [ resort ]);
If you could share the code that is run between the time of "saving" your checkbox choices and initializing the popup, it would help make the issue more clear.
Update: to parse an input, you need to get the value of the input element. The s within the parser format function only contains the text found within the table cell. When there is only an input within the table cell, no text is returned because the input element doesn't contain text, it has a value. So instead of using the "checkbox" parser I shared above, use this "input" parser; but as stated before, this parser will work with the original version of tablesorter (v2.0.5) but will not work properly if the "updateCell" method is used.
$.tablesorter.addParser({
id: "inputs",
is: function(){
return false;
},
format: function(s, table, cell) {
return $(cell).find('input').val() || s;
},
type: "text"
});
This parser also requires the code within the $(window).load(...) shown above to allow updating the parsed input for sorting when the user changes it.
After inserting the dynamically-generated content, you just need to trigger an update. It looks like your table is identified with the "attendanceList" class, so the command after the dynamic update would be:
$(".attendanceList").trigger("update");

jQuery / datatables: update rank column after sort & page

The first column of a table has its rank in the current sort order. I update it after sorting (easy) but cannot figure out how to access the current page # and size of page to update it for the 2nd, 3rd, etc page. I have..
$("table.datatable")
.dataTable({
fnDrawCallback: function() {
$(this).find("td.counter span").each(function(i, row) {
$(this).html(i + 1);
// Should be something like
// $(this).html(dataTable.pageno + dataTable.pagesize + i)
});
}
});
What's the proper way of getting the page # and page size to do that so the first row on the second page is #11 (if it's 10 per page)?
UPDATE ended up doing this; not sure how "proper" it is, but..
fnDrawCallback: function(settings) {
$(this).find("td.counter span").each(function(i, row) {
$(this).html(i + 1 + settings._iDisplayStart);
});
}
You can use this example on the Datatables documentation, which adds an index column to your table:
http://datatables.net/release-datatables/examples/api/counter_column.html

Categories

Resources