JS and DOM, trying to create table - javascript

I tried to create table but I can't create td in every tr, td is creating only in first td what is in table, how I can solve the problem?
// Creating div
var main = document.createElement("div")
main.innerHTML = ""
document.body.appendChild(main)
main.setAttribute("id", "main")
//Creating Icons
var puzzleico = document.createElement("div")
puzzleico.innerHTML = ""
document.getElementById("main").appendChild(puzzleico)
puzzleico.setAttribute("id", "puzzleico")
var puzzleico = document.getElementById("puzzleico").onclick = function() {createtable()};
//Creating tr and td
function createtable() {
//Creating Table
var table = document.createElement("table")
table.innerHTML = ""
document.body.appendChild(table)
table.setAttribute("id", "table")
for (var i = 0; i < 50; i++) {
var tr = document.createElement("tr")
tr.innerHTML = ""
document.getElementById("table").appendChild(tr)
tr.setAttribute("id", "tr")
var td = document.createElement("td")
td.innerHTML = ""
document.getElementById("tr").appendChild(td)
}
}

Element id's within a document need to be unique. The issue here is that your document.getElementById("tr") will always return the first element it finds with that id and so, all of your <td> elements will be appended to the first <tr>.
In order to fix it you can remove the tr.setAttribute("id", "tr") line and use the already existing tr variable to append the td child to.
function createtable() {
//Creating Table
var table = document.createElement("table")
table.innerHTML = ""
document.body.appendChild(table)
table.setAttribute("id", "table")
for (var i = 0; i < 50; i++) {
var tr = document.createElement("tr")
tr.innerHTML = ""
document.getElementById("table").appendChild(tr);
var td = document.createElement("td");
td.innerHTML = "test"
tr.appendChild(td)
}
}
createtable();
The above code will work, but using the already declared variables instead of finding them again can also be applied to the table case. Also, table.innerHTML = "" doesn't add any value because the innerHTML is already empty when you create a new element.
function createtable() {
//Creating Table
var table = document.createElement("table");
document.body.appendChild(table);
for (var i = 0; i < 50; i++) {
var tr = document.createElement("tr");
table.appendChild(tr);
var td = document.createElement("td");
td.innerHTML = "test";
tr.appendChild(td);
}
}

You can use this to create the table:
function createTable(){
//Creating And Appending Child
let table = document.createElement('table');
document.body.appendChild(table);
for(let i = 0; i < 50; i++){
let tr = document.createElement('tr');
let td = document.createElement('td');
td.innerHTML = i;
tr.appendChild(td);
table.appendChild(tr);
}
}
Here is the link to my codepen:
https://codepen.io/prabodhpanda/pen/gOPLqYe?editors=1010

id attribute of each element in DOM should be unique. You set same id for each tr element you create. document.getElementById element always returns the first element match by the id. This is the reason of the issue. Your last code snippet should be:
function createtable() {
//Creating Table
var table = document.createElement("table")
table.innerHTML = ""
document.body.appendChild(table)
table.setAttribute("id", "table")
for (var i = 0; i < 50; i++) {
var tr = document.createElement("tr")
tr.innerHTML = ""
document.getElementById("table").appendChild(tr)
tr.setAttribute("id", "tr" + i) // Check this
var td = document.createElement("td")
td.innerHTML = ""
document.getElementById("tr" + i).appendChild(td) // Check this
}
}
tr.appendChild(td) should also work if you don't need ID attribute.

I edited your answer and got what I want.
//Creating tr and td
function createtable() {
//Creating Table
var table = document.createElement("table")
table.innerHTML = ""
document.body.appendChild(table)
table.setAttribute("id", "table")
for (var i = 0; i < 50; i++) {
var tr = document.createElement("tr")
tr.innerHTML = ""
document.getElementById("table").appendChild(tr)
tr.setAttribute("id", "tr")
for (var v = 0; v < 50; v++) {
var td = document.createElement("td")
td.innerHTML = ""
tr.appendChild(td)
}
}
}

Related

Set type text inside cell javascript

I want to type text inside the cell but I tried to set attribute with td but it doesn't work. Please help me how can I set attribute to type text in the cell. Thank you for your help!
function addTable() {
rn = window.prompt("Input number of rows", 1);
cn = window.prompt("Input number of columns",1);
var myTableDiv = document.getElementById("myDynamicTable");
var table = document.createElement('TABLE');
table.border = '1';
var tableBody = document.createElement('TBODY');
table.appendChild(tableBody);
for (var i = 0; i < parseInt(rn, 10); i++) {
var tr = document.createElement('TR');
tableBody.appendChild(tr);
for (var j = 0; j < parseInt(cn, 10); j++) {
var td = document.createElement('TD');
td.width = '75';
td.appendChild(document.createTextNode("text"));
tr.appendChild(td);
}
}
myTableDiv.appendChild(table);
}
addTable();
You need to create an input element and then append that to td:
rn = window.prompt("Input number of rows", 1);
cn = window.prompt("Input number of columns", 1);
var myTableDiv = document.getElementById("myDynamicTable");
var table = document.createElement('TABLE');
table.border = '1';
var tableBody = document.createElement('TBODY');
table.appendChild(tableBody);
for (var i = 0; i < parseInt(rn, 10); i++) {
var tr = document.createElement('TR');
tableBody.appendChild(tr);
for (var j = 0; j < parseInt(cn, 10); j++) {
var td = document.createElement('TD');
td.width = '75';
var input = document.createElement('input');
input.setAttribute('type', 'text');
input.setAttribute('value', 'text');
td.appendChild(input);
tr.appendChild(td);
}
}
myTableDiv.appendChild(table);
<div id="myDynamicTable">
</div>
You can use contenteditable attribute: td.contenteditable = 'true';.
Depending on how you want to use this value, you might also insert an input element.
You are perhaps looking for contentEditable?
function addTable() {
const rn = +window.prompt("Input number of rows", 1);
const cn = +window.prompt("Input number of columns", 1);
const myTableDiv = document.getElementById("myDynamicTable");
const table = document.createElement('table');
table.border = '1';
const tableBody = document.createElement('tbody');
table.appendChild(tableBody);
for (let i = 0; i < rn; i++) {
var tr = document.createElement('tr');
tableBody.appendChild(tr);
for (let j = 0; j < cn; j++) {
var td = document.createElement('td');
td.width = '75';
td.contentEditable = true;
td.appendChild(document.createTextNode("text"));
tr.appendChild(td);
}
}
myTableDiv.appendChild(table);
}
addTable();
<div id="myDynamicTable"></div>
if you want to operate on tables, use corrects javascript instructions ...
const
DynTb = document.getElementById('myDynamicTable')
rn = +window.prompt("Input number of rows", 1)
, cn = +window.prompt("Input number of columns", 1)
;
if( isNaN(rn) || isNaN(cn))
throw 'bad integer input value (s)'
const myTable = addTable(DynTb, rn, cn )
function addTable(tDiv, rn, cn)
{
let
tab = tDiv.appendChild( document.createElement('table') )
, tBy = tab.createTBody()
;
for(let r=0;r<rn;++r)
{
let row = tBy.insertRow()
for(let c=0;c<cn;++c)
{
row.insertCell().innerHTML =
`<input type="text" placeHolder="${r}-${c}">`
} }
return tab
}
table {
border-collapse : collapse;
margin : 2em 1em;
}
td {
padding : .2em;
border : 1px solid darkblue;
}
input {
width : 5em;
}
<div id="myDynamicTable"></div>

How can I convert this innerhtml loop to a innertext one because XSS vulnerabilities?

I need to convert this loop to innertext with the dynamically added content how can I do that I looked on the internet but could'nt find anything?
function showMessages(messages) {
jsonMessages.innerHTML = "<tr><th>Naam</th><th>Bericht</th><th>Datum</th></tr>";
messages.sort(function (a, b) {
return a.created_at > b.created_at ? 1 : -1;
});
for (var i = 0; i < messages.length; i++) {
jsonMessages.innerHTML += `<tr><td>${messages[i].user_id}</td><td>${messages[i].content.replace(/</g,"<")}</td><td>${messages[i].created_at}</td></tr>`;
}
console.log(messages);
}
To change your code to prevent xss by using innerText instead of arbitrarily setting innerHTML to some unknown code you will need to create elements themselves first then set their content
For instance
//create a tr element
tr = document.createElement('tr');
//create new cell for above tr
td = tr.insertCell();
td.innerText = messages[i].user_id;
You would do this for the all elements that would have dynamic content. So in your case you could do the following
for (var i = 0; i < messages.length; i++) {
let tr = document.createElement('tr');
let userIdCell = tr.insertCell();
let contentCell = tr.insertCell();
let dateCell = tr.insertCell();
userIdCell.innerText = messages[i].user_id;
contentCell = messages[i].content;
dateCell = messages[i].created_at;
//finally add it to your table
jsonMessages.appendChild(tr);
}
There are other routes that do the same thing, like putting a blank string of your html structure into an element then select the elements and set them:
let tr = document.createElement('tr');
tr.innerHTML = `<tr><td></td><td></td><td></td></tr>`;
//first td child
tr.children[0] = messages[i].user_id;
//second td child
tr.children[1] = messages[i].content;
//third td child
tr.children[2] = messages[i].created_id;
It all just depends on your personal preference. The main point is to just create the elements first then set their innerText property instead of setting the whole html as one.
function showMessages(messages) {
jsonMessages.innerHTML = "<tr><th>Naam</th><th>Bericht</th><th>Datum</th></tr>";
messages.sort(function (a, b) {
return a.created_at > b.created_at ? 1 : -1;
});
for (var i = 0; i < messages.length; i++) {
var mainTr = document.createElement('tr');
var td1 = document.createElement('td').appendChild(document.createTextNode(messages[i].user_id));
var td2 = document.createElement('td').appendChild(document.createTextNode(messages[i].content.replace(/</g,"<")));;
var td3 = document.createElement('td').appendChild(document.createTextNode(messages[i].created_at));
mainTr.appendChild(td1);
mainTr.appendChild(td2);
mainTr.appendChild(td3);
jsonMessages.appendChild(mainTr);
}
console.log(messages);
}

How to add onClick function to this code

I am trying to add an onclick function to this table. So when I click on the cell it will change color from red to blue.
Relevant code below:
function addTable() {
var myTableDiv = document.getElementById("myDynamicTable");
var table = document.createElement('TABLE');
table.border='1';
var tableBody = document.createElement('TBODY');
table.appendChild(tableBody);
for (var i=0; i<ruudud.value; i++){
var tr = document.createElement('TR');
tableBody.appendChild(tr);
for (var j=0; j<ruudud.value; j++){
var td = document.createElement('TD');
td.width='50';
td.height='50';
td.style.backgroundColor="red";
tr.appendChild(td);
}
}
myTableDiv.appendChild(table);
}
There is many ways to do this as the below :
1 - In for loop
<div id="myDynamicTable"></div>
<script type="text/javascript">
addTable();
function addTable() {
var myTableDiv = document.getElementById("myDynamicTable");
var table = document.createElement('TABLE');
table.border = '1';
var tableBody = document.createElement('TBODY');
table.appendChild(tableBody);
for (var i = 0; i < 3 ; i++) {
var tr = document.createElement('TR');
tableBody.appendChild(tr);
for (var j = 0; j < 2; j++) {
var td = document.createElement('TD');
td.width = '50';
td.height = '50';
td.style.backgroundColor = "red";
//************************************************
td.setAttribute("onclick", "yourFun(this)");
tr.appendChild(td);
}
}
myTableDiv.appendChild(table);
}
function yourFun(tdObj) {
tdObj.style.backgroundColor = "green";
}
2 - By Function :
<div id="myDynamicTable"></div>
<script type="text/javascript">
addTable();
setFunction();
function addTable() {
var myTableDiv = document.getElementById("myDynamicTable");
var table = document.createElement('TABLE');
table.border = '1';
var tableBody = document.createElement('TBODY');
table.appendChild(tableBody);
for (var i = 0; i < 3 ; i++) {
var tr = document.createElement('TR');
tableBody.appendChild(tr);
for (var j = 0; j < 2; j++) {
var td = document.createElement('TD');
td.width = '50';
td.height = '50';
td.style.backgroundColor = "red";
tr.appendChild(td);
}
}
myTableDiv.appendChild(table);
}
function setFunction() {
var myTableDiv = document.getElementById("myDynamicTable");
var tds = myTableDiv.getElementsByTagName("td");
for (var i = 0; i < tds.length; i++) {
tds[i].setAttribute("onclick", "yourFun(this)");
}
}
function yourFun(tdObj) {
tdObj.style.backgroundColor = "green";
}
3- Or You can use Event Delegation see this http://davidwalsh.name/event-delegate
You can do it by setting the onclick attribute for each td in your for loop which calls a corresponding function to handle a class change. The colors can be defined in your css for the two classes.
// for loop addition
td.setAttribute('class', 'bgRed');
// and
td.setAttribute('onclick', chgColor(this));
// or
td.onclick(function(this) {return function() {chgColor(this);};})(this);
// Function for changing td background class/color
function chgColor(td){
td.className == "bgRed" ? td.className = "bgBlue" : td.className = "bgRed";
}
You can directly add the event listener on the table, and in the callback you can check the event source and act accordingly. The event source would be a node so if you want to hold any specific data, you can keep attributes and read them on event.

Creating dynamically large table using JavaScript

I'm trying to create dynamically a table using JavaScript.
Here is the code I'm using (or here http://liveweave.com/mqG5iT):
function Process(){
CreatTable(['First Name', 'Last Name', 'Email']);
}
function CreatTable(data) {
var checkbox;
var table;
var thead;
var tr;
var th;
var tbody;
tablearea = document.getElementById('ShowDataID');
table = document.createElement('table');
table.id = "ContactsTable";
thead = document.createElement('thead');
tr = document.createElement('tr');
tbody = document.createElement('tbody');
//create columns input checkbox column
checkbox = CreateHTMLElement("chkBoxAllEmails", "chkBoxAllEmails", "SelectAllEmails()", "checkbox", "false");
th = document.createElement('th');
th.appendChild(checkbox);
tr.appendChild(th);
thead.appendChild(tr);
//create columns FirstName,LastName,Emails
for (var i = 0; i < data.length; i++) {
var headerTxt = document.createTextNode(data[i]);
th = document.createElement('th');
th.appendChild(headerTxt);
tr.appendChild(th);
thead.appendChild(tr);
}
table.appendChild(thead);
//create rows and addind to table
for (var i = 0; i < 2000; i++) {
tr = document.createElement('tr');
checkbox = CreateHTMLElement("11", "11", "11", "checkbox", "11");
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.cells[0].appendChild(checkbox); tr.cells[1].appendChild(document.createTextNode('John'+i.toString()));
tr.cells[2].appendChild(document.createTextNode('McDowell'));
tr.cells[3].appendChild(document.createTextNode('ddd#gmail.com'));
tbody.appendChild(tr);
table.appendChild(tbody);
}
document.getElementById("TablePagingArea").appendChild(table);
//return table;
}
function CreateHTMLElement(id, name, onclick, type, value) {
var HTMLElement = document.createElement('input');
HTMLElement.id = id;
HTMLElement.name = name;
HTMLElement.onclick = onclick;
HTMLElement.type = type;
HTMLElement.value = value;
return HTMLElement;
}
With a small set of data 1000-3000 rows it works relatively well but, some of the data set contains upwards of 5000 rows which causes Firefox to crash and close or become unresponsive.
My question is: is there a better way to accomplish what I am trying to do?
Most efficient way to create a bunch of elements is to create a string and create element from this string.
Most efficient way to create a string of element is to join from array
So you should refactor your code to
Create an array of elements like a[i] = "<tr><intput type='checkbox'></tr>";
Join an array to get one string var s = a.join();
Create DOM elements like var div = document.createElement('div'); div.innerHTML = s;

Some misunderstanding with creating dynamic table in JavaScript

I try to create dynamic table using JavaScript, the table contains two columns first name and family name.
Here is the JavaScropt code:
function CreatTable() {
var tablearea = document.getElementById('ShowDataID');
var table = document.createElement('table');
var thead = document.createElement("thead");
var tr = document.createElement('tr');
var th = document.createElement('th');
var firstNameTxt = document.createTextNode("First Name");
th.appendChild(firstNameTxt);
tr.appendChild(th);
thead.appendChild(tr);
table.appendChild(thead);
var familyNameTxt = document.createTextNode("Family Name");
th.appendChild(familyNameTxt);
tr.appendChild(th);
thead.appendChild(tr);
table.appendChild(thead);
for (var i = 1; i < 4; i++) {
var tr = document.createElement('tr');
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.cells[0].appendChild(document.createTextNode('John'))
tr.cells[1].appendChild(document.createTextNode('McDowell'))
table.appendChild(tr);
}
tablearea.appendChild(table);
}
And here the the result I get:
My question is why do I get "McDowell" not under the family name column.Why it is shifted?What I am missing?
Try to create a new th for the second time, don't use the already used one
function CreatTable() {
var tablearea = document.getElementById('ShowDataID');
var table = document.createElement('table');
var thead = document.createElement("thead");
var tr = document.createElement('tr');
var th = document.createElement('th');
var firstNameTxt = document.createTextNode("First Name");
th.appendChild(firstNameTxt);
tr.appendChild(th);
thead.appendChild(tr);
table.appendChild(thead);
//********* Look here *****************
var familyNameTxt = document.createTextNode("Family Name");
th = document.createElement('th'); //*** Create a new th here. Dont use the old one
//********* Look here *****************
th.appendChild(familyNameTxt);
tr.appendChild(th);
thead.appendChild(tr);
table.appendChild(thead);
for (var i = 1; i < 4; i++) {
var tr = document.createElement('tr');
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.cells[0].appendChild(document.createTextNode('John'))
tr.cells[1].appendChild(document.createTextNode('McDowell'))
table.appendChild(tr);
}
tablearea.appendChild(table);
}
DEMO
SOLUTION
function CreatTable() {
var tablearea = document.getElementById('ShowDataID');
var table = document.createElement('table');
var thead = document.createElement('thead');
var tr = document.createElement('tr');
var th = document.createElement('th');
var firstNameTxt = document.createTextNode("First Name");
th.appendChild(firstNameTxt);
tr.appendChild(th);
thead.appendChild(tr);
table.appendChild(thead);
var familyNameTxt = document.createTextNode("Family Name");
th = document.createElement('th');
th.appendChild(familyNameTxt);
tr.appendChild(th);
thead.appendChild(tr);
table.appendChild(thead);
for (var i = 1; i < 4; i++) {
tr = document.createElement('tr');
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.cells[0].appendChild(document.createTextNode('John'));
tr.cells[1].appendChild(document.createTextNode('McDowell'));
table.appendChild(tr);
}
tablearea.appendChild(table);
}
CreatTable();
you miss creating new th
var familyNameTxt = document.createTextNode("Family Name");
th = document.createElement('th'); // this line missed
th.appendChild(familyNameTxt);
Create dynamic table row and remove on click delete button row. for this you can use jQuery two method
.append() this method used for append html table row, on button click of .add_row_record its get value from text box and append data on table row.
.remove () this method is used for remove dynamic content data, in this example we are used for delete append record. .delete_row_record button remove the record on the basis of selected checkbox.
<script type="text/javascript">
$(document).ready(function(){
//add row
$(".add_row_record").click(function(){
var name = $("#name").val();
var email = $("#email").val();
var mobile = $("#mobile_number").val();
var markup = "<tr><td><input type='checkbox' name='record'></td><td>" + name + "</td><td>" + email + "</td><td>" + mobile + "</td></tr>";
$("table tbody").append(markup);
});
// select record for delete
$(".delete_row_record").click(function(){
$("table tbody").find('input[name="record"]').each(function(){
if($(this).is(":checked")){
$(this).parents("tr").remove();
}
});
});
});
Demo

Categories

Resources