I have the following table element:
<table id="my-table" class="table table-striped table-hover ">Loading...</table>
I am dynamically creating the table inside of an ajax call, and then writing the data to the table:
<script>
$.ajax({
success:function(result){
$.getScript("table-sort-controller.js", function () {
sortTable("my-table")
}); //makes table sortable using DataTables
$.getScript("search-controller.js"); //makes table searchable using DataTables
},
url: "http://myserver:8080/url/"
}).then(function(data) {
var table = "<thead>";
table += createTableHeader(data); //fake method to simplify code
table += "</thead>";
table += "<tbody id='sortable-cells'>";
table += createTableBody(data); //fake method to simplify code
table += "</tbody>";
//This is the line where I try to clear "Loading...".
document.getElementById("my-table").innerHTML = table;
});
</script>
However, I am failing to remove "Loading..." from on top of the loaded table. I have tried the following in the line directly after my table creation:
document.getElementById("my-table").innerHTML = "";
document.getElementById("my-table").empty();
//a few other attempts I cannot remember
Some more info:
alert(document.getElementById("my-table")); //output is [object HTMLTableElement]
alert(document.getElementById("my-table").innerHTML); //output is empty alert
alert(document.getElementById("my-table").getCaption()); //console says "undefined is not a function"
I am unclear as to why getCaption() returns undefined, as it appears to be a function under W3C.
How can I remove "Loading..." after my table has finished loading and before I populate #my-table with the appropriate HTML? Alternatively, how can I removing "Loading..." immediately after writing my table?
Thanks to #Phylogenesis and #Paul Roub, fixed it!
I changed
<table id="my-table" class="table table-striped table-hover ">Loading...</table>
to
<table id="my-table" class="table table-striped table-hover "><tr><td>Loading...</td></tr></table>
Then I added following to remove my old "Loading...".
$('#my-table').empty();
Now it works. Thanks!
EDIT: In my particular case, I actually was able to remove the clearing call altogether, as I was overwriting the element in the very next line.
Related
I'm trying to display a table on a new page by calling an API and loading the data in the table. This page is loaded on click of a menuItem.
But the issue I'm facing is that the table is displaying, but not the data I'm intending to. I know that I'm able to fetch the data from the API since i can see that in the console log.
Here is the code:
In this first html file im clickling the menu and calling my next html page i want to load
and also im giving my id="covidLink" which im calling in my JS FILE.
pan.html
<div class="navbar">
<a class="covidText" id="covidLink" href="covidStatusUpdate.html">Covid-19</a>
</div>
In the below js file im making a call to the api and appending the data in tbody.
Fetchdata.js
$(document).ready(function () {
$("#covidLink").click(function () {
console.log("Link clicked...");
requestVirusData();
});
});
function requestVirusData() {
$.getJSON('https://api.covid19api.com/summary',
function(data){
var countries_list = data.Countries;
//console.log(countries_list);
$(countries_list).each(function(i, country_dtls){
$('#totalbody').append($("<tr>")
.append($("<td>").append(country_dtls.country))
.append($("<td>").append(country_dtls.TotalConfirmed))
.append($("<td>").append(country_dtls.TotalDeaths))
.append($("<td>").append(country_dtls.TotalRecovered)));
});
})
}
and lastly
statusUpdate.html
<table class="table table-striped table-bordered table-sm" cellspacing="0" width=80%>
<thead>
<tr>
<th>Country</th>
<th>TotalConfirmed</th>
<th>TotalDeaths</th>
<th>TotalRecovered</th>
</tr>
</thead>
<tbody id="totalbody">
</tbody>
</table>
What am I supposed to do ? I have to admit that I'm lost here.
I don't think you quite understand how AJAX works. You're handling a click on "covidLink". This does two things simultaneously.
it tells the browser to navigate away from the current page and go to statusUpdate.html instead.
it runs the requestVirusData() function. This gets the data from the API and returns it to the page.
But the problem is: the API call returns the data to the page where the script was called from - i.e. it returns it to pan.html. And you've just told the browser to move away from that page. Also, pan.html doesn't contain a table to put the returned data into.
The logical solution here is to link to fetchdata.js from statusUpdate.html instead, and tweak the code slightly so it runs when that page loads, rather than on the click of a button:
$(document).ready(function () {
console.log("page loaded...");
requestVirusData();
});
As suggested by ADyson i did changes in my code and now im able to display the table with data.
Here are my code changes:
statusUpdate.html
<tbody id="tbody">
<script>
var datatable;
fetch('https://api.covid19api.com/summary')
.then(function (response) {
return response.json();
})
.then(function (data) {
appendData(data);
})
.catch(function (err) {
console.log('error: ' + err);
});
function appendData(data) {
var countries_list = data.Countries;
var tbody = document.getElementById("tbody");
// clear the table for updating
$('table tbody').empty();
// hide the table for hidden initialize
$('table').hide();
// loop over every country
for (var i in countries_list) {
var country_dtls = countries_list[i];
// replace -1 with unknown
for (var o in country_dtls) {
if (country_dtls[o] == -1) country_dtls[o] = 'Unknown';
}
$('table tbody').append(`
<tr>
<td>${country_dtls.Country}</td>
<td>${country_dtls.TotalConfirmed}</td>
<td>${country_dtls.TotalDeaths}</td>
<td>${country_dtls.TotalRecovered}</td>
</tr>`);
}
}
// }
</script>
</tbody>
pan.html
<a class="covid" href="statusUpdate.html">Covid-19</a>
and now i do not need fetchdata.js obviously.
Hope this helps someone stuck like me :)
I've copied data of a html table on page 1 in an array obj(arrData). And i've save that arrData into the session storage. Now on page 2, how do i display the data from the arrData to the html table. New in JS. Thanks in advance
PAGE 1 JS
var arrData=[];
$("#checkout").on('click',function(){
$("#table tr").each(function(){
var currentRow=$(this);
var col1_value=currentRow.find("td:eq(0)").text();
var col2_value=currentRow.find("td:eq(1)").text();
var obj={};
obj.col1=col1_value;
obj.col2=col2_value;
arrData.push(obj);
sessionStorage.myArrData=JSON.stringify(arrData);
});
console.log(arrData);
});
PAGE 2
<table class="table table-checkout" id="table">
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
</tbody>
PAGE 2 JS
var arrData = JSON.parse(sessionStorage.myArrData);
You need to use sessionStorage.setItem("foo", 12) rather than sessionStorage.foo = 12;
The latter is attaching a new property to the javascript object, not talking to the browser session API. When the page reloads, the object you attached is gone.
To get the item back, use sessionStorage.getItem
Mozilla docs for sessionStorage including setItem and getItem
Once you've done that, you will need a way of creating new table rows in the table. There are a multitude of frameworks for this purpose, but you can also build tables (with a few more steps than with other elements) yourself
How to insert row in HTML table body in Javascript?
As I understand from above, You have data in array of objects after var arrData = JSON.parse(sessionStorage.myArrData);, in below format..
arrData:
[
{col1:"Item1", col2:"quantity1"},
{col1:"Item1", col2:"quantity1"},
...
]
Now to display this data on Page 2
var rows = "";
arrData.map((row)=>{
var row = '<tr><td>'+row.col1+'</td><td>'+row.col2+'</td></tr>';
rows = rows+row;
})
var tbody = document.queryselector('#table tbody');
tbody.innerHTML = rows;
I'm trying to edit a table by adding rows, but running into an issue with the the partial view not being fully rendered (This is my assumption)
I'm loading the partials into their divs via page load and ajax calls;
<div id="preTestSteps">
</div>
<div id="mainTestSteps">
</div>
<div id="postTestSteps">
</div>
Scripts;
$(document).ready(function() {
var testSuiteExecutionId = #(Model.TestSuiteExecutionId);
var testSuiteId = #(Model.TestSuiteId);
loadTestStepResultsPartialView(testSuiteExecutionId, testSuiteId, 1, "preTestSteps");
loadTestStepResultsPartialView(testSuiteExecutionId, testSuiteId, 0, "mainTestSteps");
loadTestStepResultsPartialView(testSuiteExecutionId, testSuiteId, 2, "postTestSteps");
});
function loadTestStepResultsPartialView( testSuiteExecutionId, testSuiteId, testStepType, divId) {
$.ajax({
type: 'POST',
url: '#Url.Action("DetailsTestStepResults", "TestSuiteExecutions")',
data: { 'testSuiteExecutionId': testSuiteExecutionId, 'testSuiteId': testSuiteId, 'testStepType': testStepType },
success: function(data) {
$("#" + divId).html(data);
}
});
In the partial view, the table has a unique ID which is accessed to append (view model is a list of viewmodels, using the first index is to get data which is unique for the list of logs);
<div id="#collapseStepItemName" class="collapse col-sm-12" role="tabpanel" aria-labelledby="headingOne">
<div class="card-body">
<table class="table" id="logTable_#Model[0].TestStepId#Model[0].MessageType">
<thead>
<tr>
<th width="5%"></th>
<th width="20% !important">Time</th>
<th width="75%">Message</th>
</tr>
</thead>
<tbody>
#foreach (var logEntry in Model)
{
<tr id="tableRow_#logEntry.TestStepId#logEntry.MessageType">
<td><img width="20" height="20" src="~/Content/Images/#HtmlUtilities.GetTestSuiteExecutionIconName(logEntry.LogType)" /></td>
<td><i>#logEntry.TimeStamp</i></td>
<td><i>#Html.Raw(HtmlUtilities.GetHtmlFormattedString(logEntry.Message))</i></td>
</tr>
}
</tbody>
</table>
</div>
The current test code (with hard coded tableID for the sake of testing) is the following;
var tableId = "logTable_" + 44 + "False";
var newRow = document.getElementById(tableId).insertRow();
newRow.innerHTML="<td>New row text</td><td>New row 2nd cell</td><td>Please work</td>";
The following error is thrown in the browser debug;
Uncaught TypeError: Cannot read property 'insertRow' of null
Is there a way to execute the script after the partial views are fully rendered? Or is this issue something else and not due to the views being loaded in?
I made sure the table appending script actually works by testing it on a table in the main view, and it worked as intended.
Since you're using jQuery, place this code inside document.ready function:
$(document).ready(function() {
// other stuff
var tableId = "logTable_" + #Model[0].TestStepId + #Model[0].MessageType;
var row = $('<tr>').append('<td>New row text</td><td>New row 2nd cell</td><td>Please work</td>');
$('#' + tableId).find('tbody').append(row);
});
If you insist using vanilla JS to add rows, make sure that all DOM objects are already loaded as given in example below:
document.addEventListener("DOMContentLoaded", function (ev) {
var tableId = "logTable_" + #Model[0].TestStepId + #Model[0].MessageType;
var newRow = document.getElementById(tableId).insertRow();
newRow.innerHTML="<td>New row text</td><td>New row 2nd cell</td><td>Please work</td>";
}
The reason behind insertRow has null value is that table DOM elements may not fully loaded when adding row script executes, hence row addition script should run when all required DOM elements are complete.
Demo example: JSFiddle
A user can search for people included in a database introducing the search terms in an input text.
I am using following Ajax script to show the database objects received from JSON:
<script type="text/javascript">
$(document).ready(function() {
// With JQuery
$("#ex6").slider();
$("#ex6").on("slide", function(slideEvt) {
$("#ex6SliderVal").text(slideEvt.value);
});
$('#keyword').on('input keyup change', function() {
var searchKeyword = $(this).val();
if (searchKeyword.length < 3) {
$('ul#content').empty()
}
if (searchKeyword.length >= 1) {
$.post('search.php', { keywords: searchKeyword }, function(data) {
$('#content').empty()
$('#content').append('<table class="table table-hover"><thead><tr><th>First Name</th><th>Last Name</th><th>Username</th></tr></thead><tbody>')
if (data == ""){
$('#content').append('No hay resultados para su búsqueda')
}
$.each(data, function() {
$('#content').append('<tr><td>'+this.nombre_doctor +'</td><td>'+ this.apellido1_doctor + '</td><td>'+ this.apellido2_doctor+'</td></tr>');
});
$('#content').append('</tbody></table>')
}, "json");
}
});
});
</script>
And this is the output when a user introduces a search term:
As you may see in the picture, the objects are not shown on the expected column.
What is wrong in the script?
When you call append with a string, jQuery constructs an object and appends that. In other words, append('<foo>') is really append($('<foo'>). The assumption in this code that append appends raw HTML is incorrect.
You want something like
var $table = $('<table class="table table-hover"><thead><tr><th>First Name</th><th>Last Name</th><th>Username</th></tr></thead></table>').appendTo('#content');
var $tbody = $('<tbody></tbody>').appendTo($table);
$.each(data, function() {
var $tr = $('<tr>').appendTo($tbody);
$('<td>').text(this.nombre_doctor).appendTo($tr);
$('<td>').text(this.apellido1_doctor).appendTo($tr);
$('<td>').text(this.apellido2_doctor).appendTo($tr);
});
// Nothing with </tbody></table> , those elements already exist
Note that your current code includes a significant vulnerability as it allows everybody who controls your data to inject arbitrary HTML and JavaScript into your website. The use of text avoids this.
You used a concate (+) function which packed all data into one column as a string. You should define 3 distinct columns to force a proper table layout.
<table width="100%" rules=groups border="0" cellspacing="0" cellpadding="0" class="table table-hover">
<colgroup>
<col width="33%" />
<col width="33%" />
<col width="33%" />
</colgroup>
Now you have a solid structure to insert your data, by column. The <th> will line up the way you have written the code.
Try building your table html as a string first, then use jquery's .html() to set it.
var htmlContents = "<table><tr><td>First column data</td><td>2nd column
data</td><td>etc</td></tr></table>";
$('#content').html(htmlContents);
That should do it.
I am creating a div dynamically in jQuery as mentioned in the below code appending to the form.
var temp = document.createElement("div");
temp.setAttribute("id", "test");
Form:
<form id="test1" method="get">
</form>
I am trying to have a table created dynamically and need to have this inside a table?
To form table dynamically:
var tableHeader = '<table border="1"> <thead> <tr><th>QueryName</th><th>Description</th><th>Modified Date</th></tr></thead><tbody>';
$("#test").prepend(tableHeader);
Now I need to have <td> (Which I need to create) inside which I need the div element I created. Like this:
<table>
...
....
<tr>
<td>
<div id="test"> // Div i created dynamically in the top(1st line)
</div>
</td>
</tr>
How do I achieve this in jQuery?
Why don't you create the table first?
and then append the table into the dom.
give an id to the td where you want to insert your div.
$('#td-id').html({div-content-goes-here}).
the html() function puts its contents inside the selected dom node.
you can also use append(),
Try the below code:
var temp = document.createElement("div");
temp.setAttribute("id", "test");
console.log(temp);
var tableHeader = '<table border="1"> <thead> <tr><th>QueryName</th><th>Description</th><th>Modified Date</th></tr></thead><tbody>';
$('body').append(tableHeader);
$('table').append(temp);
Also check this JSFiddle and share your thoughts.
To append the div to the td of the table, you must first have such a td. The code below checks its existence and adds it if it doesn't exist.
<form id="test1" method="get"></form>
JavaScript:
var tableHeader = '<table border="1"> <thead> <tr><th>QueryName</th><th>Description</th><th>Modified Date</th></tr></thead><tbody>';
$("#test1").prepend(tableHeader);
if ($('#test1 table tr td:first-child').size()==0) {
console.log('Table has no TDs. Creating a row.');
$('#test1 table tbody').append('<tr><td></td><td></td><td></td></tr>');
}
var temp = document.createElement("div");
temp.setAttribute("id", "test");
temp.appendChild(document.createTextNode('test Div Inserted'));
// appends the DIV to the first TD of the TABLE under #test1 FORM
$('#test1 table tr td:first-child').append(temp);
JSFiddle Demo.
#user2067567, here is a healthy approach, put an id on your dynamic table, before you append it to the DOM...
var tableHeader = '<table border="1" id="mtableid"> <thead> <tr><th>QueryName</th><th>Description</th><th>Modified Date</th></tr></thead><tbody>';
...Then make your base point for manipulating your new table from this ID...
var mtable = $('#mtableid');
...Then look for the tr row you want to enter...
var firstrow = mtable.find('tr').eq(1);
...Then append content to the first row...
$('<td><div>...</div></td>').appendTo(firstrow);
This is all untested, but posted just to give you a general idea.
Let me know if you want further details.
var temp = document.createElement("div");
temp.setAttribute("id", "test");
var tableHeader = '<table border="1"> <thead> <tr><th>QueryName</th><th>Description</th><th>Modified Date</th></tr></thead><tbody>';
$("#test1").prepend(tableHeader);
$('tr').append(temp);
$('div').html('create div content');
the answer to your question is quite simple but there is an important point that you've missed to explain. Which tr do you want to append to. Do you want to create a new tr for every div you want to append to the table or is there some other logic?