Inserting Table Rows conditionally

J

jc

A while back I posted a problem on here and got some awsome help and
insight with deleting table rows using javascript. Thank you! Well
the problem gets a bit more complex now as I need to insert rows too.

In the original problem, I needed to remove Table rows rows that did
not fit a certain condition. The resulting and working code looked
like this:

<script type="text/javascript">
var theRows = document.getElementsByTagName("TR");
var r = 0;
var strTitle = "";
while (r < theRows.length)
{ try
{ strTitle = theRows[r].innerText || theRows[r].textContent;
strTitle = strTitle.replace(/\n|\r|\t|\^ /g,"");
var row = theRows[r],
cells = row.getElementsByTagName('td');
if (cells[0].className.indexOf('ms-formlabel') > -1)
{
if (strTitle.indexOf("(HP)") == -1)
{
theRows[r].style.display = "none";
}
else
{
theRows[r].cells[0].innerHTML = theRows[r].cells
[0].innerHTML.replace("(HP)","");
}
}

}catch(err){}r+=1;
}
</script>


And it works great!

Now the challenge is that I need to insert a Row header when a certain
qualifying row is encountered under that same conidtion.

So for example, if a row contains (HP), it will fall into the
condition.. it that row has a string (H:whatever) in it, I need to
insert a row in that table, right above that qualifiying row as
follows:


The rendered html looks likes

<TR>
<TD nowrap="true" valign="top" width="190px" class="ms-
formlabel"><H3

class="ms-standardheader">
<nobr>(HP)(H:whatever) Question</nobr>
</H3></TD>
<TD valign="top" class="ms-formbody" width="400px">



The result of the new code would look like this:

<tr><td>whatever</td></tr>

<TR>
<TD nowrap="true" valign="top" width="190px" class="ms-
formlabel"><H3

class="ms-standardheader">
<nobr>Question</nobr>
</H3></TD>
<TD valign="top" class="ms-formbody" width="400px">



Thanks in advance for any help or information!
 
R

RobG

A while back I posted a problem on here and got some awsome help and
insight with deleting table rows using javascript. Thank you! Well
the problem gets a bit more complex now as I need to insert rows too.

In the original problem, I needed to remove Table rows rows that did
not fit a certain condition. The resulting and working code looked
like this:

<script type="text/javascript">
var theRows = document.getElementsByTagName("TR");

That will get all the tr elements in the document, it would be safer
to get just the rows of the table you are dealing with.
var r = 0;
var strTitle = "";
while (r < theRows.length)

As order here is not important, you can write that as:

r = theRows.length;
while (r--)

and then not increment r at the bottom of the while block.

You should indent your code with 2 or 4 spaces to make it easier to
read. The harder you make it, the less likely it is that people will
help.

Why do you think a try..catch block is required here? Are there errors
if you remove it? If so, deal with the errors, don't just hide them.
Tables also have a live rows collection that can be used as an
alternative to getElementsByTagName.

{ strTitle = theRows[r].innerText || theRows[r].textContent;

Write a function that uses a suitable feature test to see which
property to read, there are plenty of examples in the archives. Later
you assume strTitle is a string and call some of its native methods, a
getText function could ensure the result is a string or null if all
feature tests fail.

But innerText and textContent are likely not needed here anyway, see
below.

strTitle = strTitle.replace(/\n|\r|\t|\^ /g,"");

You should check strTitle is a string before using string methods. The
suggested function could also normalise the result.

var row = theRows[r],
cells = row.getElementsByTagName('td');

Row elements have a cells collection that may suit better.
if (cells[0].className.indexOf('ms-formlabel') > -1)

If you are onlly looking at the first cell, then you don't need
getElementsByTagName, just use the row's cells collection:

if (row.cells[0].className... )
{
if (strTitle.indexOf("(HP)") == -1)

Presuming strTitle is a string.

{
theRows[r].style.display = "none";}

else
{
theRows[r].cells[0].innerHTML = theRows[r].cells
[0].innerHTML.replace("(HP)","");

Rather than getting a reference to the same cell several times, get a
reference once and re-use it. And if it's safe to use innerHTML here,
you can likely use it above instead of that innerText and textContent
expression.

}

}
}catch(err){}r+=1;

Indenting and formatting your code to be easily read would be a help.

}

</script>

And it works great!

Now the challenge is that I need to insert a Row header when a certain
qualifying row is encountered under that same conidtion.

So for example, if a row contains (HP), it will fall into the
condition.. it that row has a string (H:whatever) in it, I need to
insert a row in that table, right above that qualifiying row as
follows:

The rendered html looks likes

<TR>
<TD nowrap="true" valign="top" width="190px" class="ms-
formlabel"><H3

The nowrap attribute is deprecated in HTML 4.01, it has been removed
from the HTML 5 draft. The CSS white-space property replaces it:

class="ms-standardheader">
<nobr>(HP)(H:whatever) Question</nobr>

There is no such element as nobr in HTML 4. You should use an HTML
validator, try:

</H3></TD>
<TD valign="top" class="ms-formbody" width="400px">

The result of the new code would look like this:

<tr><td>whatever</td></tr>

<TR>
<TD nowrap="true" valign="top" width="190px" class="ms-
formlabel"><H3

class="ms-standardheader">
<nobr>Question</nobr>

I suppose you want to change the text in the cell from:

(HP)(H:whatever) Question

to

Question

But your regular expression doesn't do that, it only removes the text
"(HP)".

</H3></TD>
<TD valign="top" class="ms-formbody" width="400px">

Thanks in advance for any help or information!

The subject of your post should reflect the content. I don't see
anywhere that you are inserting rows. Here's a re-write of your code:

var theRows = document.getElementsByTagName('TR');
var r = theRows.length;
var strTitle,
row,
cell;

while (r--) {
row = theRows[r];
cell = row.cells[0];

if (cell.className.indexOf('ms-formlabel') > -1) {

if (cell.innerHTML.indexOf("(HP)") == -1) {
row.style.display = "none";
} else {
cell.innerHTML = cell.innerHTML.replace("(HP)","");
}
}
}
 
J

jc

Rob,

Thank you for that - much cleaner indeed.

Sorry, my point in posting was to ask how I could insert a row header
(right before) rows with a matching "H:" and have the row text be the
string following the H: .. no attempt yet in the code below. Also,
note: I've removed the className condition for this test.

for example <TR><TD>testing</TD></TR>
would be inserted above <TR><td>QualifiesH(HP)(H:testing)</td></TR>


Thanks again.
JC

Code:
<html>
<head>
</head>
<body>
<table>
<TR><td>test</td></TR>
<TR><td>test2</td></TR>
<TR><td>test3</td></TR>
<TR><td>test4</td></TR>
<TR><td>Qualifies1(HP)</td></TR>
<TR><td>test</td></TR>
<TR><td>test2</td></TR>
<TR><td>test3</td></TR>
<TR><td>test4</td></TR>
<TR><td>Qualifies2(HP)</td></TR>
<TR><td>test</td></TR>
<TR><td>test2</td></TR>
<TR><td>test3</td></TR>
<TR><td>QualifiesH(HP)(H:testing)</td></TR>
<TR><td>test</td></TR>
<TR><td>test2</td></TR>
<TR><td>test3</td></TR>
</table>
</body>
</html>
<script type="text/javascript">
var theRows = document.getElementsByTagName('TR');
var r = theRows.length;
var strTitle,
row,
cell;


while (r--) {
row = theRows[r];
cell = row.cells[0];



if (cell.innerHTML.indexOf("(HP)") == -1) {
row.style.display = "none";
} else {
cell.innerHTML = cell.innerHTML.replace("(HP)","");
}
}
</script>
 
D

Dr J R Stockton

In comp.lang.javascript message <bbbe6981-5eb0-441c-840f-6417ea6681df@13
g2000prl.googlegroups.com>, Thu, 3 Dec 2009 16:22:21, RobG
You should indent your code with 2 or 4 spaces to make it easier to
read. The harder you make it, the less likely it is that people will
help.

You can indent code automatically with the "Indt" button in a copy of
<URL:http://www.merlyn.demon.co.uk/js-quick.htm>. It is designed to
ONLY alter the number of spaces at the beginning of a line, so it is
safe. It DOES NOT handle all possible code correctly (for example a
line containing unmatched {} within strings or comment), but it is
usually right.

And, since it is JavaScript, you can improve it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,709
Latest member
AustinMudi

Latest Threads

Top