I have tried all the commands for destroy and empty of the datatable after selecting a new option, and is not working.
this is some part of my js file that contains the ajax. it uses dynamic urls apis.
function table(url, columns) {
var dt = $("#datatables").dataTable({
"serverSide": true,
"processing": true,
"ajax": {
"url": url,
"type": "GET",
},
"columns": columns,
lengthMenu: [[25, 100, 250, 500], [25, 100, 250, 500]],
pageLength: 25,
// destroy: true
});
... // more stuff here about the design of the table
}
$("form#btnGetDomain").on("submit", function (ev) {
ev.preventDefault();
ev.stopPropagation();
// $("#datatables").dataTable().fnDestroy();
var url;
var columns;
var categ = document.getElementById("categ").value;
// this is where i do if statements depending what options was selected
// i get the proper url api
...
table(url, columns);
});
i have tried all those commands:
$("#datatables").dataTable().fnDestroy();
$("#datatables").empty();
destroy: true,
The command "destroy: true" inside the dataTable i don't know if it works properly because after i try to select the second time another option, the table doesn't responde, it just says ** Processing....**
I also tried to put the comand inside the on submit function before i select any option to clear the table. Now i m thinking of doing an if statement, if their is a table, clear it.
Thank you
UPDATE
i ve tried with dataTable and DataTable
**UPDATE 2 **
if ($.fn.DataTable.isDataTable("#datatables")) {
$("#datatables").DataTable().clear().draw();
$("#datatables").dataTable().fnDestroy();
}
This command i have put before the var dt = $("#datatables").dataTable({...
Yes i noticed i used small and big cap datatable...but this worked ...i did try to put both with big D but didn't work... also tryed to use in the last one: DataTable().destroy();...didn't work
Example: using videos and channels
I have selected the first time videos.
After i select channels:
It changes the columns names no problem ( i have different columns names for every api)... but the rows remain the same.
When i select back to videos.
Column names change, and rows are changing to previous selection which was channels.
Hope you can understand. It doesn't really make sense why i have to use dataTable and DataTable...
it does change, but wrong changes...at least i am getting closer to the answer, hopefully.
I found out the answer i put this lines of code at the beginning of the table function
function table(url, columns) {
var dt;
if ($.fn.DataTable.isDataTable("#datatables")) {
$("#datatables").DataTable().clear().draw();
$("#datatables").DataTable().destroy();
$("#datatables thead").html('');
}
...
}
It works for me fine, it clears the rows, destroys the table, and empty the thead.
Oh..and i have change from lower case dataTable too upper case DataTable
Update: Did you try clear command? https://datatables.net/reference/api/clear()
$('#datatables').DataTable().clear().draw();
Another thing you could try is using the variable to destroy the table:
var dt = $('#datatables').DataTable({...init stuff...});
dt.destroy();
This could be a dt version issue. Did you try:
$('#datatables').DataTable().destroy();
Please notice the difference dataTable vs DataTable.
Related
I'm trying to implement the child row feature to display extra columns fetched from a google spreadsheet into a basic Datable I've setup via a combination of Datatables, Tabletop and Bootstrap scripts packaged on github. This basic datatable is live and working fine error-free.
I've created a duplicate of the html page & the JS file and modified the code to implement the child rows according to the Datatable reference page. The html page is here: https://www.socialtheorywatch.org/database2.html
If you need to see the original basic working Datatable code just remove the 2 from the URL.
Google chrome browser console & JShint keep throwing Unmatched { on line 73 of my code $(document).ready(function() {. The full JShint error list looks like this:
Four warnings 127 Expected an identifier and instead saw ')'.
127 Expected an assignment or function call and instead saw an
expression. 73 Unmatched '{'. 128 Unrecoverable syntax error. (100%
scanned).
Before the syntax error issue I had the table drawn up fine with the open/close column successfully drawn, but the onClick function wasn't revealing the child rows. I posted that issue on the Datables forum and they helped me with moving the onClick function inside the bottom of the writeTable function by removing a closed curly bracket '}' from the line right before it. But now I get the syntax errors and I've fiddled with adding/removing/repositioning all sorts of brackets everywhere with no luck.
$(document).ready(function() {
function initializeTabletopObject() {
Tabletop.init({
key: key,
callback: function(data, tabletop) {
writeTable(data); //call up datatables function
},
simpleSheet: true,
debug: false });
}
initializeTabletopObject();
function writeTable(data) {
//select main div and put a table there
//use bootstrap css to customize table style: http://getbootstrap.com/css/#tables
$('#childRowTest').html(
'<table cellpadding="4" cellspacing="4" border="1" class="table table-condensed table-bordered table-striped table-hover table-responsive" id="wrongfulConvictionDBSA"></table>'
);
//initialize the DataTable object and put settings in
$("#wrongfulConvictionDBSA").DataTable({
"autoWidth": false,
"data": data,
"columns": columns,
"order": [
[7, "desc"]
], //order on second column
"pagingType": "simple_numbers" //'Previous' and 'Next' buttons, plus page numbers
//"pageLength": 50
//"lengthMenu": [ [10, 25, 50, -1], [10, 25, 50, "All"] ]
//uncomment these options to simplify your table
//"paging": false,
//"searching": false,
//"info": false
});
// Add event listener for opening and closing details
$('#wrongfulConvictionDBSA tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row( tr );
if ( row.child.isShown() ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
});
});
//end of writeTable
I'm looking to resolve the syntax errors.
This is more of an answer to the "table not defined" issue described in this comment, but it seemed somewhat clumsy and inappropriate to try to solve it in replies.
It looks like your code is based on this example.
But in that example, the table variable is declared and assigned the return value of the DataTable call:
var table = $(...).DataTable({...})
and you're not doing that in your code:
//initialize the DataTable object and put settings in
$("#wrongfulConvictionDBSA").DataTable({
"autoWidth": false,
"data": data,
...
There may be other problems, but I'd start by getting the table variable and then see what breaks next, if anything.
Good day
Painting the scenario:
I have a scenario I am working on for work, where I had to freeze the header row and first column on larger tables. I have utilized the jquery Datatables plugin with its fixedColumns extension to be able to do so
The table that I am working on also happens to have knockout.js bindings, which renders the <tbody> rows from data obtained in the page's typescript.
the issue
When I do a pull from the server to get the data from the table, on page refresh or on interactions with other controls on the page, I run the following code (be warned, it's quite ugly - just trying to get it to work now):
module dataTable {
export class dataTableClass {
applyTable(tableIdString: string) : void {
(<any>$(tableIdString))
.DataTable({
scrollY: 1000,
scrollX: true,
scrollCollapse: true,
paging: false,
searching: false,
fixedHeader: true,
fixedColumns: {
leftColumns: 1
}
});
}
dataTableExists(tableIdString: string): boolean {
return (<any>$.fn.DataTable.isDataTable(tableIdString));
}
applyDatatableIfTableExists(retryCount: number, elementId: string): void {
if (!elementId) {
console.warn("table id not defined.");
return;
}
if (!retryCount) {
retryCount = 0;
} else if (retryCount > 100) {
console.warn("could not convert table to dataTable.");
return;
}
window.setTimeout(() => {
var tableIdString = "#" + elementId;
if ((<any>$(tableIdString)).length <= 0) {
this.applyDatatableIfTableExists(++retryCount, elementId);
} else {
if (this.dataTableExists(tableIdString)) {
debugger;
(<any>$(tableIdString)).DataTable({ retrieve: true }).destroy(); // <-- issue here. it seems to restore old data to the now-datatable-less table
}
window.setTimeout(() => {
this.applyTable(tableIdString);
if (!this.dataTableExists(tableIdString)) {
this.applyDatatableIfTableExists(++retryCount, elementId);
}
}, 250);
if (!(<any>$(tableIdString)).hasClass(".dataTable")) {
(<any>$(tableIdString)).addClass(".dataTable");
}
}
}, 250);
}
applyDataTable(id) {
this.applyDatatableIfTableExists(0, id);
}
}
}
On server pull, in typescript, when the deferred code resolves and sets the table's data on an knockout observable array, the applyDataTable class gets called with the table's html ID
all the code runs fine for the first time - I allow the browser some time to render the table and to convert the table into a DataTable
When a user interacts with other controls on the page (to set filters for the knockout Observable array to change the table's contents), I destroy the table - presuming the table has already been initialised.
I recreate the table with the same DataTable options immediately after that so that new data (theoretically) displays in the table, having the fixedColumns extension render correctly again (since it changes cells and table header cells into tables of their own and apply css to make it look neat)
The issue comes on the line I marked. What happens on-screen is that it definitely removes the changes applied by DataTables from the HTML, but, the table that renders has old data in it (even though I fetched new data from the server by changing my search criteria on page - which generates new ....).
Also commenting out all this code inside my applyDataTable() method, it never sets the datatable plugin on my html table (as expected) and changing my filters reflects the newest and correct data on my table.
So in tl;dr - what is happening is that some state information gets stored by datatables. is there a way for me to clear this state and only apply a datatable with my settings over my html table?
You can remove the old data from table body or the whole table. It depends on whether you're recreating column headers later.
For example:
$('#example').DataTable().destroy();
$('#example tbody').empty();
So in your case it would be something like:
(<any>$(tableIdString)).DataTable().destroy();
(<any>$(tableIdString + ' tbody')).empty();
I have the following code that builds a grid using slickgrid.js.
var grid;
var gridDataview;
var gridOptions = {
enableCellNavigation: true,
enableColumnReorder: true,
forceFitColumns: false,
topPanelHeight: 25
};
function createGrid(data) {
gridDataview = new Slick.Data.DataView({ inlineFilters: true });
grid = new Slick.Grid("#grid", gridDataview, data.columns, gridOptions);
grid.setSelectionModel(new Slick.RowSelectionModel());
var pager = new Slick.Controls.Pager(gridDataview, grid, $("#pager"));
var columnpicker = new Slick.Controls.ColumnPicker(data.columns, grid, gridOptions);
grid.onSort.subscribe(function (e, args) {
sortdir = args.sortAsc ? 1 : -1;
sortcol = args.sortCol.field;
// using native sort with comparer
// preferred method but can be very slow in IE with huge datasets
gridDataview.sort(comparer, args.sortAsc);
});
// if you don't want the items that are not visible (due to being filtered out
// or being on a different page) to stay selected, pass 'false' to the second arg
gridDataview.syncGridSelection(grid, true);
$("#gridContainer").resizable();
}
I am using this with knockout-js and initially only create the grid after the user makes a selection from a listbox, at which point i fetch data from an rest service and build the grid. each subsequent user selection will not create the grid, only update the data.
self.selectedInstrument.subscribe(function (newValue) {
$.getJSON('/data/' + self.selectedCategory().id + '/' + newValue.id, function (data) {
self.cotData(data);
if (grid == null) {
debugger;
createGrid(data);
}
//gridDataview.beginUpdate();
gridDataview.setItems(data.data);
//gridDataview.endUpdate();
});
});
What's happening is:
1. when the grid is initially create, no data is shown, just the column headers. if i move re-order a column header, then the data is shown.
2. If i sort a column, the sort is not visibly reflected. if i start scrolling, then i see the sort being reflected.
3. if i add a grid.render() to the end of the subscription handler above, i do see the data immediately, but then i'm not able to vertically scroll any longer. things seem badly broken at this point.
Any thoughts on what may be happening here? This started happening after i modified the code to create a DataView rather than loading the data right into the grid immediately. I need a DataView because i want to allow sorting and later different types of aggregation and groupings.
Is this possibly related to usage of slickgrid with knockout js?
Thanks much
Not sure why yet, as i'm still feeling my way around SlickGrid, but i had to add the following two subscriptions. the first allowed the grid to display rows immediately when new data is loaded and the second solved a similar issue, but when sorting:
// wire up model events to drive the grid
gridDataview.onRowCountChanged.subscribe(function (e, args) {
grid.updateRowCount();
grid.render();
});
gridDataview.onRowsChanged.subscribe(function (e, args) {
grid.invalidateRows(args.rows);
grid.render();
});
I'm trying to use tablesorter.js but im running into issues when using ajax to update my table. I followed the code on this page but it doesn't seem to be working properly. One thing i also notice is that the code doesnt work properly even on the example website. When i click "append new table data" it adds the data to the table but it isn't sorting it correctly. If i copy the javascript code and paste it into the console, it works fine and sorts the table correctly. The code im using is the following:
var updateTableSort = function(){
var table = $('#transaction-table')
//tells table sorter that table has been updated
table.trigger("update");
//re sorts after table has been updated based on
//current sort patern
var sorting=table.get(0).config.sortList;
table.trigger('sorton', [sorting]);
}
Again, if i copy and past this into console it works fine, but when i have it in my success ajax function, it doesnt sort the table properly. Any help figuring out what the issue is would be greatly appreciated
Try my fork of tablesorter. It automatically resorts the table after an update:
// pass anything BUT false and the table will resort
// using the current sort
$("table").trigger("update", [false]);
Here is the updated append data to the table using ajax demo:
$(function() {
$("table").tablesorter({ theme : 'blue' });
$("#ajax-append").click(function() {
$.get("assets/ajax-content.html", function(html) {
// append the "ajax'd" data to the table body
$("table tbody").append(html);
// let the plugin know that we made a update
// the resort flag set to anything BUT false (no quotes) will
// trigger an automatic
// table resort using the current sort
var resort = true;
$("table").trigger("update", [resort]);
// triggering the "update" function will resort the table using the
// current sort; since version 2.0.14
// use the following code to change the sort; set sorting column and
// direction, this will sort on the first and third column
// var sorting = [[2,1],[0,0]];
// $("table").trigger("sorton", [sorting]);
});
return false;
});
});
jqGrid exposes a property rowNum where you can set the number of rows to display for each page. How do you set the grid to just display ALL rows?
Right now I'm just setting the rowNum to something really high like <%= int.MaxValue %> but I'm wondering if there is a better way.
In the latest version of jqGrid, you can set rowNum to -1 to instruct the grid to always display all rows:
rowNum: -1
See the latest jqGrid documentation here.
Specifically:
Sets how many records we want to view in the grid. This parameter is passed to the url for use by the server routine retrieving the data. Note that if you set this parameter to 10 (i.e. retrieve 10 records) and your server return 15 then only 10 records will be loaded. Set this parameter to -1 (unlimited) to disable this checking.
Update
Unfortunately this behavior was broken in jqGrid 3.6.3. According to this post from Tony:
Yes, this is true. The reason is the new introduced scroll:1. In the future we will correct this behavior.
So the jqGrid developers are aware of this problem and apparently are planning to fix it in a future release. Unfortunately this post was from over a year ago...
At this time, all I can recommend is that you set rowNum to a very large number to simulate the behavior of -1.
You can also try whatispunk's solution below of using rowNum: ''. However, I tried this on a grid containing local data (loadonce: true). When attemping to sort the rows all of the grid's local data would disappear. So this solution does not seem to work for grids with local data, unless this defect has been fixed in a later version of jqGrid (I tested it on jqGrid 3.8.2). If you have feedback, please post a comment below!
Update - April 16, 2014
According to the jqGrid team this is now fixed:
I have added support to set different display values on pager select box including -1 for all.
I have not had a chance to test to confirm the fix, though. Presumably this change will be in the next release after jqGrid 4.6.0.
jqgrid (3.5 anyway) doesn't seem to have an elegant built in way to do this. The best I have found so far is to add something like the following to your grid options:
rowList:[10,20,30,100000000],
loadComplete: function() {
$("option[value=100000000]").text('All');
},
Where the 100000000 is some arbitrarily higher number than the maximum # of rows you will ever return, and the option[value=] line is so your user interface looks a little nicer. Jenky, but works for me.
if you dont wish to use paging at all then change you server side code to simply return all the rows. dont use the rows parameter at all.
if you want to have the rowlist but also have an option to show all then do something like this in the grid properties
jQuery("#statement_mods").jqGrid({
rowList:['ALL',30,50,100,200]
});
and then in the serverside code make sure that you ignore the rows parameter if GET['rows']='ALL'
This works:
// Step1 - defines the rows
jqGridOptions.rowList =[10, 50, 100, 500, 'All'];
...
...
// Step2 - Change the 'All' to a meaningful value
loadComplete: function (data) {
$(".ui-pg-selbox option[value='All']").val(1000);
}
setting rowNum:-1 did the trick for me
If you have set the pagination on the navbar, you can also access to the total number of rows written on the right-bottom of the grid and then append to the generated RowList option.
Do something like :
// Get the total number of rows and delete space between numbers (Split the content of the div depending of the language (for me french)
var val=jQuery("#pager_right div").text().split('sur')[jQuery("#pager_right div").text().split('sur').length-1].split(' ').join('');
// And do the appending if the option isn't already added
if(!$(".ui-pg-selbox option[value='"+val+"']").length > 0)
jQuery(".ui-pg-selbox").append($('<option></option>').val(val).html(val));
Setting rowNum: '' you get all rows.
Jqgrid.PagerSettings.PageSize = Max Row you want to display;
Jqgrid.ToolBarSettings.ToolBarPosition = ToolBarPosition.Hidden;
I've got this working:
$('#bla').jqGrid({
...
'rowNum' : 0,
'loadOnce' : true,
'loadComplete': function(data) {
$(this).jqGrid('setGridParam', 'rowNum', data.total);
},
...
});
This works with and without the loadOnce option set to true. Note that you have to set the rowNum option to 0 first, if you leave out this option it'll still default to the 20 records to show.
Also, I'm assuming you're returning the total rows from the server in the documented JSON reader format.
resolved it with simple change:
rowNum: inputDataArray.length
where inputDataArray is the array that I am providing to the Grid.
By default the JQ grid show 20 rows Max ,if you are using not using pagination:
// To over come with this problem ,you can just write the bold mark
(rowNum:10000,):
$("#MasterDataDefinationGrid").jqGrid({
url: 'FetchData.aspx/GetDataFromDB',
datatype: 'json',
mtype: 'POST',
height: 300,
autowidth: true,
serializeGridData: function (postData) {
return JSON.stringify(postData);
},
ajaxGridOptions: { contentType: "application/json" },
loadonce: true,
colNames: [Your column names],
colModel: [Your model],
formatter: 'actions',
pager: '#MasterDataDefinationPager', pgbuttons: false,pgtext:false,
multiselect: false,
ignoreCase: true,
**rowNum: 10000,**
loadtext: 'Loading ...',
gridview: true,
hidegrid: false,
jsonReader: {
page: function (obj) { return 1; },
total: function (obj) { return 1; },
records: function (obj) { return obj.d.length; },
root: function (obj) { return obj.d; },
repeatitems: false,
id: "0"
},
caption: 'Data'
});
You can also go into jquery.jqGrid.js and change "rowNum:20" to "rowNum:Some-Really-Large-Number". When you define your jqGrid, don't specify rowNum. Then return your entire dataset back to jqGrid.
Even if it still appears in the doc that you cannot set rowNum to -1 as of jqGrid 4.5.4 it works again (maybe in earlier version too).
loadComplete: function (data) {
//set our "ALL" select option to the actual number of found records
$(".ui-pg-selbox option[value='ALL']").val(data.records);
}
This changes the "ALL" option to the actual number of records in the dataset.
Setting rowNum:-1 works for me like, after that it was showing all records but it still has row number option in grid footer like this:
To remove this I just added a css option display none by getting the sector in jquery. Like this
$('#id_tableCell').css('display', 'none');
Note: This css setting should be done when the grid load is completed.