Inserting Table Rows conditionally

Discussion in 'Javascript' started by jc, Dec 2, 2009.

  1. jc

    jc Guest

    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!
     
    jc, Dec 2, 2009
    #1
    1. Advertisements

  2. jc

    RobG Guest

    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.
    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.

    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.

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

    Row elements have a cells collection that may suit better.
    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... )
    Presuming strTitle is a string.

    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.

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

    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:

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

    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)".

    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)","");
    }
    }
    }
     
    RobG, Dec 4, 2009
    #2
    1. Advertisements

  3. jc

    jc Guest

    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 (Text):

    <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>
     
     
    jc, Dec 4, 2009
    #3
  4. In comp.lang.javascript message <[email protected]
    g2000prl.googlegroups.com>, Thu, 3 Dec 2009 16:22:21, RobG
    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.
     
    Dr J R Stockton, Dec 5, 2009
    #4
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.