DataTable fixed header not working for scrollable table - javascript

I've been working with dataTables for a short period of time and I have a DataTable with two columns:
TableVehUsage = $("#TableVehUsage ").DataTable({
data: [],
ordering: true,
paginate: false,
"info": false,
fixedHeader: {header: true},
columns: [
{ data: "Vehicle", title: "Vehicle" },
{ data: "Serial", title: "Serial" }
],
"columnDefs": [
{
"targets": 0,
"render": function (data, type, full, meta) {
// If it is rendering the cell contents
if (type === 'display') {
switch (data) {
case "-":
return "-";
default:
if (full.IsOnSale == true)
return '<span style="color:red" onclick="ToParentTab(' + full.Id + ')">' + data + '</span>';
else
return '<span onclick="ToParentTab(' + full.Id + ')">' + data + '</span>';
}
}
return (isNaN(data)) ? -1 : +data;
}
} }]
});
I have some situation when all the data don't fit in the page and the user needs to scroll down to see all the info. I've tried to use Fixed Header by adding to my javascript the line fixedHeader: {header: true} and in the html:
<script src="https://cdn.datatables.net/fixedheader/3.1.2/js/dataTables.fixedHeader.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/fixedheader/3.1.2/css/fixedHeader.dataTables.min.css">
But is not working for me :(
What am I doing wrong?

I found a DataTable plugin that may be of help. Information on it is located at https://datatables.net/extensions/scroller/
Using this, my definition looks like this:
var table1 = $('#example').DataTable({ paging: true,   
scrollY:        200,
deferRender:    true,
scroller:       true });
I made a jsFiddle at https://jsfiddle.net/bindrid/oywvh1ek/6/

Try adding your data in a different variable with only the 'value' part of the key-value pair in it. For example, in the case of
{"vehicle":"Audi"},
your 'data' variable should have only ["Audi"] in it.
The below code worked perfectly for me.
$("<your_table_name>").DataTable({
data:data,
fixedHeader:true,
"scrollX": true,
"scrollY": "200px",
"scrollCollapse": true,
columns: [
{ title: 'Vehicle' },
{ title: 'Serial' }
]
});

I had a problem where my fixedHeader was working until I got about halfway down the page, then it disappeared. Here is what I did to get it working:
At the top of my JS file:
$(document).ready(function () {
DrawDataTable();
//This enables the table header to stick to the top of the page when the user is scrolling
var employeeData = $('#employee-table').DataTable();
employeeData.fixedHeader.adjust();
});
Then in the same JS file, in my jQuery ajax call, I had to add the line of code that says "fixedHeader": true
Finally, in my HTML file, I had to include the following in my <head> section:
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.12.1/fh-3.2.4/r-2.3.0/datatables.min.css"/>
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.12.1/fh-3.2.4/r-2.3.0/datatables.min.js"></script>
Do not forget that you will also need to include whatever Bootstrap, JavaScript or jQuery scripts or style sheets in the head as well.

Related

Apps Script Reload Datatable after GS Function

So I have made a Crud web application that also builds a PDF document, all this is done by a GS function when a submit button is clicked, it also appends the data into a Google Sheet. I also have a Datatable that loads data from the same spreadsheet, but I cannot find a way to refresh or reload the table after the GS function is done
<script>
google.script.run.withSuccessHandler(showData).gettableData();
function showData(dataArray){
$(document).ready(function(){
$('#data-table').DataTable({
data: dataArray,
columns: [
{"title":"IDs"},
{"title":"Names",
render: function (data, type, row) {
return data + ' ' + row[2] + '';
},},
{"title":"Name2"},
{"title":"Address"},
{"title":"Date"},
{"title":"Version"},
{"title":"Total"},
{"title":"",
render: function (data, type, row, meta) {
if (type === "display") {
data = '<a class="btn btn-small" href="' + data + '" target="_blank">View</a>';
}
return data;
}},
{"title":"",
render: function(data, type, row, meta) {
return '<button data-target="modal1" class="btn btn-small modal-trigger" id="' + row[0] + '" onclick="editPastForms((this.id))">Edit</button>';}
}
],
columnDefs: [
{ "visible": false, "targets": [0,2] },
{
targets: [1, 2, 3, 5, 6, 7, 8],
orderable: false
},
{ className: "center-align", targets: [7,8] }
],
lengthMenu: [
[25],
[25],
],
order: [[4, 'desc']],
"bLengthChange": false,
});
});
}
</script>
I have tried adding a function to reloaded the page using a .withSuccessHandler() however I get an error saying the iFrame permissions won't allow this
&
I have tried simply rerunning the google.script.run.withSuccessHandler(showData).gettableData(); function, but I get an error saying that I cannot reinitialise the datatable
All examples I have found online only refer to Ajax (I have no idea what that is lol) and nothing really for Apps Script. If anyone has any solutions or links to something that can help me out I would be so appreciative

Datatable rowCallback function after initialize

I have the below working code for data table to set cell color based on condition.
$(document).ready(function() {
// DataTable
var table = $('#example').DataTable({
/*
dom: 'Bfrtip',
buttons: ['excel',{
extend: 'pdfHtml5',
orientation: 'landscape',
pageSize: 'LEGAL' }],
"ordering": false,
language: {
search: "_INPUT_",
searchPlaceholder: "Search All Data"
} */
rowCallback: function(row, data, index) {
console.log(row)
if (data[12].split(';')[1] == "In Progress") {
$(row).find('td:eq(11)').addClass('color')
}
}
});
});
The above code works fine but if I remove the comments section which is to add export function, it doesn't work.
I tried reproducing the same issue you're facing. I've created a jsfiddle example, which is working nice and fine. The only thing I changed in your code is that I added a comma (,) before rowCallback, this way :
$('#example').DataTable({
dom: 'Bfrtip',
buttons: ['excel',{
extend: 'pdfHtml5',
orientation: 'landscape',
pageSize: 'LEGAL' }],
"ordering": false,
language: {
search: "_INPUT_",
searchPlaceholder: "Search All Data"
},
rowCallback: function(row, data, index) {
console.log(row)
if (data[12].split(';')[0] == "In Progress") {
$(row).find('td:eq(11)').addClass('color')
}
}
});
and Plus, do recheck that the files related to jQuery datatable are same as the files I've added in my jsfiddle , there is a possibility that you've added a file twice or you might be using an older version of Jquery. If the issue still persists, edit your question and add your html + the files related to jquery that you've initialized.

Reordering columns, Virtual scroll, gridResize in jqgrid does not work

I am using jqgrid with Symfony to show a datagrid.
Oleg's answer solved major problems.
Here's my code:
<link rel="stylesheet" type="text/css" media="screen" href="{{ asset('bundles/productorderlookup/css/ui-lightness/jquery-ui.css') }}" />
<link rel="stylesheet" type="text/css" media="screen" href="{{ asset('bundles/productorderlookup/css/ui.jqgrid.css') }}" />
<link rel="stylesheet" type="text/css" media="screen" href="{{ asset('bundles/productorderlookup/css/ui.multiselect.css') }}" />
<style type="text/css">
span.cellWithoutBackground
{
display:block;
background-image:none;
margin-right:-2px;
margin-left:-2px;
height:14px;
padding:4px;
}
</style>
<script src="{{ asset('bundles/productorderlookup/js/i18n/grid.locale-en.js') }}" type="text/javascript"></script>
<script src="{{ asset('bundles/productorderlookup/js/jquery.jqGrid.src.js') }}" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://jquery-ui.googlecode.com/svn/tags/latest/ui/minified/i18n/jquery-ui-i18n.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-migrate/1.2.1/jquery-migrate.js"></script>
<script>
jQuery(document).ready(function(){
jQuery("#list").jqGrid({
url:"{{ asset('/app_dev.php/_thrace-datagrid/data/user_management') }}",
datatype: 'json',
mtype: 'POST',
colNames:['Product ID','Product Name', 'Product Details'],
colModel :[
{name:'id', index:'u.id', width:200,
formatter: function (cellvalue) {
var color;
var val = Number(cellvalue);
if (val%3 == 0) {
color = 'red';
} else if (val%3 == 1) {
color = 'yellow';
} else if (val%3 == 2){
color = 'green';
}
return '<span class="cellWithoutBackground" style="background-color:' + color + ';">' + cellvalue + '</span>';
}},
{name:'productName', index:'u.productName', width:200, editable: true},
{name:'productDetails', index:'u.productDetails', width:200, align:'right', editable: true}
],
autowidth: true,
//width: 800,
height: 600,
gridview: true,
autoencode: true,
shrinkToFit: false,
pager: '#pager',
rowNum:50,
rowTotal: 1000000,
rowList:[50, 100, 500, 1000],
rownumWidth: 40,
viewrecords: true,
caption: 'Product Order Lookup',
sortname: 'u.id',
sortorder: 'asc',
sortable:true,
//multiselect: true,
ondblClickRow: function(rowid) {
jQuery(this).jqGrid('editGridRow', rowid);
},
footerrow: true,
gridComplete: function() {
var $grid = $('#list');
var colSum = $grid.jqGrid('getCol', 'id', false, 'sum');
$grid.jqGrid('footerData', 'set', { 'id': colSum });
},
loadonce:false,
editurl:"{{ asset('/app_dev.php/_thrace-datagrid/row-action/user_management') }}",
subGrid: true,
subGridRowExpanded: function(subgrid_id, row_id) {
var subgrid_table_id;
var pager_id = "p_"+subgrid_table_id;
subgrid_table_id = subgrid_id+"_t";
jQuery("#"+subgrid_id).html("<table id='"+subgrid_table_id+"' class='scroll'></table><div id='"+pager_id+"' class='scroll'></div>");
jQuery("#"+subgrid_table_id).jqGrid({
url:"{{ asset('/app_dev.php/_thrace-datagrid/data/product_order_management') }}",
postData: {
masterGridRowId: row_id
},
datatype: "json",
mtype: 'POST',
colNames: ['oid','orderno'],
colModel: [
{name:"oid",index:"o.id",key:true},
{name:"orderno",index:"o.orderno", editable: true}
],
height: '100%',
pager: pager_id,
rowNum:50,
//editData: {pid: row_id}, // edit options
editurl:"{{ asset('/app_dev.php/_thrace-datagrid/row-action/product_order_management') }}",
rowList:[50, 100, 500, 1000]
});
jQuery("#"+subgrid_table_id).jqGrid('navGrid',"#"+pager_id,{
idPrefix: "s_" + row_id + "_",
del:true,
add:true,
edit:true,
addtext: 'Add',
edittext: 'Edit',
deltext: 'Delete',
searchtext: 'Search',
refreshtext: 'Reload'},
{editData: {pid: row_id}},
{editData: {pid: row_id}},
{editData: {pid: row_id}},
{multipleSearch:true}
);
jQuery("#"+subgrid_table_id).jqGrid('filterToolbar',{stringResult: true,searchOnEnter : true});
}
});
jQuery("#list").jqGrid('navGrid','#pager',{del:true,add:true,edit:true},{},{},{},{multipleSearch:true}).navButtonAdd('#pager',{
caption: "Excel",
buttonicon:"ui-icon-disk",
onClickButton: function(){
exportExcel($(this));
},
position:"last"
});
jQuery("#list").jqGrid('filterToolbar',{ defaultSearch: 'cn', stringResult: true,searchOnEnter : true});
jQuery('#list').jqGrid('gridResize');
});
I followed the instructions as Oleg suggested like here and it still gives me the same problem.
Couple of things I am facing problems with.
(1) [SOLVED] My virtual scroll is not working. I played around with height, width and shrinkToFit too. But it still does not seem to work. The only thing happening when setting scroll:true is that the paging gets disabled.
(2) [SOLVED] Sortable:true does not work. I have included the necessary css and js files and sortable still does not work.
(3) [SOLVED] Also gridResize is not working. I do get the different cursor for changing the size but upon trying to change the size, it does not seem to work.
Only thing wrong I can think of is including too many css and js files.
Any help would be appreciated on this. Thanks.
The code which you posted have many problems.
First of all you inserted jquery-1.11.3.js, then jqueryui/1.8.13/jquery-ui.min.js and then jqueryui/1.7.2/jquery-ui.js. Including of multiple versions of JavaScript libraries on one page can break functionality of the included library. You hove to remove the old jQuery UI 1.7.2.
I should include multiple document.ready handlers on the page only if you do absolutely independent things inside of the handlers. What you do are dependent calls. You can use navGrid, filterToolbar and other jqGrid methods only after the grid is created. So you should include the content of all handlers in one, first, document.ready handler.
The call of columnChooser in the form have no sense. You should include the button in navigator toolbar and call the method columnChooser only incide of onClick handler of the button.
You should include idPrefix option in subgrids which you create inside of subGridRowExpanded. Every subgrid should have unique prefix. The problem is: multiple subgrids can be opened at the same time and the ids of the rows could be the same. To protect the code to produce id duplicates you should use idPrefix option. For example idPrefix: "s_" + row_id + "_".
The last remark: I don't recommend to use scroll: true at all because of many restriction which exist in the usage of another features of jqGrid and different other implementation problems.

JQuery Datatables : Cannot read property 'aDataSort' of undefined

I created this fiddle to and it works well as per my requirements: Fiddle
However, when I use the same in my application I get an error in the browser console saying Cannot read property 'aDataSort' of undefined
In my application, the javascript reads something like as below: I have checked the controller output...it works well and is printed on the console too.
$(document).ready(function() {
$.getJSON("three.htm", function(data) {
// console.log("loadDataTable >> "+JSON.stringify(data));
})
.fail(function( jqxhr, textStatus, error ) {
var err = textStatus + ', ' + error;
alert(err);
console.log( "Request Failed: " + err);
})
.success(function(data){
loadDataTable(data);
});
function loadDataTable(data){
$("#recentSubscribers").dataTable().fnDestroy();
var oTable = $('#recentSubscribers').dataTable({
"aaData" : JSON.parse(data.subscribers),
"processing": true,
"bPaginate": false,
"bFilter": false,
"bSort": false,
"bInfo": false,
"aoColumnDefs": [{
"sTitle": "Subscriber ID",
"aTargets": [0]
}, {
"sTitle": "Install Location",
"aTargets": [1]
}, {
"sTitle": "Subscriber Name",
"aTargets": [2]
}, {
"aTargets": [0],
"mRender": function (data, type, full) {
return '<a style="text-decoration:none;" href="#" class="abc">' + data + '</a>';
}
}],
"aoColumns": [{
"mData": "code"
}, {
"mData": "acctNum"
}, {
"mData": "name"
}]
});
}
})
It's important that your THEAD not be empty in table.As dataTable requires you to specify the number of columns of the expected data .
As per your data it should be
<table id="datatable">
<thead>
<tr>
<th>Subscriber ID</th>
<th>Install Location</th>
<th>Subscriber Name</th>
<th>some data</th>
</tr>
</thead>
</table>
Also had this issue,
This array was out of range:
order: [1, 'asc'],
For me, the bug was in DataTables itself; The code for sorting in DataTables 1.10.9 will not check for bounds; thus if you use something like
order: [[1, 'asc']]
with an empty table, there is no row idx 1 -> this exception ensures.
This happened as the data for the table was being fetched asynchronously. Initially, on page loading the dataTable gets initialized without data. It should be updated later as soon as the result data is fetched.
My solution:
// add within function _fnStringToCss( s ) in datatables.js
// directly after this line
// srcCol = nestedSort[i][0];
if(srcCol >= aoColumns.length) {
continue;
}
// this line follows:
// aDataSort = aoColumns[ srcCol ].aDataSort;
I faced the same problem, the following changes solved my problem.
$(document).ready(function() {
$('.datatable').dataTable( {
bSort: false,
aoColumns: [ { sWidth: "45%" }, { sWidth: "45%" }, { sWidth: "10%", bSearchable: false, bSortable: false } ],
"scrollY": "200px",
"scrollCollapse": true,
"info": true,
"paging": true
} );
} );
the aoColumns array describes the width of each column and its sortable properties.
Another thing to mention this error will also appear when you order by a column
number that does not exist.
In my case I had
$(`#my_table`).empty();
Where it should have been
$(`#my_table tbody`).empty();
Note: in my case I had to empty the table since i had data that I wanted gone before inserting new data.
Just thought of sharing where it "might" help someone in the future!
In my case I solved the problem by establishing a valid column number when applying the order property inside the script where you configure the data table.
var table = $('#mytable').DataTable({
.
.
.
order: [[ 1, "desc" ]],
You need to switch single quotes ['] to double quotes ["] because of parse
if you are using data-order attribute on the table then use it like this data-order='[[1, "asc"]]'
Most of the time it occurs when something is undefined. I copied the code and removed few columns which disturbed the order by index. Carefully make changes and every variable after it.
"order": [[1, "desc"]], fixed my issues previous i was using "order": [[24, "desc"]], and that index was not avaialble.
I had this problem and it was because another script was deleting all of the tables and recreating them, but my table wasn't being recreated. I spent ages on this issue before I noticed that my table wasn't even visible on the page. Can you see your table before you initialize DataTables?
Essentially, the other script was doing:
let tables = $("table");
for (let i = 0; i < tables.length; i++) {
const table = tables[i];
if ($.fn.DataTable.isDataTable(table)) {
$(table).DataTable().destroy(remove);
$(table).empty();
}
}
And it should have been doing:
let tables = $("table.some-class-only");
... the rest ...
I got the error by having multiple tables on the page and trying to initialize them all at once like this:
$('table').DataTable();
After a lot of trial and error, I initialized them separately and the error went away:
$("#table1-id").DataTable();
$("#table2-id").DataTable();
My Solution
add this :
order: 1 ,
For me
adding columns in this format
columns: [
{ data: 'name' },
{ data: 'position' },
{ data: 'salary' },
{ data: 'state_date' },
{ data: 'office' },
{ data: 'extn' }
]
and ajax at this format
ajax: {
url: '/api/foo',
dataSrc: ''
},
solved for me .
Old question, but in my case I was passing an unrelated order= in the URL that would sometimes be empty. Once I changed the url variable to "sortorder" or anything other than "order" the plugin began working normally.
I got the same error, In my case one of the columns was not receiving proper data. some of the columns had strings in place of Integers. after i fixed it it started working properly. In most of the cases the issue is "table not receiveing proper data".
Just my two cents regarding order: [...];
It won't check items type, and in my case I was passing [arrOrders] as opposed to just arrOrders or [...arrOrders], resulting in [[[ 1, "desc" ], [ 2, "desc" ]]].

Populate JQuery DataTable with my json data

I'm suggested to use JQuery data table. Now I need to populate grid with bunch of json objects sent from my controller. How can I send this data on the grid from js
$.ajax({
...
url: '/Home/ReturnJsonData',
success: function (result) {
$.each(result, function (i, item) {
// this is where I should sent item object to my grid
});
},
error: function () { alert("error"); }
});
Update
I've found these link, but I dont know how to implement it.
You should use JQuery DataTable sAjaxSource property to specify ajaxsource in your case it would be /HomeReturnJsonData
An example follow
$(document).ready(function () {
$('#myDataTable').dataTable({
"bServerSide": true,
"sAjaxSource": "Home/ReturnJsonData",
"bProcessing": true,
"aoColumns": [
{ "sName": "ID",
"bSearchable": false,
"bSortable": false,
"fnRender": function (oObj) {
return '<a href=\"Details/' +
oObj.aData[0] + '\">View</a>';
}
},
{ "sName": "COMPANY_NAME" },
{ "sName": "ADDRESS" },
{ "sName": "TOWN" }
]
});
});
You can use Jquery Grid Plugin in that case.
Read this article to use MVC Data Grid: using jqGrid and JSON
http://blog.davidrenz.com/?p=663
Update:
In that case if you only want to use J-query Datatable go to this link.
http://www.codeproject.com/Articles/155422/jQuery-DataTables-and-ASP-NET-MVC-Integration-Part
I put this in a function because that was the easiest way to do it for me, feel free to copy the function and use it. All your going to need to change is the url and the column names and number there of. To call it just copy the html with the paths done so that they match whatever yours are.
function SetUpGrid(tableID, pagerID, data) {
$("#" + tableID).jqGrid({
url: '/pagename/stuff?data=' + data,
datatype: 'json',
mtype: 'GET',
colNames: ['col name1', 'col name2', ... 'col nameN'],
colModel: [
{ name: 'colName1', index: 'colName1', align: "center", sortable: true, editable: false, resizable: false },
{ name: 'colName2', index: 'colName2', align: "center", sortable: true, editable: false, resizable: false },
...
{ name: 'colNameN', index: 'colNameN', align: "center", sortable: true, editable: false, resizable: false }
],
pager: '#' + pagerID,
autowidth: true,
viewrecords: true,
rowNum: 15,
pgbuttons: true,
pginput: false,
pgtext: "Page {0} of {1}",
recordtext: "Data {0} - {1} of {2}",
emptyrecords: "No data to display",
loadui: true,
rowList: [15, 30, 60],
scrollrows: true,
hidegrid: true,
sortorder: "desc",
beforeRequest: function () { // This just inserts a loading image, you don't need it but I was loading a lot of data and wanted the user to know something was happening.
$("#" + tableID).empty().append('<tr><td><img src="/Content/imgs/loading.gif" /></td></tr>');
},
loadComplete: function (data) {
/*
Called when the json load is done, this is a way to insert the data the way I want to.
Feel free to use whatever you want like links or <p>s or <div>s or whatever.
*/
if (data.length > 1) {
for (var key in data) {
if (data.hasOwnProperty(key)) {
$("#" + tableID).empty().append("<tr><td>" + data[key].colName1 + "</td><td>" + data[key].colName12+ "</td> ... <td>" + data[key].colNameN + "</td></tr>");
}
}
} else {
$("#" + tableID).empty().append("<tr><td>" + this.colName1 + "</td><td>" + this.colName2 + "</td> ... <td>" + this.colNameN + "</td></tr>");
}
},
loadError: function (xhr, status, error) {
// Called when an error occurs, handle as you wish, if you even do.
alert(xhr);
alert(status);
alert(error);
}
});
$("#" + tableID).jqGrid("navGrid", "#" + pagerID, { add: false, edit: false, refresh: false, del: false, search: false }).trigger("reloadGrid", [{ page: 1 }]);
}
<script src="/Scripts/jquery-1.7.2.js"></script>
<script src="/Scripts/jquery-ui-1.8.23.min.js"></script>
<script src="/Scripts/jquery.jqGrid.min.js"></script>
<script src="/Scripts/grid.locale-en.js"></script>
<script src="/Scripts/ADTFunding.js"></script>
<link href="/Content/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<link href="/Content/jquery.jqGrid/ui.jqgrid.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
$(function () {
SetUpFundingGrid('dataTable', 'pager', '9895998');
});
</script>
<table id="dataTable"></table>
<div id="pager"></div>
You can also use the fnAddData property to push json to table. Check this article https://jqueryajaxphp.com/jquery-datatable-using-json/

Categories

Resources