Jquery methods won't add HTML to DOM - javascript

I was trying to add data to my existing table using Jquery's append(), but for some reason it did not work. I found another way to solve this problem, but I was wondering why this solution did not work. Could anyone explain it to me?
JS Code:
$(document).ready(function(){
var mapItems=new Map();
mapItems.set("firstName", "First Name");
mapItems.set("lastName", "Last Name");
mapItems.set("dob", "Date of Birth");
mapItems.set("gender", "Gender");
mapItems.set("idnumber", "ID Number");
mapItems.set("occupation", "Occupation");
mapItems.set("ethnicity", "Ethinicity");
function viewAllItems(data){
var info="";
for(var x=0; x<data.length;x++){
info+="<th>";
for(var key of mapItems.keys()){
var added=data[x][key];
added="<tr>"+added;
added+="</tr>";
info+=added;
}
info+="</th>";
}
return info;
}
$("#viewAll").on('click', function(){
$.ajax({
url:"A_URL_THAT_RETURNS_DATA",
type: "GET",
success:function(data) {
$("#tableViewAll").children().remove();
$("#tableViewAll").append(viewAllItems(data));
}
});
});
});
HTML
<button id="viewAll">View All</button><br>
<table id=tableViewAll>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Date of Birth</th>
<th>Gender</th>
<th>ID number</th>
<th>Occupation</th>
<th>Ethnicity</th>
</tr>
</table>
After console.logging viewAllItems(data), I got a proper HTML string back as a result, here it is:
<th><tr>sdfsdf</tr><tr>asdfasd</tr><tr>2006-03-04</tr><tr>male</tr> <tr>234234234</tr><tr>sadf</tr><tr>hispanic</tr></th><th><tr>John</tr><tr>Smith</tr><tr>1997-05-23</tr><tr>male</tr><tr>456456456</tr><tr>Garbageman</tr><tr>asian</tr></th><th><tr>aasd</tr><tr>asdfffe</tr><tr>2009-06-07</tr><tr>male</tr><tr>789789789</tr><tr>dfhdfbfdgb</tr><tr>hispanic</tr></th>
The information inside doesn't make any sense(on purpose) and is formatted poorly, but I just wanted to show that I get a proper HTML string back as a response.
Thus, my append method should append this string into the table. However, it does not do so.
Any help would be greatly appreciated. I just want to understand why it didn't work the way I thought it would.
P.S. I realize that I'm deleting my table headings, that's to be fixed. Also, I realized i'm using the th tag when I shouldn't be, but I'll also fix that later

The generated table row is wrapped in a TH. Also there is no TD present inside TR. Please correct that and the code should work fine.

Related

Assign id's (1,2,..etc) to a dynamic html table

Trying to achieve functionality in the linked picture.
The table grows as users click on the add button. I'm trying to replace the text inside the first column of the newly added td with the length of the table. I'm new to jQuery and not sure how to do that. Any help would be great.
It will be easier to answer you with your code but you can know the added row number with $('#yourTBodyID > tr').length
Have a look to this code :
HTML
<table>
<thead>
<tr>
<th>Zone ID</th>
<th>Zone Description</th>
<th><button onclick="addRow();">Add Row</button></th>
</tr>
</thead>
<tbody id="tableBody">
</tbody>
</table>
JS :
function addRow() {
var rowNum = $('#tableBody > tr').length + 1;
$('#tableBody').append('<tr>'
+ '<td>' + rowNum + '</td>'
+ '<td><input type="text"/></td>'
+ '<td><button>Disable</button></td>'
);
}
jsFiddle
Hope it helps ;)
You'll face a few more problems, more than just showing the number on the recently created tr. As you don't write down any code, I'm note sure at which point of the development you are, or which functionalities have you created already. I'll briefly try to explain how to achieve it, just showing you the path.
Add button should find in the DOM a valid <tr>to .clone(). It could be a "seen tr" or a template one. In the first situation you should clean the information in the input.
Once you have saved that cloned node into a variable, you should prepare it for insertion.
Counting the <tr> lines (it'd help if you have a classname on them) and assign the .length() to the first <td> using .text()
Changing name attribute on the input inside the second <td>tag. Otherwise when the form is sent to the server, you will loose every input with the same name which prior the last one.
On the last <td> tag you have a disabled button. It won't have any attached event on your brand new element. You can attach it here, or if you prefer, you can add the event on the very beginning using something like $('table').on('click','.disable-button',function(e){}). Doing that instead of $(.disable-button).click() will assure you that elements with this class created after DOM .ready()fires up will get this event.
I hope it helped you

Why doesn't this Javascript code execute sequentially?

Using jQuery I'm doing a call to my server which returns some json. I then have a callback defined using .done to create a callback, which doesn't seem to behave sequentially.
I've got a div in my html (<div id="properties"></div>), and I try to fill that div with a table of results:
request.done(function(data){
if (data['result'].length == 0) {
$("#properties").html("<h3>No results were found..</h3>");
} else {
$("#properties").html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody>");
data['result'].forEach(function(prop){
$("#properties").append("<tr>");
$("#properties").append("<td>prop.status</td>");
$("#properties").append("<td>prop.title</td></tr>");
});
$("#properties").append("</tbody></table>");
}
});
The result I get is this:
<div id="properties">
<table class="table table-hover"><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>
<tr></tr>
<td>prop.status</td>
<td>prop.title</td>
</div>
I know that .done is only called once the ajax call returns something, but withint that call, it should behave sequentially right? There are 2 things I really really don't understand here:
Why do the table row and data get written after the </table> tag?
And why on earth does the <tr></tr> gets written before the <td> tags, even though the last </tr> is appended together with the last <td> in the lastappend()` in the foreach loop?
So I also tried appending the whole table row in one go:
$("#properties").append("<tr><td>prop.status</td><td>prop.title</td></tr>");
This works a bit better, but still only produces this:
<div id="properties">
<table class="table table-hover"><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>
<tr><td>prop.status</td><td>prop.title</td></tr>
</div>
Javascript has puzzled me before, but this really blows my mind. Any tips are welcome!
What you are seeing here are tags closing out on you, because those elements are getting created in whole on append/html. In order to get the behavior you're expecting build in a string, say something more like this:
request.done(function(data){
if (data['result'].length == 0) {
$("#properties").html("<h3>No results were found..</h3>");
} else {
var propertiesTableHTML = "<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody>";
data['result'].forEach(function(prop){
propertiesTableHTML += "<tr>";
propertiesTableHTML += "<td>" + prop.status + "</td>";
propertiesTableHTML += "<td>" + prop.title + "</td>";
propertiesTableHTML += "</tr>";
});
propertiesTableHTML += "</tbody></table>";
$("#properties").html(propertiesTableHTML);
}
});
You are expecting .html() and .append() to work like document.write() but they don't. When used with HTML, they expect proper HTML. Broken HTML (for example missing end tags) is corrected which leads to the unexpected behavior. This part of your code for example:
$("#properties")
.html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody>");
Produces the following result:
<table>
<thead>
<tr>
<th>Status</th>
<th>Title</th>
</tr>
</thead>
<tbody>
</tbody><!-- tag closed automatically -->
</table><!-- tag closed automatically -->
Along the same lines, this code:
$("#properties").append("<tr>");
$("#properties").append("<td>prop.status</td>");
$("#properties").append("<td>prop.title</td></tr>");
Produces the following result:
...
</table>
<tr></tr><!-- tag closed automatically -->
<td>prop.status</td>
<td>prop.title</td><!-- </tr> ignored -->
One possible solution is to revise your code like this:
$("#properties").html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>");
data['result'].forEach(function(prop){
var $tr = $("<tr></tr>").appendTo("#properties > table > tbody");
$("<td></td>").text(prop.status).appendTo($tr);
$("<td></td>").text(prop.title).appendTo($tr);
});
You can't add tags to the DOM, you can only add elements. When you try to add a <table> tag, it will add a complete table element. When you try to add the ending tag, it will be ignored (or possibly cause an error, depending on the browser) because it's not code that can be parsed into an element.
Rewrite the code to add elements instead of tags:
$("#properties").html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>");
var tbody = $("#propertis tbody");
data['result'].forEach(function(prop){
var row = $("<tr>");
row.append($("<td>").text(prop.status));
row.append($("<td>").text(prop.title));
tbody.append(row);
});
By creating table cells as elements and use the text method to set the content, you avoid the problem with any special characters that would need HTML encoding (e.g. <. >, &) to mess up the HTML code.

Copy HTML Table to Text Box Using JQuery/JS

My problem has left me trying many solutions and stumped for a while now. My problem is exactly this:
There's a HTML table and a button on a page. Upon pressing the button, a script will run, copying the contents of the cells in the table into a text box. Here is the code for the table:
<table>
<tr><th></th><th>Category1</th></tr>
<tr><td>1.</td><td class="rule">Rule1</td></tr>
<tr><td>2.</td><td class="rule">Rule2</td></tr>
<tr><th></th><th>Category2</th></tr>
<tr><td>3.</td><td class="rule">Rule3</td></tr>
<tr><td>4.</td><td class="rule">Rule4</td></tr>
<tr><th></th><th>Category3</th></tr>
<tr><td>5.</td><td class="rule">Rule5 </td></tr>
<tr><td>6.</td><td class="rule">Rule6</td></tr>
<tr><td>7.</td><td class="rule">Rule7</td></tr>
<tr><th></th><th>Category4</th></tr>
<tr><td>8.</td><td class="rule">Rule8</td></tr>
</table>
My first thoughts were to write a script that iterated through the table and copied the contents of each cell (and creating a new line after every 2 cells). I realized very quickly, that I had no idea how to do that. After some searching I was able to come up with a script that clones the table, and it actually works quite well. This code is here:
$("button").click(function () {
$("table").clone().appendTo(".copy");
});
There are two problems that arise from using this method, however. I want plaintext, not a carbon copy of the table. The other problem is that this method only works when I clone the table into a div, it will not work when I try to clone it to a text box.
I've searched for a while for something similar to this and can only find solutions to copying single rows or cells. I had originally started there but couldn't figure out a way to write a loop that started at the beginning of the table and iterated through the entire thing, copying the contents as it iterated row by row (and creating a new line with each new row that it encountered). The loop would obviously end when there were no more rows to iterate through... This all sounds so simple to do, I know there must be a way.
Please Note: This script will be applied to a Site.Master Page so the script must be able to run for a plethora of tables. All of the tables follow the same structure shown above, but some will have more rows than others.
Any ideas? Any help is greatly appreciated.
You could use the .each() JQuery Method:
JS
function cloneTableContents()
{
$("table tr").each(function()
{
$(this).children().each(function()
{
$(".copy").append($(this).text());
});
});
}
JS For All Tables On Page In Order
function cloneTableContents()
{
$("table").each(function()
{
$(this).find("tr").each(function()
{
$(this).children().each(function()
{
$(".copy").append($(this).text()+" ");
});
});
});
}
HTML
<table id="mine">
<tr><th></th>
<th>Category1</th>
</tr>
<tr><td>1.</td><td class="rule">Rule1</td></tr>
<tr><td>2.</td><td class="rule">Rule2</td></tr>
<tr>
<th></th>
<th>Category2</th>
</tr>
<tr><td>3.</td><td class="rule">Rule3</td></tr>
<tr><td>4.</td><td class="rule">Rule4</td></tr>
<tr>
<th></th><th>Category3</th>
</tr>
<tr><td>5.</td><td class="rule">Rule5 </td></tr>
<tr><td>6.</td><td class="rule">Rule6</td></tr>
<tr><td>7.</td><td class="rule">Rule7</td></tr>
<tr>
<th></th><th>Category4</th>
</tr>
<tr><td>8.</td><td class="rule">Rule8</td></tr>
</table>
<textarea class="copy"></textarea>
<button onclick="cloneTableContents('mine','.copy');">Copy</button>
Working Example:
http://casewarecomputers.com:8088/soHelp.html

Javascript works in a href but not in JS file

Hope everyone is fine. Well I have a weird question, something that I'm missing or failing to understand. Hope anyone here can help me out. Well here goes,
Well I have an html page where I've defined a table with a few hard-coded values as below,
<table id='data-table' class='someClass'>
<thead>
<tr>
<th id="name-title">NAME</th>
</tr>
</thead>
<tbody>
<tr class="odd"><th class='c1'>Zachary Quinto</th></tr>
<tr class="even"><th class='c1'>Penny</th></tr>
<tr class="odd"><th class='c1'>Glen McGrath</th></tr>
</tbody>
</table>
Now I have a javascript file in which, somewhere down the code (Using jQuery), I do this,
$('#data-table').click(function() {
var value = $(this).find("th.c1").text();
if(value == "Zachary Quinto")
someFunc.showData('data-table', 1);
});
And for some reason this doesn't work, it goes over this function and I don't see any change/effect. However, to my amazement, If, when encapsulating my data into tags, it seem to work. (By encapsulating, I mean something like below)
<tr class="odd"><th class='c1'>Zachary Quinto</th></tr>
<tr class="even"><th class='c1'>Penny</th></tr>
<tr class="odd"><th class='c1'>Glen McGrath</th></tr>
Can anyone please help me with this, I'm not really sure what I'm doing wrong in Javascript file which doesn't let me do this. It's kind of weird as I thought both mean the same thing one way or another.
Thanks a lot for your time.
Because something is wrong with your script.
You should write it as:
"use strict";
$('#data-table').on("click", "th", function(e) {
e.preventDefault();
var value = $(this).text();
if(value == "Zachary Quinto")
someFunc.showData('data-table', 1);
});
jQuery's text function returns the combined text of all matching elements. In your case, there are three th.c1 matches, so the text() function returns Zachary QuintoPennyGlen McGrath.
You can see this by throwing a breakpoint on your event handler in a debugger.

Ordering of Columns in html using javascript or jquery

I am facing a problem on getting a solution on Ordering of Columns. I have used many 3rd party libraries like danvk library,jqGrid for dragging the columns. But what i want to do is. I have a div and have five fields in it. {FirstNJame,LastName,Address,Phone,Designation} also having up and down button so that i can move the fields up and down. On the Ok button, I want to have my table order according the order of fields which i have set on that div. so in short, change in thead and tbody, of what kind of order has been set in that div. Ihave programmed up and down, back and forward. I just need a solution to move the column position in javascript or in jquery. Thanks.
This should get you going: http://jsfiddle.net/S9ykD/
The code (using jQuery):
var order = [0,2,1,3];
$(function() {
$("table tr").each(function() {
var orderedTds = new Array();
for (var i=0; i<order.length;i++)
orderedTds[i] = $(this).children("td")[order[i]];
for (var i=0; i<order.length;i++)
$(this).append(orderedTds[i]);
});
});
this is the sample markup :
<table>
<tr>
<td>aaa</td>
<td>bbb</td>
<td>ccc</td>
<td>ddd</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
</table>
Just use some js library - I recommend to use Datatables, which is very nice and you can accomplish almost everything and is very cusotmizable. Or use whatever you are used to. Then just handle the click event on the button and send the configuration to the library. This can be done pretty well with Datatables. See fnSort or fnSortListener in the Datatables API doc.

Categories