Assign ID to datatable row from json data - javascript

i'm new to datatable jquery plugin.
I got stuck with this for more than 2 days. I have a Json Data, i still cant load the table and i also want to assign first column to be id of the row
Here is html:
<table cellpadding="0" cellspacing="0" border="0" class="display"
id="accDetailTable">
<thead>
<tr>
<th>Currency</th>
<th>Current/Savings Account No.</th>
<th>Securities Account No.</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
and my initialization
var oTable=$('#accDetailTable').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": contextPath + "/user/investorAjax?method=getInvestorAccDetailList",
"iDeferLoading": 57,
} );
Return jsonData from server :
{"sEcho":1,"iColumns":4,"iTotalRecords":16,"iTotalDisplayRecords":16,
"aaData":
[{"DT_RowId":2032,"currency":1,"currentAccNo":"aa","secureAccNo":"aa"},
{"DT_RowId":2033,"currency":1,"currentAccNo":"111","secureAccNo":"111"},
{"DT_RowId":2034,"currency":1,"currentAccNo":"a","secureAccNo":"aa"},
]}
}
But it always hit :
DataTables warning (table id = 'accDetailTable'): Added data (size undefined) does not match known number of columns (3)

Your datatables is waiting for three entries per line and you give it four. In your table declaration (in html part) specify a new header cell <th> at the beginning of your row. You will put ids in it. Then after your dataTables initialization you can hide the first column using fnSetColumnVis(index, visibility) function :
oTable.fnSetColumnVis(0, false); //It will hide your first column
Doing that each row is containing his id (DT_RowId) but not displaying it.

It's kind of easy. Let's just do a tiny change, since you want the first column contains id, you may need to use fnRender, please check the api of datatables, I didn't add this part of code:
var oTable=$('#accDetailTable').dataTable({
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": contextPath + "/user/investorAjax?method=getInvestorAccDetailList",
"aoColumns":[
{"mDataProp":"currency"},
{"mDataProp":"currentAccNo"},
{"mDataProp":"secureAccNo"}
]
});

Related

How to add a new row in datatable and re order the indexes of each row?

I am adding a new row in the datatable and its working correctly, I am ordering the table by a field (which is timestamp) which means the newly created row should have index 0 and the rows should be 1,2,3...
however the problem is that the new row is giving -1 when I check its index. So, how can I actually re-order the table when I add a new row so that the newly created row should have index 0?
var myTable = $('#myTable').DataTable();
var rowNode = myTable
.row.add([ btnHtml1, btnHtml ])
.draw();
when I check the index after it has been added:
rowindex = tr.index(); //this gives -1 for the newly created row
Can anyone suggest why is it giving the wrong index?
UPDATE:
function myFunction(this_) {
var tr = $(this_).closest("tr");
rowindex = tr.index(); //this gives the displayed index of the row, NOT the real index
}
I call it from the datatable row like this:
<td>
<button type="button" id="edit_button" onclick='myFunction(this)' name="edit_button">Edit</button>
</td>
I am not able to recreate your problem.
But I am not sure where the tr variable is defined - so, that may be causing an issue.
For a simple test, here is some data:
<table id="example" class="display dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Row Index</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>0</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>1</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>2</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>3</td>
</tr>
<tr>
<td>Airi Satou</td>
<td>4</td>
</tr>
<tr>
<td>Haley Kennedy</td>
<td>5</td>
</tr>
</tbody>
</table>
And here is a test for the data:
<script type="text/javascript">
$(document).ready(function() {
var table = $('#example').DataTable();
var rowNode = table.row.add( ['Quinn Flynn', '?'] ).draw();
console.log(rowNode.index());
});
</script>
This prints 6 to the browser console - the new row has an index of 6, as expected.
Another way to verify this is to loop through all the rows, showing the index of each one:
<script type="text/javascript">
$(document).ready(function() {
var table = $('#example').DataTable();
var rowNode = table.row.add( ['Quinn Flynn', '?'] ).draw();
table.rows().every( function () {
console.log(this.index());
});
});
</script>
This generates the following output in the browser console:
Here we can see that the row for "Quinn Flynn" has the expected index: 6.
Update
Some additional notes based on comments in the answer:
The row index assigned to a row does not change, once it has been assigned, until the row is deleted, or if the data is replaced and refreshed.
Index values are assigned based on the order of the data provided to DataTables - so, for example, in my case, the first row in my HTML table is for "Tiger Nixon" - so that is assigned row index 0. The same applies to data provided by a JSON object.
The row index is independent of the display order of the row (due to sorting and/or filtering).
When you add a new row to DataTables, it is added to the end of the existing rows inside DataTables - and is indexed accordingly. So, my new row is assigned index 6.
It sounds like you want to take the first row as displayed in the table regardless of what its index number is.
There is a shortcut you can use to get that:
console.log(table.row().data());
In my example, this returns an array:
[ "Airi Satou", "4" ]
It works because it uses row() - not rows() and therefore defaults to fetching only one row (the first row!) from the displayed table.
Be aware that if you provide your data as objects, you may not get an array like my example - you may get an object - for example, something like this:
{ "firstName": "Airi Satou", "index": "4" }

Get calling table from column option

I have a few Bootstrap table on one page. Each table has some data attributes (like data-link="test-page" and so on). Besides that, one column of each Bootstrap table uses a column formatter, using data-formatter="actionFormatter". However, I want to get the current table data attributes when actionFormatter is called, so based on the data attributes I can return a string.
Both this and $(this) return an Object, which doesn't work. $(this).closest('table').data() doesn't work either, while I expected that one to be the most true.
Here's the code I use:
<th data-field="actions" data-formatter="actionFormatter" data-events="actionEvents">Actions</th>
this returns a JSON object with the row properties, and $(this).closest('table').data(XXX) return undefined. I expected it to return an array with all the data attributes.
Is there any way to get the current processing table from within the formatter?
Example code:
<!-- table 1 -->
<table
data-actions="edit,remove"
data-url="some/url"
>
<thead>
<tr>
<th data-formatter="actionFormatter">Actions</th>
</tr>
</thead>
</table>
<!-- table 2 -->
<table
data-actions="edit,remove"
data-url="some/url"
>
<thead>
<tr>
<th data-formatter="actionFormatter">Actions</th>
</tr>
</thead>
</table>
// actionFormatter:
function actionFormatter(value, row, index, field) {
// get data-actions from the right table somehow,
// and return a string based on data-url/other
// data attributes
}
It seems that when the action formatter is called, the execution context this is an object with all the bootstrap table row associated data as well as all the data-* attributes of the row.
Taking that into account you can add an id to each table and a data-table-id attribute to your rows like:
<table
id="table-1"
data-actions="edit,remove"
data-url="some/url"
>
<thead>
<tr>
<th data-formatter="actionFormatter" data-table-id="table-1">Actions</th>
</tr>
</thead>
so that in your formatter you can retrieve the table DOM Element by using that id:
function actionFormatter(value, row, index, field) {
// get data-actions from the right table somehow,
// and return a string based on data-url/other
// data attributes
var data = $('#' + this.tableId).data();
}

AdminLTE v2.3.8. Datatable DateTime column sort

Consider this code (I use razor ASP.NET C# but it doesn't really matter).
I'am able to sort all column but the last one is a datetime which is sorted as string.
I just want to know if it is possible to have a sorting datetime column with AdminLTE datatables, with or without (better) adding plugins.
<div class="table-responsive">
<table id="tableClienti" class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Zona</th>
<th>Classe</th>
<th>Rag Soc</th>
<th>Indirizzo</th>
<th>Email/Telefono</th>
<th>Contatto</th>
<th>Email/Telefono</th>
<th>Ultimo Pass.</th>
</tr>
</thead>
<tbody>
#{
foreach (var r in Model)
{
<tr>
<td>#r.Zona</td>
<td>#r.ClasseCliente</td>
<td>#r.RagioneSociale</td>
<td><b>#r.Citta #r.CAP</b><br /> #r.Indirizzo</td>
<td>#r.Email<br /> #r.Telefono</td>
<td><b>#r.NomeContatto<br /> #r.CognomeContatto</b></td>
<td>#r.EmailContatto<br /> #r.TelefonoContatto</td>
<td>#r.DataUltimoPassaggio</td>
</tr>
}
}
</tbody>
</table>
</div>
$(function () {
var table = $("#tableClienti").DataTable({
paging: false,
"sDom": '<"top"i>rt<"bottom"><"clear">',
"scrollX": true,
"scrollY": "45vh",
"bSort": true
]
});
If you stumble upon this question, I solved after having issues using data-order.
This link shows how data-order works but this comment found on same page was the key for me:
Its important to notethat the data-* attributes with search() will
only work if you use this on every COL!!! You can not mix it like:
< tr>< td>Value1< /td>< /tr> < tr>< td data-search='Value 2
XYZ'>Value2< /td>< /tr> It seems the Plugin-Code always check the first
row and then use this value for all search operations. Maybe for the
future would be very cool if you can mix it ;):
Best Regards Tom
Previously, I tried to add data-order to < td> only if the "DateTime variable" was not null.
Thanks to this comment I set data-order = "DateTime variable".Ticks when "DateTime variable" is not null and data-order = 0 when "DateTime variable" is null.
So, I changed this piece of code
<td>#r.DataUltimoPassaggio</td>
in this way
#{
DateTime data;
if (DateTime.TryParse(r.DataUltimoPassaggio.ToString(), out data))
{
<td data-order="#(data.Ticks)">#(data.ToString())</td>
}
else
{
<td data-order="0"></td>
}
}

Adding select menu to multiple tables with jquery data tables pluglin

I've got two tables (table1,table2) that are structurally the same, but fed from different sources. Both tables share the class 'display' which I use to initialise the plugin for both tables. This works great for the most part, however the column filters select menu for table2 is duplicated on table1.
I've tried to fix this by using 'this' keyword to indicate a particular instance of the toolbar each of the filters need applying to, but not had much success.
The code that works is:
HTML:
<table id="table1" class="display table-striped table-borded table-hover" cellspacing="0" width="100%">
<thead>
<tr>
<th>Report Name</th>
<th>Year</th>
<th>Montly Snapshot</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Date of Last Refresh --var from warehouse-- </th>
</tr>
</tfoot>
</table>
<table id="table2" class="display table-striped table-borded table-hover" cellspacing="0" width="100%">
<thead>
<tr>
<th>Report Name</th>
<th>Year</th>
<th>Montly Snapshot</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Date of Last Refresh --var from warehouse-- </th>
</tr>
</tfoot>
</table>
JS:
//initialise data tables plugin and apply custom settings.
var reportstable = $('table.display').DataTable({
"sDom": '<"toolbar">Bfrtlp',
"searchCols": [
null, {
'sSearch': 'Current'
}
],
language: {
search: "_INPUT_",
searchPlaceholder: "Search for a Report..."
},
// create select form controls
initComplete: function() {
this.api().columns([1, 2]).every(function() {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo($('.toolbar'))
.on('change', function() {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
column.data().unique().sort().each(function(d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
if ($('#info').css('display') == 'block') {
$("#reports_wrapper").css('display', 'none');
}
// add bootstrap classes and placeholder property to form controls to add style
$('.toolbar select').addClass('selectpicker');
$('.dt-button').addClass('btn btn-danger').removeClass('dt-button');
$('.toolbar select').attr('id', 'year');
$('#year').prop('title', 'Financial Year');
$("#year option:contains('Current')").remove();
$('.toolbar select:nth-of-type(2)').attr('id', 'month');
$('#month').prop('title', 'Monthy Snapshot');
$("#month option:contains('undefined')").remove();
});
});
},
// create clear filter button
buttons: [
{
text: 'Clear Filters',
action: function(e, dt, node, config) {
$('select').val('').selectpicker('refresh');
// set Current Year as default filter
reportstable
.search('')
.columns([1]).search('Current')
.columns([2]).search('')
.draw();
}
}
],
//hide specified columns
"columnDefs": [
{
"targets": [1],
"visible": false,
"searchable": true
}, {
"targets": [2],
"visible": false,
"searchable": true
}
]
});
I've updates your jsfiddle and created a new jsfiddle. It's now appending 2 select menus in both tables's wrapper div. I've found why it's appending 4 select menus instead of 2 on the table1's wrapper div. It's because of this code: .appendTo($('.toolbar')). When initComplete callback function is called for table1 there is only one div with class=toolbar, and when the initComplete callback function is called for table2 there is two div with class=toolbar, one in table1's wrapper div and one in table2's wrapper div. that's why on table2's initComplete callback function it append select menus to all divs with class=toolbar. We should rather append to the current table wrapper's div with class=toolbar.

I have a button in each row of a table: How can the OnClick handler tell which row it was called from?

The goal: ,,
So I've got a Table (Which is initialized as a JQuery DataTable). Each row contains a 'remove me' button, and when that button is pressed, I want to delete the row from the current table.
What I've tried:
tr = $(this).closest('tr');
$('.my-table-class').dataTable().fnDeleteRow(tr);
What happens
No matter what row I click on, the last row is deleted from the table is deleted, except if there's only one row in the table, in this situation a javascript error: "TypeError: j is undefined" is thrown from Jquery.dataTable.min.js. Both baffle me.
I can get the attributes of the right row - for example, If do something like: alert($(this).attr("data-name")); I click on John Smith's row, I'll see 'John Smith' in an alert box... so $(this) is the a tag, so why doesn't the .closest() method grab the right trtag?
My Questions:
How do I get 'this' row (the one which contained the button which was pressed) in order to delete it?
Any idea what's causing the 'TypeError: j is undefined" error when there's only one row in the table?
Details:
Here's the rendered (from .jsp) HTML table:
<table class="table my-table-class">
<thead><tr><th>Name</th><th> </th></tr></thead>
<tbody>
<tr>
<td>John Smith</td>
<td><i class="icon-plus"></i></td>
</tr>
<tr>
<td>Robert Paulson</td>
<td><i class="icon-plus"></i></td>
</tr>
<tr>
<td>Juan Sanchez</td>
<td><i class="icon-plus"></i></td>
</tr>
</tbody>
Here's how I initialize the tables as a Jquery DataTable:
$('.st-my-table-class').dataTable( {
"bInfo": true,
"aaSorting": [[ 0, "desc" ]], // sort 1st column
"bFilter": true, // allow search bar
"bPaginate": false, // no pagination
"sDom": '<"top"f>rt<"bottom"lp><"clear">' // (f)ilter bar on top, page (i)nfo omitted
} );
And here's the whole event handler:
$('.my-button-class').on("click", function(){
tr = $(this).closest('tr');
$('.my-table-class').dataTable().fnDeleteRow(tr);
});
I think This JSFIDDLE is much closer to what you wanted. Here is the basic code
$(function() {
var dataTable = $('.my-table-class').dataTable();
$( ".test" ).click(function() {
var row = $(this).closest('tr');
var nRow = row[0];
dataTable.dataTable().fnDeleteRow(nRow);
});
});
which I pulled from this resource here that explains in full detail on how it works. In short you need to select the node itself not the jQuery object. You can also use .firstlike so.
$( ".test" ).click(function() {
var row = $(this).closest('tr').first();
dataTable.dataTable().fnDeleteRow(row);
Note: I added the "This" text as I don't have the button style/icon.
As #Dawn suggested, you're passing a jQuery element to fnDeleteRow, which is expecting a HTML node.
Simply try:
$('.my-button-class').on("click", function () {
tr = $(this).closest('tr').get(0); // gets the HTML node
$('.my-table-class').dataTable().fnDeleteRow(tr);
});
Working JSFiddle: http://jsfiddle.net/so4s67b0/
First of all in the function it is need to declare a variable and assign our data table to it. Then take the selected row's index into another variable. After that remove the selected row from the data table. .draw(false) will be manage the pagination and no of rows properties in jquery DataTable.
$('.my-button-class').click(function () {
var tbl = $('.my-table-class').DataTable();
var index = tbl.row(this).index();
var row = $(this).closest("tr").get(index);
tbl.row(index).remove().draw(false);
});

Categories