How to sort capacities column in Datatables - javascript

i have a datatable with capacities column like this :
<table id="datatable" class="table">
<thead> <tr> <th>N</th> <th>capa</th> </tr> </thead>
<tbody>
<tr>
<td>1</td>
<td>2 Go</td>
</tr>
<tr>
<td>2</td>
<td>1 To</td>
</tr>
<tr>
<td>3</td>
<td>320 Go</td>
</tr>
<tr>
<td>4</td>
<td>2 To</td>
</tr>
<tr>
<td>5</td>
<td>500 Go</td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function() {
$('#datatable').dataTable({
'aaSorting': [],
'iDisplayLength': 50,
'aLengthMenu': [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'Tous']]
});
});
</script>
and I am trying to sort it to get this result :
2 Go
320 Go
500 Go
1 To
2 To
But can't figure out how to do it from reading the sorting plugins docs.
Thanks

Ok, finally got it
http://jsfiddle.net/jkwoaj3x/1/
$('#datatable').dataTable({
"columns": [
null,
{ "orderDataType": "custom-sort" }
]
});
and this is your custom sort func
$.fn.dataTable.ext.order['custom-sort'] = function ( settings, col )
{
return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
console.log($(td).text().replace(/[^0-9\.]+/g, ''));
return $(td).text().replace(/[0-9]/g, '');
} );
}
is it your solution?

If I understand correctly, you want to sort on the text part of the 'capa' column. You can achieve this by adding a column containing the text field, hiding it, and using iDataSort to sort on the hidden column when the 'capa' column header is clicked.
First, add the new text-only column to each row:
<tr>
<td>1</td>
<td>2 Go</td>
<td>Go</td>
</tr>
In the datatable initialisation code, use aoColumns to specify the column definitions:
...
'iDisplayLength': 50,
'aoColumns': [{},{ "iDataSort": 2 }, {'bVisible':false }],
...
Here's a working jsfiddle
Update: so it sounds like you want to sort on the text column THEN the int column, it would have been helpful if you had just stated that earlier.
'aoColumns': [{},{ "aDataSort": [2], "aTargets": [ 0, 2 ] }, {'bVisible': false, "aTargets": [ 0 ] }],
Here's an updated jsfiddle

you can have a table with all source data in gigas but render it differently without change nested data thanks to render in columnDefs option , it will use the built-in sort for numbers that works very well
http://legacy.datatables.net/usage/columns
I always do that when i want to display sentences and still have sortable column and it is very efficient
<table id="datatable" class="table">
<thead> <tr> <th>N</th> <th>capa</th> </tr> </thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
<td>1000 </td>
</tr>
<tr>
<td>3</td>
<td>320</td>
</tr>
<tr>
<td>4</td>
<td>2000</td>
</tr>
<tr>
<td>5</td>
<td>500</td>
</tr>
</tbody>
</table>
//targets is the number of the column you want render (here number 1)
//care full!!!! use DataTable and not datatable, second is old and doesn't have all options, if you don't want use fnRender
table = $('#datatable').DataTable({
"columnDefs":{
"targets": 1, "visible": true, "searchable": true
, "render": function (data, type, row) {
if (type == "display") {
if (data > 1000)
return ((data / 1000) + " To");
else
return (data + " Go");
}
return data;
},
};
});
It is best solution !

Thanks everyone.
I'm putting my answer which works well for me.
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
"file-size-pre": function (a) {
var x = a.substring(0, a.length - 2);
var x_unit = (a.substring(a.length - 2, a.length) == "Go" ? 1000 : (a.substring(a.length - 2, a.length) == "To" ? 1000000 : 1));
return parseInt(x * x_unit, 10);
},
"file-size-asc": function (a, b) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"file-size-desc": function (a, b) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
});
$(document).ready(function () {
$('#datatable').dataTable({
'columnDefs': [{ 'type': 'file-size', 'targets': 1 }],
'aaSorting': [],
'iDisplayLength': 50,
'aLengthMenu': [ [10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'Tous'] ]
});
});
Here is a fiddle : http://jsfiddle.net/cu9taqfg/1/

Related

How can have multirows Footer in Datatables?

I want make two rows at my footer datatables. First row of footer for sum columns and second row of footer for search columns.
This is my code in javascript
$(function () {
$('#ntable1 tfoot th').each( function () { //for search columns in footer
var title = $(this).text();
$(this).html( '<input type="text" placeholder="'+title+'"/>' );
} );
var table = $("#ntable1").DataTable({
"responsive": false, "scrollX": true, "lengthChange": true, "autoWidth": false,
"buttons": [
{
extend: 'copy',
exportOptions: {
columns: [':visible' ]
}
},
{
extend: 'excel',
exportOptions: {
columns: [':visible' ]
},
messageBottom: textTop,
},
{
extend: 'print',
footer: true,
exportOptions: {
columns: [':visible' ]
},
messageTop: textTop
},
{
extend: 'colvis',
exportOptions: {
columns: [':visible' ]
}
}
],
footerCallback: function (row, data, start, end, display) { //for sum of columns in footer
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(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
$('tr:eq(0) td:eq(3)', api.table().footer()).html(format('$' + pageTotal + ' ( $' + total + ' total)')); //not work
// $(api.column(3).footer()).html('$' + pageTotal + ' ( $' + total + ' total)'); //not work
},
initComplete: function () {
// Apply the search
this.api().columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change clear', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
} );
}
}).buttons().container().appendTo('#ntable1_wrapper .col-md-6:eq(0)');
});
Datatables code in html
<table id="ntable1" class="table table-bordered table-striped">
<thead> ... </thead>
<tbody> ... </tbody>
<tfoot>
<tr> <!-- for sum columns -->
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr> <!-- for search columns -->
<th>No</th>
<th>Nama Program</th>
<th>Tahun</th>
<th>Jumlah Kota</th>
<th>Nama Kota</th>
<th>Jumlah Sekolah</th>
<th>Jumlah Siswa</th>
<th>Pre Test</th>
<th>Post Test</th>
<th>%</th>
<th>Tingkat Kepuasan</th>
<th>Tabungan Pelajar (Account)</th>
</tr>
</tfoot>
</table>
If I add row in footer, my search column doesn't work. My problem only how to have multiple rows in footer datatables, which first row for calculate sum and second row for search column. Hope anyone can help.

Individual column searching (text inputs) not working in my rails code

Individual column searching (text inputs) is not working in my rails code.
My mappings.js file :
$(document).ready(function(){
$("table[role='example_datatable']").each(function(){
var dataTableInstance = $('#mappings').DataTable({
"order": [[ 4, "desc" ]],
columnDefs: [
{ "searchable": false, "targets": 6},
{ "orderable": false, "targets": 6}
],
"bFilter": false,
dom: 'Bfrtip',
pageLength: 10,
processing: true,
serverSide: true,
ajax: $(this).data('url')
});
$('#mappings tfoot th').each(function(){
var title = $('#mappings thead th').eq($(this).index()).text();
$(this).html( '<input type="text" placeholder="Search '+title+'" name="'+title+'" />' );
});
dataTableInstance.columns().every(function () {
alert("hi");
var datatableColumn = this;
$(this.footer()).find('input').on('keyup', function () {
alert("hi2");
datatableColumn.search(this.value).draw();
});
});
});
})
My mappings.html.erb file:
<%= content_tag :table,
role: :example_datatable,
id: 'mappings',
class: 'table reconciletable table-striped table-bordered table-hover',
data: { url: mappings_path(format: :json)} do %>
<tfoot>
<tr>
<th>Id</th>
<th>Entity</th>
<th>Item</th>
<th>Group</th>
<th>Record Created On</th>
<th>Record Created By</th>
</tr>
</tfoot>
<thead>
<tr>
<th>Id</th>
<th>Entity</th>
<th>Item</th>
<th>Group</th>
<th>Record Created On</th>
<th>Record Created By</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
<% end %>
I'm able to get the input texts for each column but once I try searching & nothing happens and it's not able to filter my datatable according to column search.
This is my code. please help me out :'(
Try this
//Apply the search
table.columns().eq( 0 ).each( function ( colIdx ) {
$( 'input', table.column( colIdx ).footer() ).on( 'keyup change', function () {
table
.column( colIdx )
.search( this.value )
.draw();
} );
} );
working Demo

unable to display sum in footer using datatable

I have created a datatable using jQuery. The table has seven columns , among one column is for Grand Total (column 6). I have to display the sum of Grand Total (column 6) in the Grand Total (column 6) at the bottom of Grand Total (column 6).
How can I do that? I have tried some code but nothing worked.
Outout is blank column.
here is the code that I found.
below is the html code
HTML
<table class="display table table-bordered table-striped" id="dynamic-table">
<thead>
<tr>
<th>Invoice Type</th>
<th>Invoice No</th>
<th>Invoice Date</th>
<th>Customer Name</th>
<th>City </th>
<th>Grand Total</th>
<th class="hidden-phone">Action</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th>Total:</th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
JavaScript
function load_datatable() {
var data = $('input[name=report]:Checked').val();
var date = $('#rep_date').val();
var type = $('#type_id').val();
datatable = $("#dynamic-table").dataTable({
"bAutoWidth": false,
"bFilter": true,
"bSort": true,
"bProcessing": true,
"bDestroy": true,
"bServerSide": true,
"oLanguage": {
"sLengthMenu": "_MENU_",
"sProcessing": "<img src='" + root_domain + "img/loading.gif'/> Loading ...",
"sEmptyTable": "NO DATA ADDED YET !",
},
"aLengthMenu": [
[10, 20, 30, 50],
[10, 20, 30, 50]
],
"iDisplayLength": 10,
"sAjaxSource": root_domain + 'app/invoice/',
"fnServerParams": function(aoData) {
aoData.push({
"name": "mode",
"value": "fetch"
}, {
"name": "report",
"value": data
}, {
"name": "type_id",
"value": type
}, {
"name": "date",
"value": date
});
},
"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 this page
pageTotal = api
.column(5, {
page: 'current'
})
.data()
.reduce(function(a, b) {
return intVal(a) + intVal(b);
}, 0);
console.log(pageTotal);
// Update footer
$(api.column(5).footer()).html('$' + pageTotal);
},
"fnDrawCallback": function(oSettings) {
$('.ttip, [data-toggle="tooltip"]').tooltip();
}
}).fnSetFilteringDelay();
//Search input style
$('.dataTables_filter input').addClass('form-control').attr('placeholder', 'Search');
$('.dataTables_length select').addClass('form-control');
}
do this example :
const Table = $('#foo').DataTable({
. . . . . .,
. . . . . .,
drawCallback: function(){
Table.columns(5, {
page: 'current'
}).every(function() {
var sum = this
.data()
.reduce(function(a, b) {
var x = parseFloat(a) || 0;
var y = parseFloat(b) || 0;
return x + y;
}, 0);
console.log(sum);
$(this.footer()).html(sum);
});
}
});
in this case the column was column number 5

Display data in a table by grouping them horizontally

I have some data that has the following format:
[name:'Name1', speed:'Val1', color:'Val2']
[name:'Name2', speed:'Val4', color:'Val5']
[name:'Name3', speed:'Val6', color:'Val7']
That I want to display in a table like this:
|Name1|Name2|Name3|
______|_____|______
speed |Val1 |Val4 |Val6
color |Val2 |Val5 |Val7
What I tried to do is group my data like this in the controller:
$scope.data = {
speeds: [{
...
},{
...
},{
...
}],
colors: [{
...
},{
...
},{
...
}],
};
But I am not sure what to put inside the empty areas, because all values there represent the values of the 'val1' variable for all Names (Accounts), and my tests until now keep failing.
You can imagine this as some sort of a comparisons matrix, that is used in order to see the all the values of the same variable across different accounts.
How can I represent the data in my model in order for me to successfully display them in a table as explained?
Edit
My difficulty lies in the fact that you create a table by going from row to row, so my html looks something like this:
<table md-data-table class="md-primary" md-progress="deferred">
<thead>
<tr>
<th ng-repeat="header in headers">
{{header.value}}
</th>
</tr>
</thead>
<tbody>
<tr md-auto-select ng-repeat="field in data">
<td ng-repeat="var in field">{{var.value}}</td>
</tr>
</tbody>
</table>
So as you can see I have a loop for each row, and a loop for each value of each row. This would be easier if I wanted to display the data horizontally, but I want the data vertically. So if we where talking about cars, we would have the car models as headers, and their respective characteristics(speed, color, etc) in each row.
If this is your basic structure:
var cols = [{name:'Name1', val1:'Val1', val2:'Val2'},
{name:'Name2', val1:'Val4', val2:'Val5'},
{name:'Name3', val1:'Val6', val2:'Val7'}];
This code
$scope.table = cols.reduce(function(rows, col) {
rows.headers.push({ value: col.name });
rows.data[0].push({ value: col.speed });
rows.data[1].push({ value: col.color });
return rows;
}, {headers:[], data:[[], []]});
will give you this structure for $scope.table:
$scope.table = {
headers : [{
value : "Name1"
}, {
value : "Name2"
}, {
value : "Name3"
}
],
data : [
[{
value : 'val1'
}, {
value : 'val4'
}, {
value : 'val6'
}
],
[{
value : 'val2'
}, {
value : 'val5'
}, {
value : 'val17'
}
]
]
};
<table md-data-table class="md-primary" md-progress="deferred">
<thead>
<tr>
<th ng-repeat="header in table.headers">
{{header.value}}
</th>
</tr>
</thead>
<tbody>
<tr md-auto-select ng-repeat="field in table.data">
<td ng-repeat="var in field">{{var.value}}</td>
</tr>
</tbody>
</table>
You could try this:
HTML
<table ng-app="myTable" ng-controller="myTableCtrl">
<thead>
<tr>
<th ng-repeat="car in cars">{{car.name}}</th>
</tr>
</thead>
<tbody>
<tr>
<td ng-repeat="car in cars">{{car.speed}}</td>
</tr>
<tr>
<td ng-repeat="car in cars">{{car.color}}</td>
</tr>
</tbody>
</table>
JS
angular.module("myTable",[])
.controller("myTableCtrl", function($scope) {
$scope.cars = [
{
name:'Name1',
speed:'Val1',
color:'Val2'
},
{
name:'Name2',
speed:'Val4',
color:'Val5'
},
{
name:'Name3',
speed:'Val6',
color:'Val7'
}
]
});
https://jsfiddle.net/ABr/ms91jezr/

jquery datatable disable sort in specific row

How to disable sorting in specific row/column in jquery datatable using a class?
here's my sample table;
<table>
<thead>
<tr>
<th class="sorting_disabled">Title1</th>
<th class="">Title2</th>
<th class="sorting_disabled">Title3</th>
</tr>
</thead>
<tbody>
<tr><td>Tag 1</td><td>Date 1</td><td>Date 2</td></tr>
<tr><td>Tag 2</td><td>Date 2</td><td>Date 2</td></tr>
<tr><td>Tag 3</td><td>Date 3</td><td>Date 3</td></tr>
<tr><td>Tag 4</td><td>Date 4</td><td>Date 4</td></tr>
<tr><td>Tag 5</td><td>Date 5</td><td>Date 5</td></tr>
....
</tbody>
</table>
script;
$('.sortable thead tr th.sorting_disabled').livequery(function() {
$(this).removeClass('sorting');
$(this).unbind('click');
});
above code works but if I click to the next column who has a sorting its shows again an arrow. though its not clickable ;(
How can I disable the sorting by using a class and not using/redraw a table.
You can disable the sorting using a class in definition.
Just add this code to the datatable initialization:
// Disable sorting on the sorting_disabled class
"aoColumnDefs" : [ {
"bSortable" : false,
"aTargets" : [ "sorting_disabled" ]
} ]
$('#example').dataTable( {
"aoColumnDefs": [
{ 'bSortable': false, 'aTargets': [ 1 ] }
]});
That should do it..;)
The only solution:
First add class="sorting_disabled" to any<th> that you want to disable sorting, then add this code to the datatable initialization:
// Disable sorting on the sorting_disabled class
"aoColumnDefs" : [ {
"bSortable" : false,
"aTargets" : [ "sorting_disabled" ]
} ],
"order": [
[1, 'asc']
],
As said in the Datatables documentation:
As of DataTables 1.10.5 it is now possible to define initialisation options using HTML5 data-* attributes. The attribute names are read by DataTables and used, potentially in combination with, the standard Javascript initialisation options (with the data-* attributes taking priority).
Example:
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th data-orderable="false">Start date</th>
<th>Salary</th>
</tr>
</thead>
I strongly recommend using this approach, as it is more cleaner than others. DataTables 1.10.15 was originally released on 18th April, 2017.
try the following answer .it works for me.
<table class="tablesorter" id="tmp">
<thead>
<tr>
<th>Area</th>
<th>Total Visitors</th>
</tr>
</thead>
<tbody>
<tr>
<td>Javascript</td>
<td>15</td>
</tr>
<tr>
<td>PHP</td>
<td>3</td>
</tr>
<tr>
<td>HTML5</td>
<td>32</td>
</tr>
<tr>
<td>CSS</td>
<td>14</td>
</tr>
<tr>
<td>XML</td>
<td>54</td>
</tr>
</tbody>
<tfoot>
<tr class="no-sort">
<td><strong>Total</strong></td>
<td><strong>118</strong></td>
</tr>
</tfoot>
source : http://blog.adrianlawley.com/tablesorter-jquery-how-to-exclude-rows
<th class="sorting_disabled"> </th>
$(document).ready(function () {
$('#yourDataTableDivID').dataTable({
"aoColumnDefs": [
{
"bSortable": false,
"aTargets": ["sorting_disabled"]
}
]
});
});
I hope below code works in your case.
$("#dataTable").dataTable({
"aoColumns": [{"bSortable": false}, null,{"bSortable": false}]
});
You need to disable sorting via "bSortable" for that specific column.
$(document).ready(function() {
$('#example').dataTable( {
"aoColumns": [
{ "bSortable": false },
null,
{ "bSortable": false }
]
});
});
I came with almost the same solution like in the question, but I used the "fnHeaderCallback". As far as I understood, it gets called after each header redisplay, so no more worries about 'sorting' class that appears again after clicking on column next to target column.
$('.datatable').dataTable({
"fnHeaderCallback": function() {
return $('th.sorting.sorting_disabled').removeClass("sorting").unbind("click");
}
});
Additional documentation about callbacks: http://datatables.net/usage/callbacks
this code worked for me in react.
in row created i added fixed-row class to the row i wanted to stay fixed and not sortable and i drawcallback i hid the row then i appended it to the table itself.
Hope this works for you:
$(this.refs.main).DataTable({
dom: '<"data-table-wrapper"t>',
data: data,
language: {
"emptyTable": "Loading ...",
},
columns,
ordering: true,
order: [0,'asc'],
destory:true,
bFilter: true,
fixedHeader: {
header: true
},
iDisplayLength: 100,
scrollY: '79vh',
ScrollX: '100%',
scrollCollapse: true,
"drawCallback": function( settings ) {
var dataTableId = $("#To_Scroll_List").find(".dataTables_scrollBody table").attr("id");
$("..fixed-row").css('display','none');
$("#"+dataTableId+"_wrapper table").find('tbody tr:last').after($('.fixed-row'));
$(".fixed-row").show();
},
createdRow: function (row, data, index) {
if(data.UnitsPerLine == 999){
$(row).addClass('fixed-row');
}
},
initComplete: function (settings, json) {
$("#To_Scroll_List").find(".dataTables_scrollBodytable").attr("id");
$("#"+dataTableId+" thead tr").remove();
});
DatatableSearch(dataTableId+"_wrapper table", "AverageUnitsPerLineReport");
}
});
}
Without using class, you can follow these steps:
Remove the row which has to remain unsorted from the body of the table.
Include the row to be added in the footer of the table if it is the last row.
I did it including the code below in drawCallback:
drawCallback: function(settings) {
let td = $("td:contains('TOTAL')");
if (td.length) {
let row = td.closest('tr');
let clonedRow = row.clone();
row.remove();
$('table tbody').append(clonedRow);
}
}

Categories