I'm facing an issue using the Datatables plug-in regarding a table reload after the user adds a row.
I'm receiving some JSON data as part of a webservice call, after successfully receiving that data, I am calling a function that will build the table rows and append them to the tbody of the datatable as follows:
const buildTableRows = obj => {
const table = document.querySelector('#participantes tbody');
table.innerHTML = "";
for (item of obj) {
const tableRow = `<tr id="${item.ContactoId}" data-contributos="${item.Contributos}" data-updated="false" class="participante-row"><td><i class="material-icons">arrow_right</i>${item.Nome}</td><td class="contributos"><input value="${item.Contributos}">   <i class="material-icons delete">delete_forever</i></td></tr>`;
table.insertAdjacentHTML('beforeend', tableRow);
}
}
After this, I call another function responsible for initializing the Datatable and saving it to a global object for future reference:
const buildDataTable = () => {
const table = $('#participantes').DataTable({
"pagingType": "simple_numbers",
"pageLength": 4,
"lengthChange": false,
"columnDefs": [{
"targets": 1,
"orderable": false
}],
responsive: true
});
controlObj.datatable = table;
}
In my HTML I have a dynamically generated select element which lets the user add a row to the table. When the user adds the row, those two functions get called again. I can see the new row in my data structure but the table doesn't get refreshed without a page reload. I went through the plugin docs and tried to use the destroy method, rows.add(), clear(), draw() etc.. but nothing seems to work for me. The table structure is already in the DOM, I just need to reload the table. Any help would be much appreciated
Datatable cannot be clear and redraw for updated HTML DOM for table but it has to be inserted using JSON array.
To refresh it after change in DOM, you need to destroy the table and re-initalize it.
See below example where on click of ADD button I have added new row and reiniitalized the table but before that I have destroyed it.
$(document).ready(function() {
//Initialize the table and save it in a variable.
var table = $('#example').DataTable();
var id = 0;
$('#add').on('click', function(){
table.destroy();
//add row to the table
var html = '<tr><td>' + id + '</td><td>First Name' + id + '</td><td>Last Name' + id + '</td></tr>';
//console.log(html);
$('#example tbody').append(html);
id++;
table = $('#example').DataTable();
});
} );
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/dataTables.jqueryui.min.css">
<script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<table id="example" class="display nowrap" style="width:100%">
<thead>
<tr>
<th>ID</th>
<th>First name</th>
<th>Last name</th>
</tr>
</thead>
<tbody>
<tr>
<td>00</td>
<td>First</td>
<td>Last</td>
</tr>
</tbody>
</table>
Click Button to Add row : <input id="add" value=" ADD " type="button">
Yes you can use DataTable api. without destroying table you just need a function.
$(document).ready(function() {
var dt = $('#example').DataTable();
$('#addRow').click(function () {
var rowHtml = $("#newRow").find("tr")[0].outerHTML
console.log(rowHtml);
dt.row.add($(rowHtml)).draw();
});
});
here is working example
Related
I am new to JavaScript, not sure if this very basic question. I am trying to create a Bitcoin Price update dashboard using the data fetched from the external WebSocket. I managed to get the data from the WebSocket. The price updates every seconds, I am not sure how should I push the row data into a HTML table dynamically. I tried to iterate the array but still I am not able to proceed.
I have provided the code snippets below as well as external Websocket from where I am pulling the data.
Please let me know how should I insert the row dynamically into a HTML table. Thank you so much in advance.
<body>
<table>
<thead>
<tr>
<th scope="col">Price</th>
</tr>
</thead>
<tbody id="pricetable">
</tbody>
</table>
<script>
var binanceSocket = new WebSocket("wss://stream.binance.com:9443/ws/btcusdt#trade");
binanceSocket.onmessage = function (event) {
var messageObject = JSON.parse(event.data)
console.log(messageObject.p);
var table = document.getElementById('pricetable')
}
</script>
</body>
Assuming that you have your table in HTML ready with the row for Bitcoin as below. Then just select the <td> cell for price and format the figure accordingly before inserting to it's textContent.
function insertRow(price){
var tr = document.createElement("tr"),
tdCoin = document.createElement("td"),
tdPrice = document.createElement("td"),
docFrag = new DocumentFragment();
tdCoin.textContent = "BTC";
tdPrice.textContent = `${Number(price.slice(0,-6)).toLocaleString("en-US",{style: 'currency', currency: 'USD'})}`;
tr.appendChild(tdCoin);
tr.appendChild(tdPrice);
docFrag.appendChild(tr);
return docFrag;
}
var binanceSocket = new WebSocket("wss://stream.binance.com:9443/ws/btcusdt#trade"),
table = document.getElementById("pricetable");
binanceSocket.onmessage = function(event) {
var messageObject = JSON.parse(event.data);
table.appendChild(insertRow(messageObject.p));
}
<body>
<table>
<thead>
<tr>
<th>Coin</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody id="pricetable">
</tbody>
</table>
</body>
Add an id to your table, so you can properly access it.
<table id="priceTable">
Then add the new data like so (since i dont know the shape of messageObject.p I am assuming it is a string):
var binanceSocket = new WebSocket("wss://stream.binance.com:9443/ws/btcusdt#trade");
binanceSocket.onmessage = function (event) {
var messageObject = JSON.parse(event.data);
console.log(messageObject.p);
var table = document.getElementById('priceTable').getElementsByTagName('tbody')[0];
var newRow = table.insertRow(table.rows.length);
newRow.innerHtml = `<p>${messageObject.p}</p>`;
}
I have flagged this post as a duplicate of this one. However OP needed a little more help on how to apply the answer to their situation. So I put an answer up
I use JQuery DataTable. I send data to datatable onclick in json file at ajax succes .the first click everything is good,But the next click I get only the right data ANd wrong value of dataTables_info it display always the first value of dataTables_info And paginatio AND row too from the first result.
This is the first display of data in datatable:
ALL the next Click I get only right data:
For this exemple they are one result showing in picture below but everything else(info ,show,pagination) belong to first search showing in the first picture :
In the second Exemple When I click at any page of pagination I get the content of the first page result!!
This is my function ONclick:
$ ( '#ButtonPostJson' ).on('click',function() {
$("tbody").empty();
var forsearch = $("#searchItem").val();
$.ajax({
processing: true,
serverSide: true,
type: 'post',
url: 'searchData.json',
dataType: "json",
data: mysearch,
/* bRetrieve : true,*/
success: function(data) {
$.each(data, function(i, data) {
var body = "<tr>";
body += "<td>" + data.name + "</td>";
..........................
..........................
body += "</tr>";
$('.datatable-ajax-source table').append(body);
})
;
/*DataTables instantiation.*/
$('.datatable-ajax-source table').dataTable();
},
error: function() {
alert('Processus Echoué!');
},
afterSend: function(){
$('.datatable-ajax-source table').dataTable().reload();
/* $('.datatable-ajax-source table').dataTable({bRetrieve : true}).fnDestroy();
$(this).parents().remove();
$('.datatable-ajax-source table').dataTable().clear();*/
}
});
});
I try everything and i dont know what I miss.
I use this jquery for datatable:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
Thanks.
Use like it
$('#product_table').DataTable().ajax.reload();
Get table id first, like:
var table=('#tableid').Datatable();
table.draw();
just put these lines after ajax success function to reload datatable
On a button clik you dont need to empty your table body and make initiate the datatable again with the ajax.
you just have to call your ajax again as you have already initiate on document ready function
just use
$("#Table_id").ajax.reload();
check the below link, you will have better idea.
https://datatables.net/reference/api/ajax.reload()
Let me know if this doesn't help you
I had this same problem. I found a function I wrote on a project that deals with this. Here is a simple 2 column table I made.
<table id="memberships" class="table table-striped table-bordered table-hover" width="100%">
<thead>
<tr>
<th>Member Name</th>
<th>Location</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Member Name</th>
<th>Location</th>
</tr>
</tfoot>
</table>
This is my script to populate it:
function drawTable(){
var table = $('#memberships').DataTable();
table.destroy();
value = $("#memberName").val();
console.log("member name-->>" + value);
$('#memberships').DataTable({
responsive:true,
pageLength: 50,
ajax:{
"url": `//BACKEND API CALL`,
"type":"get",
"dataSrc": 'members'//my data is in an array called members
},
columns: [
{"data": "name_display" },
{"targets": 0,
"data": "membershipID",
"render": function ( data, type, full, meta ) {
return '<button type="button" class="btn btn-info btn-block"
onclick="editMember(' + data + ')">Edit Member</button><button
type="button" class="btn btn-danger btn-block"
onclick="deleteMember(' + data + ')">Delete</button>';
}
}
]
});
$.fn.dataTable.ext.errMode = 'none';
}
You can ignore my column render function. I needed 2 buttons based on the data returned. The key was the table.destroy in the function. I created the table in a variable called table. I destroy it right in this initialization because it allowed me to use this same function over and over. The first time it destroys an empty table. Each call after that destroys the data and repopulates it from the ajax call.
Hope this helps.
Update: After playing with datatables alot more I found that setting table to a variable in a global scope to your function allows you to use reload.
var table = $('#memberships').DataTable({});
Then
table.ajax.reload();
should work.
I created this simple function:
function refreshTable() {
$('.dataTable').each(function() {
dt = $(this).dataTable();
dt.fnDraw();
})
}
use below code..it perfectly work, it keep your pagination without lose current page
$("#table-example").DataTable().ajax.reload(null, false );
$('.table').DataTable().ajax.reload();
This works for me..
$("#Table_id").ajax.reload(); did not work.
I implemented -
var mytbl = $("#Table_id").datatable();
mytbl.ajax.reload;
.reload() is not working properly untill we pass some parameter
var = $("#example").DataTable() ;
datatbale_name.ajax.reload(null, false );
Try This i hope it will work
$("#datatable_id").DataTable().ajax.reload();
I'm using jQuery and django
I have a dynamic table generated by jQuery, which holds the email field and password field and the delete button that could remove the row:
$("button#genBtn").click(function() {
var t = $("input#inputEmail").val();
var p = $("input#inputPassword").val();
var delBtn = $('<button class=\"btn btn-danger\">delete</button>');
var row = $("<tr><td>" + t + "</td><td>" + p + "</td><td></td></tr>");
$('td:last', $(row)).append(delBtn);
$(delBtn).bind("click", deleteNode);
$("table tbody").append(row);
});
This is the table:
<table class="table table-striped">
<thead>
<tr>
<th>email</th>
<th>password</th>
<th>action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Let say I'd like to get the data of all rows from this table, and post it to sever side. How could I do that?
Without any additional libraries, something like this:
(1) get the data from the table
function getTableData()
{
// Array of data we'll return
var data = [];
// Counter
var i = 0;
// Cycle through each of the table body's rows
$('tbody tr').each(function(index, tr) {
var tds = $(tr).find('td');
// Check we've got two <td>s
if (tds.length > 1) {
// If we do, get their text content and add it to the data array
data[i++] = {
email: tds[0].textContent,
password: tds[1].textContent
}
}
});
return data;
}
(2) post it to the server
$.ajax({
method: 'post',
url: '', // Set the URL of whatever in Django will handle your post
data: getTableData()
});
However, if I were attempting this task, I would achieve (1) by using Knockout, which would allow for a much better separation between view and viewmodel (or between template and view, you might think of them, as a Django user). Great that you're using a decent server-side framework, would be a pity to end up with spaghetti code on the client!
Here is my code:
oTable2 = $('#BigData2').dataTable({
"bLengthChange":false,
"bPaginate":false,
"oLanguage": {
"sZeroRecords": "No records found"
},
"sAjaxSource":'StatusSrv',
// "sDom":'RCT<"clear">lfrtip',
//"aoColumnDefs":[{}]
})
var auto_refresh = setInterval(
function (){
$('#Status_Table').fadeOut('slow').load('SupplyPlanning.jsp
#oTable2.fnDraw()').fadeIn("slow");
}, 6000);
<div id="Status_Table" class="chartFloatLeftInner">
<table id="BigData2" >
<thead >
<tr>
<th><input type="checkbox" onClick="checkall()" name="maincheck" id="maincheck"/></th>
<th title="REQ_NO">REQ_NO</th>
<th title="Retailer Partner number">Retailer num</th>
<th title="STATUS">OVERALL_STATUS</th>
</tr>
</thead>
<tbody></tbody>
</table>
I want to refresh my datatable in a particular time interval so that I am using fndraw but it only redraws the table with the old data. If I insert new data in the database, the new data is not shown after refresh; it shows only the old data.
Probably you would need to add the "bDestroy": true attribute to your datatable code which allow you to rebuild it otherwise once created you can not load it with new data.
Try using append:
$('#Status_Table').append( your table in here);
It work for me
How can get a row's value on mouse click or checking the checkbox preferably from the below given html table?
Here is the js for getting values for my table from a xml using spry
var ds1 = new Spry.Data.XMLDataSet("xml/data.xml", "rows/row");
var pv1 = new Spry.Data.PagedView( ds1 ,{ pageSize: 10 , forceFullPages:true, useZeroBasedIndexes:true});
var pvInfo = pv1.getPagingInfo();
Here is the Div with spry region containing the table that gets populated from pv1 (see js part)
<div id="configDiv" name="config" style="width:100%;" spry:region="pv1">
<div spry:state="loading">Loading - Please stand by...</div>
<div spry:state="error">Oh crap, something went wrong!</div>
<div spry:state="ready">
<table id="tableDg" onclick="runEffect('Highlight', 'trEven', {duration: 1000, from: '#000000', to: '#805600', restoreColor: '#805600', toggle:true}, 'Flashes a color as the background of an HTML element.')"
style="border:#2F5882 1px solid;width:100%;" cellspacing="1" cellpadding="1">
<thead>
<tr id="trHead" style="color :#FFFFFF;background-color: #8EA4BB">
<th width="2%"><input id="chkbHead" type='checkbox' /></th>
<th width="10%" align="center" spry:sort="name"><b>Name</b></th>
<th width="22%" align="center" spry:sort="email"><b>Email</b></th>
</tr>
</thead>
<tbody spry:repeat="pv1">
<tr class="trOdd"
spry:if="({ds_RowNumber} % 2) != 0" onclick="ds1.setCurrentRow('{ds_RowID}');"
style="color :#2F5882;background-color: #FFFFFF">
<td><input type="checkbox" id="chkbTest" class = "chkbCsm"></input></td>
<td width="10%" align="center"> {name}</td>
<td width="22%" align="center"> {email}</td>
</tr>
<tr class="trEven" name="trEven" id="trEven"
spry:if="({ds_RowNumber} % 2) == 0" onclick="ds1.setCurrentRow('{ds_RowID}');"
style="color :#2F5882;background-color: #EDF1F5;">
<td><input type="checkbox" class = "chkbCsm"></input></td>
<td id="tdname" width="10%" align="center"> {name}</td>
<td width="22%" align="center"> {email}</td>
</tr>
</tbody>
</table>
</div>
</div>
I am trying the below code but still I am not getting the alert and hence none of the answers are also not working. I know the syntax n all are everything correct, but i am not able to figure out what is the problem here!
//inside $(document).ready(function()
$("#chkbHead").click(function() {
alert("Hi");
});
My page has other tables too for aligning some contents. So when I use the below code it works perfectly on those tables except the one in the question. It might be the problem because there are only 2 tr in the table which gets populated by a spry dataset and hence not getting identified properly. May be, I am not sure, just trying to help improve my understanding
$('tr').click(function() {
alert("by");
});
The values of a Row you will get with:
$('#tableDg tbody tr').live( 'click', function (event) {
$(this).find('td').each( function( index, item ) {
if ( $(this).has(':checkbox') ) {
alert( $(this).find(':checkbox').val() );
} else {
alert( $(this).text() );
}
};
});
What exactly do you mean by value of a table row? You can get the inner html of a table row like this:
var html = '';
$('tr').click(function() {
html = $(this).html();
});
You can get attributes of the table row (e.g. it's Id) like so:
var id = '';
$('tr').click(function() {
id = $(this).attr('id');
});
Alternatively you can get the value of nested elements such as a text input like so:
var text = '';
$('tr').click(function() {
text = $(this).find('#myTextBox').val();
});
EDIT
This is how to change the checked attribute of a checkbox nested in a table row:
$('tr').click(function() {
$(this).find('input:checkbox').attr('checked', 'checked');
// alternatively make it unchecked
$(this).find('input:checkbox').attr('checked', '');
});
EDIT
As the table rows are being loaded dynamically - the $().click() event binding method will not work, because when you are calling it - the table rows do not exist, so the click event cannot be bound to them. Instead of using $().click use the jQuery live method:
$('tr').live('click', function() {
// do stuff
});
This binds the click event to all current table rows and all table rows that may be added in the future. See the jQuery docs here
you have to use Spry Observer,
something like this:
function funcObserver(notificationState, notifier, data) {
var rgn = Spry.Data.getRegion('configDiv');
st = rgn.getState();
if (notificationState == "onPostUpdate" && st == 'ready') {
// HERE YOU CAN USE YOUR JQUERY CODE
$('#tableDg tbody tr').click(function() {
$(this).find('input:checkbox').attr('checked', 'checked');
// alternatively make it unchecked
$(this).find('input:checkbox').attr('checked', '');
});
}
}
Spry.Data.Region.addObserver("configDiv", funcObserver);