I need to sort by a specific column on page load, in this case, have it show initial results with a descending sort on "RecordDate".
The problem is, I believe the server side is blocking any sort specification, and any modification I made below will not load results (asSorting [[number of column, and tried name, desc]] etc).
Is there a special function I can write to force this column sort? Curious if this can be handled here before modifying a stored procedure or another cs file.
function GetRecords( DTO ) {
var grpid = ApplyGroupingOnTable();
console.log( grpid );
oTable = $( "#SearchTable" ).dataTable( {
"oLanguage": {
"sZeroRecords": "No records to display"//,
//"sSearch": "Search on UserName"
},
"aLengthMenu": [[10, 25, 50, 100, 150, 250, 500], [10, 25, 50, 100, 150, 250, 500]],
"iDisplayLength": 10,
"sScrollX": "1300px",
"bSortClasses": false,
"bStateSave": false,
"bFilter": false,
"bLengthChange": true,
"bPaginate": true,
"bAutoWidth": false,
"bProcessing": false,
"bServerSide": true,
"bDestroy": true,
"sAjaxSource": "/Data/SearchRecords",
"aoColumns": [
{ "mData": "SelectID", "sClass": "alternatingCenterAlign", fnRender: CreateSelectCaseViewerButton, "bSortable": false, "bSearchable": false, "sWidth": "18px" },
{ "mData": "ViewID", "sClass": "alternatingCenterAlign", fnRender: CreateCaseViewerButton, "bSortable": false, "bSearchable": false, "sWidth": "18px" },
{ "mData": "TagID", "sClass": "alternatingCenterAlign", fnRender: CreateTagCaseButton, "bSortable": false, "bSearchable": false, "sWidth": "18px" },
{ "mData": "ID", "sClass": "alternating", "sType": "string", "bSortable": true, "bSearchable": false, "sWidth": "50px" },
{ "mData": "ClientName", "sClass": "alternating", "sType": "string", "bSortable": true, "sWidth": "120px" },
{ "mData": "RecordDate", "sClass": "alternating", "sType": "string", "bSortable": true, "bSearchable": false, "sWidth": "70px" },
"bJQueryUI": false,
"sPaginationType": "full_numbers",
"bDeferRender": true,
"bRetrieve": false,
"fnServerParams": function ( aoData ) {
aoData.push( { "name": "iParticipant", "value": $( "#participant" ).val() } );
aoData.push( { "name": "iSearch", "value": JSON.stringify( DTO ) } );
aoData.push( { "name": "iId", "value": cliid } );
aoData.push( { "name": "iOrder", "value": grpid } );
},
"fnDrawCallback": function ( oSettings ) {
if ( grpid ) FinalGrouping( oSettings, grpid );
$( ".overflow" ).each( function () { $( this ).attr( 'title', $( this ).text() ); } );
$( '#tablediv select' ).chosen();
},
"fnServerData": function ( sSource, aoData, fnCallback ) {
$( '.grid-loading' ).show();
$.ajax( {
dataType: 'json',
contentType: "application/json; charset=utf-8",
type: "GET",
url: sSource,
data: aoData,
cache: false,
success: function ( msg ) {
if ( msg.Exception != undefined ) {
alert( msg.Exception );
$( '.grid-loading' ).hide();
return false;
}
lastId = ( msg.aaData.length > 0 ) ? msg.aaData[msg.aaData.length - 1][0] : 0;
fnCallback( msg );
$( '.grid-loading' ).hide();
}
} ); //End Ajax Call
}
} );
}
Assuming you have access to the dataTable's data array and it is of the form:
var array = [
{ name: "somename", value: "somevalue" },
{ name: "somename2", value: "somevalue2" }
];
You can do a simple descending sort based on the value with the following:
array.sort(SimpleCompareDescOnValue);
Given the function:
function SimpleCompareDescOnValue(a, b) {
// Use caution so as not to define 'undefined'. It's not a great practice but it works.
var c = a.length != undefined ? Math.max.apply(Math, a.map(function (o) { return o.value; })) : a.value;
var d = b.length != undefined ? Math.max.apply(Math, b.map(function (o) { return o.value; })) : b.value;
if (c > d)
return -1;
if (c < d)
return 1;
return 0;
}
Not sure if this helps you at all. I've never used the dataTable library (although it looks cool) but I have to assume you can access the data after pulling it from the server and it only makes sense that it would be stored in arrays at some level.
Related
We have a datatable that looks like this. As you can see, when you click the column visibility button only a line is appearing:
var dataTableDefaults ={
columnDefs: [
{
"targets": -1,
"orderable": false,
"searchable": false
},
{
"targets": "noSearchOrSort",
"orderable": false,
"searchable": false
},
{
"targets": "noSort",
"orderable": false,
},
{
"targets": "noSearch",
"searchable": false
},
{
"targets": "invisible",
"visible": false
}
],
buttons: [
{
extend : 'colvis',
columns : ":visible"
}
],
order: [[0, 'asc']],
lengthMenu: [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
language: {
loadingRecords: 'Loading...',
emptyTable: 'No Data available'
},
pagingType: 'full_numbers',
processing: true
};
var cols = [
null,
null,
null,
{ "bVisible" : false }
];
jointDefaults = $.extend(true,{},dataTableDefaults);
jointDefaults.columns = cols
$('#table').DataTable(
$.extend(
jointDefaults,
{
bServerSide: true,
bProcessing: true,
sAjaxSource: 'ajax.php',
fnServerData: function(sSource, aoData, fnCallback) {
aoData.push(
{
name: 'gt',
value: 1
},
{
name: 'mode',
value: pageMode
},
);
$.ajax({
dataType: 'json',
type: 'GET',
url: sSource,
data: aoData,
success: function (response) {
fnCallback(response);
}
});
}
}
)
);
Why are the show/hide buttons on the column visibility not appearing?
i am getting error your cannot read property of undefined i have below is code which describe table structure there is also edit() function i am trying to store id in my id variable using var id=data[0] but my i am getting error on this line
function edit() {
var current_row = $(this).parents('tr');
if (current_row.hasClass('child')) {
current_row = current_row.prev();
}
var data = table.row(current_row).data();
console.log('Row data:' + data);
var id = data[0];
$("#ID").val(id); // here i am getting error
}
//datatable structure
function createCustomisedDatatable(arr) {
table = $('#example').DataTable({
"data": arr,
"iDisplayLength": 10,
"pagingType": "simple_numbers",
"bDestroy": true,
responsive: true,
columnDefs: [
{
responsivePriority: 1,
targets: 1
},
{
"aTargets": [0],
"sTitle": "Id",
"class": "Id",
"bSortable": true
}, {
"aTargets": [1],
"sTitle": "name",
"class": "name",
"bSortable": true
}, {
"aTargets": [2],
"sTitle": "gender",
"class": "gender",
"bSortable": true
}, {
"aTargets": [3],
"sTitle": "pincode",
"class": "pincode",
"bSortable": true
}, {
"aTargets": [4],
"sTitle": "City",
"class": "City",
"bSortable": true
}, {
"aTargets": [5],
"sTitle": "Action",
"bSortable": true,
"render": function(data, type, row) {
var returnHTML = CreateDataHTML(data);
return returnHTML;
}
}
],
order: [1, 'asc']
});
}
I think this is your problem:
// returns an array for each row. Since t here is only one row,
// there will be only one item in the array.
var data = table.rows(current_row).data();
console.log('Row data:' + data);
var rowData= data[0];
// now you need the column that it belongs to
$("#ID").val(rowData[0]); // assuming that id is in the first column
I'm try to achieve that, but so far not working. Tried those suggestion either in stackoverflow or datatables forum so far no luck yet. I tried the fnSetFilteringEnterPress of jQuery DataTables: Delay search until 3 characters been typed OR a button clicked but so far can't make it work, any suggestion. Any advise would be appreciate. Thanks
var oTable;
var ws_GetData = 'Default.aspx/GetList';
$(document).ready(function () {
oTable = $('#tbl1').dataTable({
"bJQueryUI": true,
"bPaginate": true,
"sPaginationType": "full_numbers",
"iDisplayLength": 25,
"bProcessing": true,
"bFilter": true,
"bServerSide": true,
"aoColumns": [{ "sWidth": "5%", "bSortable": false },
{ "sWidth": "3%", "bSortable": false },
{ "sWidth": "5%", "bSortable": false },
{ "bSortable": false }, { "bSortable": false },
{ "bSortable": false }, { "bSortable": false },
{ "sWidth": "5%", "bSortable": false },
{ "sWidth": "2%", "bSortable": false}],
"sAjaxSource": ws_GetData,
"fnServerData": function (sSource, aoData, fnCallback, oSettings) {
var page = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
aoData.push({ "name": "pageNo_1", "value": page });
ResultData(sSource, aoData, fnCallback);
}
}).columnFilter({ //sPlaceHolder: "head:before",
aoColumns: [{ "sWidth": "5%", type: "text" },
{ "sWidth": "3%", type: "select", values: ['00', '02'] },
{ "sWidth": "5%", type: "text" },
{ type: "date-range" },
{ type: "text" },
{ type: "text" },
{ type: "number-range" },
{ "sWidth": "5%", type: "text"}]
});
});
function ResultData(sSource, aoData, fnCallback) {
$.ajax({
type: "GET",
url: sSource,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: aoData,
async: true,
beforeSend: function () {
// SHOW the overlay:
$('#overlay').show();
},
complete: function () {
// HIDE the overlay:
$('#overlay').hide();
},
success: function (result) {
var myObject = JSON.parse(result.d);
fnCallback(myObject);
},
error: function (errMsg) {
alert(errMsg);
}
});
}
Maybe this plugin might be of some help or give you an idea on how to continue:
Filter on Return
Add it to your script like this:
$(function() {
$.fn.dataTableExt.oApi.fnFilterOnReturn = function(oSettings) {
var _that = this;
this.each(function(i) {
$.fn.dataTableExt.iApiIndex = i;
var $this = this;
var anControl = $('input', _that.fnSettings().aanFeatures.f);
anControl.unbind('keyup').bind('keypress', function(e) {
//here's the part that you might need to modify:
if (e.which == 13) {
$.fn.dataTableExt.iApiIndex = i;
_that.fnFilter(anControl.val());
}
});
return this;
});
return this;
};
$('#datatable').DataTable({
"oLanguage": {
"sSearch": "Filter Data"
},
"iDisplayLength": -1,
"sPaginationType": "full_numbers"
}).fnFilterOnReturn();
});
Working example in this Plunker
In My datatable custom directive, I have three action icons in a cell.
$(document).ready(function () {
var oTable = $("#elem").dataTable({
'bJQueryUI': false,
'sScrollY': '300px',
'bScrollInfinite': true,
'bSearchable': true,
'bScrollCollapse': true,
'sDom': 'tSi',
"bDeferRender": true,
'bPaginate': true,
'aaSorting': [
[1, 'asc']
],
'aaData': scope.datasource,
"fnRowCallback": processRow,
"aoColumnDefs": [{
"bSortable": true,
"bSearchable": true,
"sWidth": "20%",
"sTitle": "Name",
"sName": "name",
"aTargets": [0],
"mData": "name",
"mRender": function (data, type, full) {
return '' + data + ' ';
}
}, {
"bSortable": true,
"bSearchable": true,
"sWidth": "18%",
"sTitle": "Types",
"sName": "types",
"aTargets": [1],
"mData": "types"
}, {
"bSortable": true,
"bSearchable": true,
"sWidth": "10%",
"sTitle": "File Type",
"sName": "fileType",
"aTargets": [2],
"mData": "fileType"
}, {
"bSortable": true,
"bSearchable": true,
"sWidth": "18%",
"sTitle": "Modified Time",
"sName": "modifiedTime",
"aTargets": [3],
"mData": "modifiedTime"
}, {
"bSortable": false,
"bSearchable": true,
"sWidth": "25%",
"sTitle": "Action Buttons",
"aTargets": [4],
"mData": "",
"mRender": function () {
return '<div class = "center">
<span>
<i class = "glyphicon-info-sign glyphicon"
id="info" style="color:#32a5e8"
onmouseover="this.style.color=\'crimson\'"
onmouseout="this.style.color=\'#32a5e8\'">
</i>
</span>
<i class = "glyphicon-edit glyphicon" style="color:#32a5e8"
onmouseover="this.style.color=\'crimson\'"
onmouseout="this.style.color=\'#32a5e8\'" ng-click="">
</i>
<span>
<i class = "glyphicon-remove glyphicon" style="color:#32a5e8"
onmouseover="this.style.color=\'crimson\'"
onmouseout="this.style.color=\'#32a5e8\'" ng-click="">
</i>
</span>
</div>';
}
}]
});
$("#elem tbody tr td:eq(4)").on('click', function () {
var data = oTable.fnGetData(this);
console.log("clicked inside table -- data: ", oTable.fnGetData());
var position = oTable.fnGetPosition(this);
console.log("clicked position inside table -- position: ", position);
});
});
After clicking on "info" icon, I need to show a message in popover.
Now,I have tried with fnGetPosition() method which returns the same position for all the icons inside the cell. If I can differentiate their position values, it will be easy for me to show the dialog on "info" icon click.
How can I work with it now? Or is there another way to do this?
$(document).ready(function() {
var oTable = $("#elem").dataTable({
'bJQueryUI':false,
'sScrollY': '300px',
'bScrollInfinite':true,
..........
..........
});
$("#elem tbody").delegate("tr i", "click", function (e) {
e.preventDefault();
var self = $(this);
var pos = self.closest('tr').index();// <-- this will give you row index.
if (self.hasClass('glyphicon-edit')) {
// Do something
}else if (self.hasClass('glyphicon-info-sign')){
// Do something
}else if(self.hasClass('glyphicon-remove'){
// Do something
}
});
In my table I have very 4 columns: Name, Age, Percentage, Checkbox column
http://live.datatables.net/umezez/51/edit
What I'm trying to do is to set value of percent column based on checkbox in last column.
Idea is to sum age column in footer based on that checkbox (this part I have done) and calculate percent value base on that footer.
When I try to debug and I put my updated data to console I see that percent value is correctly updated, but table isn't updated.
My idea is to update row in fnRowCallback but I think table should be updated when I modify data in fnPreDrawCallback
I'm using DataTables 1.9.4.
Here is my code:
$(document).ready(function () {
$(document).on('click', "input.updateFooter", function () {
var rowIndex = oTable1.fnGetPosition($(this).closest('tr')[0]);
var ok = this.checked ? 1 : 0;
oTable1.fnSettings().aoData[rowIndex]._aData.use = ok;
oTable1.fnDraw();
});
var iTotal = 0,
rowsInUse = 0;
var oTable1 = $('#example1').dataTable({
"table-layout": "fixed",
"oLanguage": {
"sZeroRecords": "No data"
},
"fnPreDrawCallback": function (oSettings) {
iTotal = 0;
rowsInUse = 0;
for (var i = 0; i < oSettings.aoData.length; i++) {
if (oSettings.aoData[i]._aData.use == 1) {
iTotal += oSettings.aoData[i]._aData.age;
rowsInUse++;
}
}
for (var j = 0; j < oSettings.aoData.length; j++) {
if (oSettings.aoData[j]._aData.use == 1) {
oSettings.aoData[j]._aData.percent = (parseInt(oSettings.aoData[j]._aData.age) / iTotal * 100).toFixed(2) + "%";
} else {
oSettings.aoData[j]._aData.percent = "";
}
}
//console.log(oSettings.aoData);
},
"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
console.log(aData);
},
"fnDrawCallback": function (oSettings) {
//oSettings.aoData[0]._aData.percent = "24%";
},
"fnFooterCallback": function (nRow, aaData, iStart, iEnd, aiDisplay) {
if (rowsInUse > 0) {
$('#sum .c0').html(iTotal);
$('#avg .c0').html(rowsInUse > 0 ? (iTotal / rowsInUse).toFixed(2) : 0);
}
},
"bPaginate": false,
"bLengthChange": false,
"bFilter": false,
"bSort": true,
"bInfo": false,
"bAutoWidth": false,
"aaSorting": [
[0, "asc"]
],
"aaData": [{
name: "Tomek",
age: 20,
percent: "20%",
use: 1
}, {
name: "John",
age: 30,
percent: "80%",
use: 1
}],
"aoColumns": [{
"sTitle": "Name",
"bVisible": true,
"sType": "string",
"sWidth": "100px",
"mData": "name"
}, {
"sTitle": "Age",
"bVisible": true,
"sType": "",
"sWidth": "50px",
"sClass": "center percent",
"mData": "age"
}, {
"sTitle": "%",
"bVisible": true,
"sType": "",
"sWidth": "50px",
"sClass": "center percent",
"mData": "percent"
}, {
"sTitle": "",
"bVisible": true,
"bSortable": false,
"sType": "string",
"sWidth": "20px",
"sClass": "center",
"mData": "use",
mRender: function (data) {
return '<input type="checkbox" class="updateFooter" name="d" ' + (data == 1 ? 'checked="checked"' : '') + ' />';
}
}]
});
});
your code is fine just put this to fnRawCallBack
"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$(nRow).children(':eq(2)').text(aData.percent);
return nRow;
},
dataTables recycle html on each draw, solution is to edit that html. Link to live example http://live.datatables.net/epulak/