Bootstrap Datatable is no longer functioning after loading content via Ajax - javascript

Before some one says its a duplicate question, i know it is. I've just not been able to find anyone's script that looks similar to mine and as i'm completely new to JavaScript and JQuery (used to php) i don't really know what I'm doing.
My datatable worked perfectly having the data loaded using php (before the page had loaded) but now its loaded after the page load, the table has lost all of it's filtering and pagination.
Here is how my table is loaded.
<div class="table-responsive">
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<?php echo $tableheader;?>
</tr>
</thead>
<tfoot>
<tr>
<?php echo $tableheader;?>
</tr>
</tfoot>
<tbody id="data"> <!--data will be inputed here-->
</tbody>
</table>
</div>
This is the script that gets the data and puts it into the table.
<script>
//call ajax
var ajax = new XMLHttpRequest ();
var method = "GET";
var url = "data_assets.php";
var asynchronous = true;
setInterval(function(){
ajax.open(method, url, asynchronous);
//sending ajax request
ajax.send();
}, 250)
//receiving response from data_assets.php
ajax.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
//convert JSON back to array
var data = JSON.parse(this.responseText);
//console.log(data); //for debugging
//html value for <tbody>
var html ="";
//looping through the data
for (var a = 0; a < data.length; a++) {
var asset_number = data[a].asset_number;
var id = data[a].id;
var room = data[a].room;
var _location = data[a]._location;
var sku = data[a].sku;
var qty = data[a].qty;
var _value = data[a]._value;
var date = data[a].date;
var po_number = data[a].po_number;
var purchaced_from = data[a].purchaced_from;
var notes = data[a].notes;
var total = data[a].total;
//storing in html
html += "<tr>";
html += "<td style='vertical-align: middle;'>" + asset_number + "</td>";
html += "<td style='vertical-align: middle;'>" + id + "</td>";
html += "<td style='vertical-align: middle;'>" + room + "</td>";
html += "<td style='vertical-align: middle;'>" + _location + "</td>";
html += "<td style='vertical-align: middle;'>" + sku + "</td>";
html += "<td style='vertical-align: middle;'>" + qty + "</td>";
html += "<td style='vertical-align: middle;'>" + _value + "</td>";
html += "<td style='vertical-align: middle;'>" + total + "</td>";
html += "<td style='text-align: center; vertical-align: middle;'>" + date + "</td>";
html += "<td style='vertical-align: middle;'>" + po_number + "</td>";
html += "<td style='vertical-align: middle;'>" + purchaced_from + "</td>";
html += "<td style='vertical-align: middle;'>" + notes + "</td>";
html += "<td style='text-align: center; vertical-align: middle;'>";
html += "<a href='?id=" + id + "&room=" + room + "&asset=" + asset_number + "&location=" + _location + "&sku=" + sku + "&qty=" + qty + "&value=" + _value + "&date=" + date + "&po=" + po_number + "&where=" + purchaced_from + "&notes=" + notes + "#editModal' class=''><i class='far fa-edit fa-lg'></i></a>";
html += "</td>";
html += "<td style='text-align: center; vertical-align: middle;'>";
html += "<a href='?id=" + id + "&room=" + room + "&asset=" + asset_number + "&location=" + _location + "&sku=" + sku + "&qty=" + qty + "&value=" + _value + "&date=" + date + "&po=" + po_number + "&where=" + purchaced_from + "&notes=" + notes + "#duplicateModal' class=''><i class='far fa-clone fa-lg'></i></a>";
html += "</td>";
html += "</tr>";
}
//replacing the <tbody>
document.getElementById("data").innerHTML = html;
}
}
</script>
If anyone could show me how to get this working in my example it would be greatly appreciated, I really want to load all of my tables on this site like this so i dont need to have a refresh on saving data (This refreshes every 250ms so the data in the table is always up to date with the database).
Update:
Right i took out my 250ms refresh and now the table works perfectly! is anyone now able to help me with my next issue. How do i get the table to refresh when new data is entered into the database, without refreshing the whole page

I suggest creating the table structure in HTML or PHP (not Javascript). Then load the data into the table with ajax. Those DOM elements are not readily available to javascript unless the event to create the elements is bound to an element that already exists like body or document or some other parent element of the table.
UPDATE:
I personally don't have much experience with DataTables plugin. So the plugin will automatically create your DOM elements (table structure) based on either the data object returned from ajax or by properties you specify. DataTables does use jQuery's ajax() method to make ajax calls however you should not override the success callback. There is a proper way to use their API when making ajax calls as specified in the documentation. There is also a proper way to reload data on an interval to refresh your tables.
Please check out this fiddle.
The ajax url, method, data properties must of course be updated to fit your application (this was the only way to simulate ajax call on jsFiddle. Please note you will have to have properly formatted JSON.

Did you tried to explicitly set pagelength property on Datatables?
$('#datatable').dataTable( {
"pageLength": 50
} );

Related

splice in javascript change values of my other objects

NOTE! this is for an extra credit assignment, so I am not looking for code re-write but rather guidance in what I am doing wrong. I have gone through my code several times and I feel like I am just missing something very minor. I have completed it fully with the exception of the following error:
I created an array of objects.
Everything starts off fine. I can create objects and they are added to the array and successfully displayed on my screen with correct values.
The trouble arises when I delete an object from the array. It does delete this object and removes it from my displayed list, but suddenly all the remaining objects get new values. These new values match those of the LAST object I added to the array. I need them to retain their original values!
var tableContent = document.getElementById("tableContent");
var tableString = " ";
var counter = 0;
var courseArray = [];
tableContent.innerHTML = tableString;
function Course(number, title, hours, prereq) {
this.number = number;
this.title = title;
this.hours = hours;
this.prereq = prereq;
}
function createCourse() {
var number = document.getElementById("number-field");
var title = document.getElementById("title-field");
var hours = document.getElementById("hours-field");
var prereq = document.getElementById("prereq-field");
courseArray.push(new Course(number, title, hours, prereq));
buildCourseTableBody();
}
function buildCourseTableBody() {
tableString += "<tr>" +
"<td>" + counter + "</td>" +
"<td>" + courseArray[counter].number.value + "</td>" +
"<td>" + courseArray[counter].title.value + "</td>" +
"<td>" + courseArray[counter].hours.value + "</td>" +
"<td>" + courseArray[counter].prereq.value + "</td>" +
"<td><button id='delete' onClick='deleteCourse(" + counter + ")'><img id=counter src='../image/delete.png' alt='delete course'></button></td>" +
"</tr>";
counter++;
tableContent.innerHTML = tableString;
}
function deleteCourse(counterIndex) {
courseArray.splice(counterIndex, 1);
counter--;
tableString = "";
for (var i = 0; i < courseArray.length; i++) {
tableString += "<tr>" +
"<td>" + i + "</td>" +
"<td>" + courseArray[i].number.value + "</td>" +
"<td>" + courseArray[i].title.value + "</td>" +
"<td>" + courseArray[i].hours.value + "</td>" +
"<td>" + courseArray[i].prereq.value + "</td>" +
"<td><button id='delete' onClick='deleteCourse(" + i + ")'><img id=counter src='../image/delete.png' alt='delete course'></button></td>" +
"</tr>";
}
and HTML code(everything in main, which is wrapped in body. js file is included):
<main id="main-index">
<h1 id="page-caption">CS Department Course Catalog</h1>
<div id="course-list">
<p id="course-list-caption">Course List</p>
<table>
<thead>
<tr>
<th>Count</th>
<th>Number</th>
<th>Title</th>
<th>Hours</th>
<th>Prereq</th>
<th>Action</th>
</tr>
</thead>
<tbody id="tableContent">
</tbody>
</table>
</div>
<div id="course-edit">
<p><input id="number-field" placeholder="Course #, e.g. CS234"></p>
<p><input id="title-field" placeholder="Course title, e.g. Database and Wed Systems Development"></p>
<p><input id="hours-field" placeholder="Credit hours, e.g. 3.0"></p>
<p><input id="prereq-field" placeholder="Course prereqs, e.g. CS150, CS111"></p>
<p><button id="add" onClick="createCourse()">+</button></p>
</div>
</main>
Your error is in createCourse. You are assigning the HTML-Elements instead of their value.
function createCourse() {
var number = document.getElementById("number-field").value;
var title = document.getElementById("title-field").value;
var hours = document.getElementById("hours-field").value;
var prereq = document.getElementById("prereq-field").value;
courseArray.push(new Course(number, title, hours, prereq));
buildCourseTableBody();
}
The class course will hold a reference to the element itself. Like that your functions which generate the table itself, will always get the most current value of the input boxes.
Notice:
Don't forget to adapt buildCourseTableBody and deleteCourse.

Issue regarding ajax and identifying data from a table

I'm desperately trying to gain access to the $BarcodeID by pressing the DELETE button on my site. All I want to do is retreive this 13 digit number, so that I can use it to remove that row from the item Database (Sql).
I know that as long as I get the correct row I can get the data but i'm wondering if thats even possible because I'm building the table inside a $.post().
Please note that before i started trying to make the button and get the barcodeID in the click function all of the code was working. Thanks!
$(document).ready(function(){
$.get("../php/security.php", function(response){
if(response.result == "failure"){
location.href='../user_login.html';
} else {
$("#header").load("../header_logout.html");
$.post("../php/item_database.php", {email1:response.data.authUser}, function(indata){
indata.items.forEach(function(element){
$BarcodeID = element.BarcodeID;
$UserID = element.UserID;
$ProductName = element.ProductName;
$BrandName = element.BrandName;
$Weight = element.Weight;
$row = "<tr><td id='rowbarcode'>" + $BarcodeID + "</td>" + "<td>" + $ProductName + "</td>" + "<td>" + $BrandName + "</td>" + "<td>" + $Weight + "</td>" + "<td>" + "<button class='delete'>Delete</button>" + "</td></tr>";
$("#final_row").before($row);
});
}, "json");//eo post
} //eo else
}, "json"); //eo get
$(".delete").click(function(){
// var BarcodeID = $(this).closest('tr').find('#rowbarcode').val();
var BarcodeID = $(this).parent().find("#rowbarcode").text();
var $row = $(this).closest("tr"); // Finds the closest row <tr>
var $tds = $row.find("td:nth-child(1)"); // Finds the 2nd <td> element
console.log($tds);
//all I want is $BarcodeID
});
});//eof
Image of table on site:
Just for anyone who's interested I found a pretty neat way of solving my problem. Thanks to everyone who helped #Pointy #Taplar #Andreas. What I needed was 'event binding on dynamically created elements'. It is particularly useful when linked with $.post and $.get operations as they complicate data retreival.
Sample output to console:
5000157024671 <- if i clicked the first delete button
6221033101517 <- if i clicked the second delete button
Next stage:
As this is only a reference to a barcode number which has to be removed from the DB I will now pass this onto php via a post operation.
Next part of my project (adding a row search feature) can be found here:
Dynamically created table queries
Sample solution code:
$(document).ready(function(){
$.get("../php/security.php", function(response){
if(response.result == "failure"){
location.href='../user_login.html';
} else {
$("#header").load("../header_logout.html");
//from here down is the relevant code
$.post("../php/item_database.php", {email1:response.data.authUser}, function(indata){
indata.items.forEach(function(element){
$BarcodeID = element.BarcodeID;
$UserID = element.UserID;
$ProductName = element.ProductName;
$BrandName = element.BrandName;
$Weight = element.Weight;
$row = "<tr class='row'><td class='rowbarcode'>" + $BarcodeID + "</td>" + "<td>" + $ProductName + "</td>" + "<td>" + $BrandName + "</td>" + "<td>" + $Weight + "</td>" + "<td>" + "<button class='delete'>Delete</button>" + "</td></tr>";
$("#final_row").before($row);
});
}, "json");//eo post
} //eo else
}, "json"); //eo get
$(".contenttable").on('click', '.delete', function(){
var BarcodeID = $(this).closest('tr').find('.rowbarcode').text();
console.log(BarcodeID);
});
});//eof

J Query pagination plugin not working for dynamically added rows in html table

I'm spending for more than 6 hours for this issue. it would be better, if any one help me to solve this issue.
I'm trying to use jquery pagination plugin in dynamically added html table. But its not working. it gives exception. however its working fine for static html table.
Here is my code
<link href="../assets/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="../assets/js/jquery.dataTables.min.js.js"></script>
<table id="productTable" >
<thead class="alert-info text">
<tr>
<th><strong>Edit</strong></th>
<th><strong>Product Name</strong></th>
<th><strong>Introduction Date</strong></th>
<th><strong>URL</strong></th>
<th><strong>Delete</strong></th>
</tr>
</thead>
Jquery is
function bindDate(res) {
var d = res;
$("#productTable tbody").remove();
if ($("#productTable tbody").length == 0) {
$("#productTable").append("<tbody></tbody>");
}
if (d != null) {
for (var i = 0; i < d.length; i++) {
$("#productTable tbody").append(
"<tr>" +
"<td onclick='edit(this);' data-toggle='modal' data-target='#myModal'>" + "<img src='../assets/imgs/edit.ico' Height='30' Width='30'/>" + "</td>" +
"<td style='display:none;'>" + d[i].ID + "</td>" +
"<td>" + d[i].ProductName + "</td>" +
"<td>" + d[i].IntroDate + "</td>" +
"<td>" + d[i].URL + "</td>" +
"<td onclick='pdelete(this);'>" + "<img src='../assets/imgs/delete.png' Height='30' Width='30'/>" + "</td>" +
"</tr>"
);
}
}
$('#productTable').DataTable();
}
that is happening because jQuery events are not bound to dynamically added elements by default.. You need to use a concept called Event Delegation where you will have to have to make sure the table is dynamically added to a static element so u can use it as a reference.
$('body').on('event', '#productTable', function(event){
//Replace event with the right event, like click or something...
});
Find out more here Event Delegation and .on() Method. Also do some googling hope this helps

JQuery Drag and Drop from two tables

I need to implement drag and drop feature form one table to another and vise versa.
This is my function where i get transactions to particular IBAN number, I also have the same function which retrieves users transaction which are hidden.
function getAllTransactions(iban) {
var iban = $("#ibanSelection").val();
var username = $("#hiddenusername").val();
var url = 'http://localhost:64300/api/BankAccountApi/GetUserTransaction/?iban=' + iban;
var table = "<table id=\"table1\">";
if ((username != "") && (iban !="")) {
$.getJSON(url, function (data) {
table += "<tr class=\"ibanSelection\">";
table += "<th>My IBAN</th>";
table += "<th>Send to IBAN</th>";
table += "<th>Transfer Date</th>";
table += "<th>Amount</th>";
table += "</tr>";
$.each(data, function (key, val) {
table += "<tr class=\"draggable_tr\">";
table += "<td>" + val.My_Iabn + "</td>";
table += "<td>" + val.Iban_To + "</td>";
table += "<td>" + val.Transfer_Date + "</td>";
table += "<td>" + val.Amount_Transferd + "</td>";
table += "</tr>";
});
table += "</table>";
$("#divResult2").html(table);
});
}
}
Just use the jQueryUI Sortable feature.
Here's the complete example + documentation. Very easy.
Also this example shows your case:
http://jqueryui.com/sortable/#connect-lists

Working with JSON input

I'm trying to get a JSON input with AJAX and load it in a select control.
but when I run it :\ It stuck on "Downloading the recipes....".
anyone see the problem maybe? (I tried couple of changes but nothing work so far)
1 more issue can anyone think on a shorter way to do the
ConvertToTable(targetNode)
cuse it's way to long and complex, I think :\
<script type="text/javascript">
function loadXMLDoc() {
var xmlhttp;
document.getElementById("span").style.visibility = "visible";
document.getElementById("span1").style.visibility = "hidden";
document.getElementById("button").style.visibility = "hidden";
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
result = xmlhttp.responseText;
result = eval('(' + result + ')');
txt = "<select onchange='ShowRecipeDetails(this)'>";
for (i = 0; i < result.length; i++) {
txt = txt + "<option VALUE=" + result[i].recipe + ">" + result[i].recipe + "</option>";
}
txt = txt + "</select >";
document.getElementById("span").style.visibility = "hidden";
document.getElementById("span1").style.visibility = "visible";
document.getElementById("myDiv").innerHTML = txt;
}
}
xmlhttp.open("POST", "http://food.cs50.net/api/1.3/menus?meal=BREAKFAST&sdt=2011-03-21&output=json", true);
xmlhttp.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xmlhttp.send();
}
function ShowRecipeDetails(event) {
// get the index of the selected option
var idx = event.selectedIndex;
// get the value of the selected option
var field = event.options[idx].value;
$.ajax({
type: "GET",
url: "http://food.cs50.net/api/1.3/recipes?&output=json&id=" + field,
success: function (data) {
$("#TableDiv").html(ConvertToTable(data[0]));
}
});
}
function ConvertToTable(targetNode) {
var table = "<table border = 1 borderColor =green>";
table += "<tr>";
table += "<td>" + "ID" + "</td>";
table += "<td>" + targetNode.id + "</td>";
table += "</tr>";
table += "<td>" + "Ingredients:" + "</td>";
table += "<td>" + targetNode.ingredients + "</td>";
table += "</tr>";
table += "<td>" + "Name:" + "</td>";
table += "<td>" + targetNode.name + "</td>";
table += "</tr>";
table += "<td>" + "Size:" + "</td>";
table += "<td>" + targetNode.size + "</td>";
table += "</tr>";
table += "<td>" + "Unit" + "</td>";
table += "<td>" + targetNode.unit + "</td>";
table += "</tr>";
table += "<td>" + "VEGETARIAN:" + "</td>";
table += "<td>" + targetNode.VEGETARIAN + "</td>";
table += "</tr>";
table += "</tr>";
table += "</table>"
return table;
}
</script>
and the HTML:
<button id="button" type="button" onclick="loadXMLDoc()" >Get all recipes</button>
<br />
<span id="span" style="visibility:hidden">Downloading the recipes....</span>
<span id="span1" style="visibility:hidden">Please choose a recipe ID to view</span>
<div id="jsonDiv"></div>
<div id="myDiv"></div>
<div id="TableDiv"></div>
The HarvardFood API also supplies a JSONP version. So if you change your URL to this:
http://food.cs50.net/api/1.3/menus?meal=BREAKFAST&sdt=2011-03-21&output=jsonp&callback=parseResponse
you can create a parseResponse function to handle the data that comes back, and you can do the AJAX by inserting a script tag.
The problem is that you're running afoul the Same Origin Policy.
I see that you've updated the question to use jQuery AJAX. That offers a jsonp data type, which might be easier than adding a script tag.

Categories