How to find empty tr in table using Javascript [closed] - javascript

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to find Empty tr in table, is there any way to find it?
after finding empty row I want to insert some data in it.

Supposing you have this HTML :
<table id=tbl>
<tr><td>A</td><td>B</td></tr>
<tr><td>A</td><td>B</td></tr>
<tr><td></td><td></td></tr> <!-- this line is empty -->
<tr><td>A</td><td>B</td></tr>
</table>
Then you can fill the empty line like this :
var rows = document.getElementById('tbl').rows;
for (var i=0; i<rows.length; i++) {
var txt = rows[i].textContent || rows[i].innerText;
if (txt.trim()==="") rows[i].innerHTML="<td>Something</td>";
}
Demonstration
This uses :
the rows property of the table
textContent (or innerText for IE) to get the content without the tags
As this also use the trim function which isn't available in IE8, you might want to add this shim :
if(!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g,'');
};
}

There might be better ways, this is what occurred to me.
$('tr').each(function() {
if($(this).find('td').length == 0) {
// empty tr
// id of tr is available through this.id
}
});

Maybe something like this $('table tr:empty').html('....')

var tables = document.getElementsByTagName('table');
var table = tables[0];
var trs = table.getElementsByTagName('tr');
for (var i = 0; i < trs.length; i++) {
if (trs[i].innerHTML === '') {
console.log('EMPTY', trs[i]);
} else {
console.log('NOT EMPTY', trs[i]);
}
}

I think its not easy. You can see this link.
HTML:
<table id="table" style="border: 1px solid green;"><tbody>
<tr id="empty"></tr>
<tr id="withText"><font style="color: red;">text</font></tr>
<tr id="withEmptyTd"><td></td></tr>
<tr id="withTdWithText"><td>text</td></tr>
</tbody></table>
<div id="output"></div>
Javascript:
var output = document.getElementById('output');
var table = document.getElementById('table');
var trs = table.querySelectorAll('tr');
var tr, id, text, tds, j, td, tdText;
for (var i = 0; i < trs.length; i++) {
tr = trs[i];
id = tr.id;
output.innerHTML += "Getting tr[" + id + "]<br />";
text = tr.innerHTML;
output.innerHTML += "tr[" + id + "].innerHTML = \"" + text + "\" it's length = " + text.length + "<br />";
tds = tr.querySelectorAll('td');
output.innerHTML += "tr[" + id + "] have " + tds.length + " tds<br />";
for (j = 0; j < tds.length; j++) {
td = tds[j];
tdText = td.innerHTML;
output.innerHTML += "tr[" + id + "] -> td[" + j + "].innerHTML = \"" + tdText + "\" its length = " + tdText.length + "<br />";
}
}
And output will be:
Getting tr[empty]
tr[empty].innerHTML = "" it's length = 0
tr[empty] have 0 tds
Getting tr[withText]
tr[withText].innerHTML = "" it's length = 0
tr[withText] have 0 tds
Getting tr[withEmptyTd]
tr[withEmptyTd].innerHTML = "" it's length = 9
tr[withEmptyTd] have 1 tds
tr[withEmptyTd] -> td[0].innerHTML = "" its length = 0
Getting tr[withTdWithText]
tr[withTdWithText].innerHTML = "text" it's length = 13
tr[withTdWithText] have 1 tds
tr[withTdWithText] -> td[0].innerHTML = "text" its length = 4
Cause any tag or text in tr but not in td shows before the table.

Related

Create new <tr>as text after 3rd <td> in JS

i want to create new table row as text <tr> after every third table data<td> from user input.
It have to be like this:
<table border="3" align="center" style="width: 100%;">
<tr>
<td><a href="link"><img src="link"></td>
<td><a href="lin"><img src="link"></td>
<td><a href="link"><img src="link"></td>
</tr>
<tr>
<td><a href="link"><img src="link"></td>
<td><a href="lin"><img src="link"></td>
<td><a href="link"><img src="link"></td>
</tr>
</table>
My code:
<script type="text/javascript">
let x = 0;
const data = Array();
document.getElementById('btn').addEventListener("click", fun);
function fun() {
var val = document.getElementById('imagename').value;
source = val;
img = document.createElement('img');
img.src = source;
document.body.appendChild(img);
// move child to up
var before = document.getElementById('before');
before.insertBefore(img, before.children[0]);
/*var html = document.getElementById('before').innerHTML;
document.getElementById('code').innerHTML = '<img src=' + src + '>';*/
document.getElementById('code').innerText = '<img src="' + source + '">';
data[x] = document.getElementById('imagename').value;
x++;
}
document.getElementById('pasteBtn').addEventListener("click", makeCode);
function makeCode(){
let resultData = "<tr>";
for (let i = 0; i < data.length; i++){
resultData += "<td>" + '<a href="' + data[i] + '">' + '<img src="' + data[i] + '"></td>\n';
if(i % 3 == 0){
resultdata += '</tr><tr>';
}
}
cssText = 'tr {width: 100%; display: flex;} td {width: 100%;}';
tableText = '\n<table border="3" align="center" style="width: 100%;">\n';
document.getElementById("paste").innerText = "<style>" + cssText + "</style>" + tableText + resultData;
}
</script>
I was trying with modulo but nothing happened. It have to be done in JS, not JQuery.
Your code has a couple of problems, which have been mentioned in the comments. The last created row is not closed. Some browsers nowadays automatically solve this problem by adding the closing tag for that row, but it leaves you with a floating row.
A second problem is your modulo calculation. Since javascript arrays start at 0 and not at 1 you modulo creates the row to early, for:
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
A row is created containing ONLY the first value. This can be fixed by changing the modulo calculation to i + 1 % 3, however it might not immediatly be clear why you seemingly randomly add the 1.
Another option is to introduce a counter. It is clear what the counter does, it counts. It is also clear to where it counts, 3. By moving the closing and starting of the row to before the adding of the cell you prevent floating rows. You only start a new row, when you actually need one. Important still is to close the row, but as said before, there are browsers that do this, but you should not rely on that.
let resultData = "<tr>";
let counter = 0;
for (let i in data){
if(counter == 3){
resultdata += '</tr><tr>';
counter = 0;
}
resultData += "<td>" + '<a href="' + data[i] + '">' + '<img src="' + data[i] + '"></td>\n';
counter++;
}
resultdata += "</tr>";
Personally I prefer to use a for...in loop for looping over an array, but that is personal preference
There are many ways to accomplish what you are looking for.
For my answer I chunked the array into groups of 3, then I loop through each element in each group.
I also chose to use createElement instead of using the string versions.
let table = document.querySelector("#paste");
let data = [
1,2,3,4,5,6,7,8,9
];
while((row = data.splice(0, 3)).length){
let tr = document.createElement("tr");
for(z=0;z<=row.length-1;z++){
let td = document.createElement("td");
let link = document.createElement("a");
let img = document.createElement("img");
img.src = row[z];
link.href = row[z];
link.appendChild(img)
td.appendChild(link)
tr.appendChild(td)
}
table.appendChild(tr)
}
<table id="paste"></table>
Adding EventListener to MakeCode.Btn.getting the count of td each row has with data.length/3(9/3=3);so each row will have 3 td's.
Creating index variable to iterate over the array.
creating Two ForLoops.
1st loop will create a row with an id of r(i).first row will have an id of id="r1".
2nd loop will get the row that was created in the first loop and it will add td tCount times which is 3 in this case.
& data will also be added inside each td with ${data[index]}
incrementing the index every time a td is added.
when index is equal to data.length getting the innerHtml of the table and pasting it in the text area as a value.and setting the innerHtml of the actual table to "" empty
const data = [
"hello",
"world",
"code",
"coding",
"javascript",
"css",
"html",
"react",
"scss"
];
let table = document.getElementById("table");
let btn = document.getElementById("pasteBtn");
let textBox = document.getElementById("textbox");
btn.addEventListener("click", () => {
let tdCount = data.length / 3;
let index = 0;
for (let i = 1; i <= 3; i++) {
table.innerHTML += `<tr id="r${i}"></tr>`;
for (let j = 1; j <= tdCount; j++) {
document.getElementById(`r${i}`).innerHTML += `<td><a href="link"><img src="link"></td>`;
index++;
if (index === data.length) {
let finalHtml = document.getElementById("table").innerHTML;
textBox.value = finalHtml;
document.getElementById("table").innerHTML = "";
}
}
}
});
textarea {
width: 100%;
height: 200px;
}
<button id="pasteBtn">makeCode</button>
<table border="3" align="center" style="width: 100%;">
<tbody id="table">
</tbody>
</table>
<textarea id="textbox"></textarea>
As mentioned #imvain2's answer, it is better to use js document.createElement over the string to create the elements. And here is an approach that uses a single loop.
HTML:
<table id="data-table"></table>
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const table = document.getElementById('data-table');
const addRows = (data) => {
let tableRow = null;
data.forEach((item, index) => {
// adds a new row on first and then after every third "td"
if (index % 3 === 0) {
tableRow = document.createElement('tr');
tableRow.id = 'tr' + (index + 1);
table.appendChild(tableRow);
}
const tableData = document.createElement('td');
tableRow.appendChild(tableData);
const link = document.createElement('a');
link.href = item;
link.title = item;
tableData.appendChild(link);
const img = document.createElement('img');
img.src = item;
link.appendChild(img);
});
};
addRows(data);

Why Chrome adds tbody tag to each table row? [duplicate]

This question already has answers here:
Why do browsers insert tbody element into table elements?
(2 answers)
Why do browsers still inject <tbody> in HTML5?
(6 answers)
Closed 6 years ago.
I have two tables that fill up throw an event.
The stylesheet is made for that the even rows get painted white.
table {
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
But due Chrome adds tbody tag to each tr tag it's doesn't work.
The first table fill up throw back-end:
var prueba = {};
prueba = nuevaCadena[nuevaCadena.length - 1].replace(/<br>/g, "").split(",");
prueba.venta = prueba[0];
prueba.fecha = prueba[1];
prueba.heladeria = prueba[2];
//prueba.base.split(",");
//if (myElem === null) {
var contenido = document.getElementById("contenido");
var tr2 = document.createElement("TR");
if (contenido.getElementsByTagName("TH").length === 0)
{
contenido.appendChild(tr2);
tr2.innerHTML += "<th>Heladeria</th>";
tr2.innerHTML += "<th>Fecha</th>";
tr2.innerHTML += "<th>ID</th>";
} else {
var template = "<tr><td>{{heladeria}}</td><td>{{fecha}}</td><td>{{venta}}</td></tr>";
document.querySelector('#contenido').innerHTML += Mustache.render(template, prueba);
}
And the second works perfectly. It's fill up throw the select tag values.
var contenido = document.getElementById("contenido2");
var tr2 = document.createElement("TR");
var tr = document.createElement("TR");
if (contenido.getElementsByTagName("TH").length === 0)
{
contenido.appendChild(tr2);
tr2.innerHTML += "<th>Heladeria</th>";
tr2.innerHTML += "<th>Fecha</th>";
tr2.innerHTML += "<th>Sabor</th>";
tr2.innerHTML += "<th>Cantidad</th>";
}
contenido.appendChild(tr);
//var th = document.createElement("TD");
var option = ["heladerias", "sabores"];
var valor = document.getElementById("sabor_calorias");
var fecha = document.getElementById("fecha");
for (var i = 0; i <= 0; i++) {
var input = document.getElementById(option[i]).selectedIndex;
var input2 = document.getElementById(option[i]).options;
tr.innerHTML += "<td>" + input2[input].text + "</td>";
tr.innerHTML += "<td>" + fecha.value + "</td>";
for (var j = 1; j <= 1; j++) {
input = document.getElementById(option[j]).selectedIndex;
input2 = document.getElementById(option[j]).options;
tr.innerHTML += "<td>" + input2[input].text + "</td>";
tr.innerHTML += "<td>" + valor.value + "</td>";
tr.innerHTML += "<input type='button' class='borrar' value='x' onclick='deleted(this)'/>";
}
}
The results are this:
This question didn't work for me Why do browsers insert tbody element into table elements? i use Mustache.
When parsing the HTML syntax, the browser will insert a tbody tag, as explained in Why do browsers still inject <tbody> in HTML5?. By appending to the innerHTML each time, you're creating a new tbody each time. The HTML syntax can't represent a tr as a direct child of a table.
You could instead use
tr = table.insertRow()
tr.innerHTML='<td>foo<td>bar'
if you still wanted to write the row with innerHTML, or use td = tr.insertCell() as well.
The tags that chrome add are not needed, and shouldn't affect your code.
If you keep getting the error you might want to try going through to make sure you don't have any missed-placed characters.

How to make list in jQuery mobile nested list?

Can you please tell me how to make list in jQuery mobile? I am trying to make this type list as given in fiddle on pop up screen dynamically .
Here is the fiddle
In this fiddle I make two rows.In first row there is only p tag. But in second row there is nested collapsible rows. I need to make same thing in pop up screen. I am able to make first row. But In my second row contend is null why? Can you suggest where I am wrong?
fiddle
$(function () {
$('#test').click(function(){
alert('d');
createCommandPopUpTabs();
$("#tabbedPopup").popup("open");
});
});
var tabsHeader = [ "InputParameter", "basic"];
var tabsHeader_basic = [ "XYZ", "Third Level",
];
function createCommandPopUpTabs(){
var header = "<h3 >dd</h3>";
var commmand = 'dd';
var button = '<button onclick="return submitCommand("'+
'")" style="" class="donebtn common-button1">Save</button>';
$("#commandInfo").append(button);
$("#commandInfoheader").html(header);
for ( var i = 0; i < tabsHeader.length; i++) {
var headerId = tabsHeader[i] + "_tab" + commmand;
var header = "<div data-role='collapsible' data-collapsed='false' id='"
+ headerId + "'><h3>InputParameter</h3></div>";
var content ;
if(tabsHeader[i]=="InputParameter"){
content = "<p>yes</p>";
}else if(tabsHeader[i]=="basic"){
for ( var i = 0; i < tabsHeader_basic.length; i++) {
headerId = tabsHeader_basic[i] + "_tab" + commmand;
header = "<div data-role='collapsible' data-collapsed='false' id='"
+ headerId + "'><h3>basic</h3></div>";
content += getcontend(tabsHeader_basic[i]);
}
}
$("#tabbedSet").append(header);
$("#tabbedSet").find("#" + headerId).append(content);
$("#tabbedSet").collapsibleset("refresh");
}
}
function getcontend(name){
if(name=="Third Level"){
return"<p>Third Level></p>";
} if(name=="XYZ"){
return"<p> second Level></p>";
}
}
There are errors in your code and logic. I will only go over a couple of them to hopefully get you on the right path:
In tabsHeader_basic array the Third Level has a space in it which you later use as an ID which makes it an invalid ID because you cannot have spaces in an ID.
From the HTML 5 Draft:
The value must not contain any space characters.
Also, the "basic" collapsible div needs to exist before you start adding the nested collapsible div.
So this line needs to come out of the for loop
header = "<div data-role='collapsible' data-collapsed='false' id='"+ headerId + "'><h3>basic</h3></div>";
Go through the JSFiddle and compare your code agaisnt my changes.
Hopefully that helps! Let me know if you have any other questions.
I have updated createCommandPopUpTabs() function.
Also removed space in Third Level on var tabsHeader_basic = ["XYZ", "ThirdLevel"];
Check the Updated Fiddle
function createCommandPopUpTabs() {
var header = "<h3 >dd</h3>";
var commmand = 'dd';
var button = '<button onclick="return submitCommand("' +
'")" style="" class="donebtn common-button1">Save</button>';
$("#commandInfo").html(button);
$("#commandInfoheader").html(header);
$("#tabbedSet").html('');
for (var i = 0; i < tabsHeader.length; i++) {
var headerId = tabsHeader[i] + "_tab" + commmand;
var header = "<div data-role='collapsible' data-collapsed='true' id='" + headerId + "'><h3>" + tabsHeader[i] + "</h3></div>";
$("#tabbedSet").append(header);
var content;
if (tabsHeader[i] == "InputParameter") {
content = "<p>yes</p>";
$("#tabbedSet").find("#" + headerId).append(content);
} else if (tabsHeader[i] == "basic") {
for (var j = 0; j < tabsHeader_basic.length; j++) {
var headerId1 = tabsHeader_basic[j] + "_tab" + commmand;
var header1 = "<div data-role='collapsible' data-collapsed='true' id='" + headerId1 + "'><h3>" + tabsHeader_basic[j] + "</h3></div>";
var content1 = getcontend(tabsHeader_basic[j]);
$("#tabbedSet").find("#" + headerId).append(header1);
$("#tabbedSet").find("#" + headerId1).append(content1);
}
}
$("#tabbedSet").collapsibleset("refresh");
}
}

JavaScript works in Chrome but not ie9 [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am facing an issue with JavaScript.I see that it works fine in chrome but not in IE9.This would not display what chrome is displaying on the web page as expected.
I am new to JavaScripting can I get help in fixing this issue.
<script type="text/javascript">
var tds = document.getElementById('course_table')
.getElementsByTagName('td');
var sum = 0;
for (var i = 0; i < tds.length; i++) {
if (tds[i].className == 'count-me') {
sum += isNaN(tds[i].innerHTML) ? 0
: parseInt(tds[i].innerHTML);
}
}
var lastrecord = tds[tds.length - 2].innerHTML;
var table = document.getElementById('course_table')
.getElementsByTagName('tr');
var max = table.length - 2;
document.getElementById('course_table').innerHTML += '<tr bgcolor=#FFCCFF><td></td><td>Total Courses</td><td>' + max + '</td><td>Total Credits Remaining</td><td>'+ sum + '</td><td> Expected Graduation Date</td><td></td><td>' + lastrecord + '</td><td></td></tr> ';
</script>
Thanks
Niveditha
The problem is most likely in the last line:
document.getElementById('course_table').innerHTML += '<tr bgcolor=#FFCCFF><td></td><td>fsffd</td><td>' + max + '</td><td>abcdRemaining</td><td>'+ sum + '</td><td> abc</td><td></td><td>' + lastrecord + '</td><td></td></tr> ';
IE doesn't handle trs being added by strings; besides it is non-standard. Replace that line with this, it programmatically builds up the row and is faster. I added the corresponding <td> as comments.
var table = document.getElementById('course_table');
var row = table.insertRow(-1);
row.style.backgroundColor = '#FFCCFF'; // `bgcolor` attribute is deprecated
row.insertCell(-1); // <td></td>
row.insertCell(-1).textContent = "fsffd"; // <td>fsffd</td>
row.insertCell(-1).textContent = max; // <td>' + max + '</td>
row.insertCell(-1).textContent = "abcdRemaining"; // <td>abcdRemaining</td>
row.insertCell(-1).textContent = sum; // <td>' + sum + '</td>
row.insertCell(-1).textContent = "abc"; // <td> abc</td>
row.insertCell(-1); // <td></td>
row.insertCell(-1).textContent = lastRecord; // <td>' + lastRecord + '</td>
row.insertCell(-1); // <td></td>
The important methods here are insertRow and insertCell, they are guaranteed to work. textContent is faster and safer than innerHTML. Please use CSS instead of the deprecated bgcolor attribute
Internet Explorer doesn't like adding <tr> elements to the <table> in that manner. What you can do is append a new <tbody> element to the table:
// ... the first part of your function ...
var lastrecord = tds[tds.length - 2].innerHTML;
var table = document.getElementById('course_table');
var newbody = document.createElement('tbody');
newbody.innerHTML = '<tr bgcolor=#FFCCFF><td></td><td>Total Courses</td><td>' + max + '</td><td>Total Credits Remaining</td><td>'+ sum + '</td><td> Expected Graduation Date</td><td></td><td>' + lastrecord + '</td><td></td></tr> ';
table.appendChild(newbody);

Creating html table using Javascript not working

Basically, I want the user the just change the 'height' variable to how ever many rows he wants, and then store the words which each td in the row should contain, and the code should then generate the table.
My html is just this:
<table id="newTable">
</table>
This is my Javascript:
<script type="text/javascript">
var height = 2; // user in this case would want 3 rows (height + 1)
var rowNumber = 0;
var height0 = ['HeadingOne', 'HeadingTwo']; // the words in each td in the first row
var height1 = ['firstTd of row', 'secondTd of row']; // the words in each td in the second row
var height2 = ['firstTd of other row', 'secondTd of other row']; // the words in each td in the third row
$(document).ready( function() {
createTr();
});
function createTr () {
for (var h=0; h<height + 1; h++) { // loop through 3 times, in this case (which h<3)
var theTr = "<tr id='rowNumber" + rowNumber + "'>"; // <tr id='rowNumber0'>
$('#newTable').append(theTr); // append <tr id='rowNumber0'> to the table
for (var i=0; i<window['height' + rowNumber].length; i++) {
if (i == window['height' + rowNumber].length-1) { // if i==2, then that means it is the last td in the tr, so have a </tr> at the end of it
var theTd = "<td class='row" + rowNumber + " column" + i + "'>" + window['height' + rowNumber][i] + "</td></tr>";
$('#rowNumber' + rowNumber).append(theTr); // append to the end of the Tr
} else {
var theTd = "<td class='row" + rowNumber + " column" + i + "'>" + window['height' + rowNumber][i] + "</td>";
$('#rowNumber' + rowNumber).append(theTr);
}
}
rowNumber += 1;
}
}
</script>
I did 'alert(theTr);' and 'alert(theTd);' and they looked correct. How come this code doesn't generate any table?
You should change the line
$('#rowNumber' + rowNumber).append(theTr);
into
$('#rowNumber' + rowNumber).append(theTd);
You are adding the Tr-Code again in the inner loop, but you actually wanted to add the Td-Code.
All that window["height"+rowNumber] stuff is a poor way to do it. Use an array, and pass it as a parameter to the function so you don't use global variables. And use jQuery DOM creation functions instead of appending strings.
<script type="text/javascript">
var heights = [['HeadingOne', 'HeadingTwo'], // the words in each td in the first row
['firstTd of row', 'secondTd of row'], // the words in each td in the second row
['firstTd of other row', 'secondTd of other row'] // the words in each td in the third row
];
$(document).ready( function() {
createTr(heights);
});
function createTr (heights) {
for (var h=0; h<heights.length; h++) { // loop through 3 times, in this case (which h<3)
var theTr = $("<tr>", { id: "rowNumber" + h});
for (var i=0; i<heights[h].length; i++) {
theTr.append($("<td>", { "class": "row"+h + " column"+i,
text: heights[h][i]
}));
}
$('#newTable').append(theTr); // append <tr id='rowNumber0'> to the table
}
}
</script>
JSFIDDLE

Categories

Resources