tags:

views:

41

answers:

3

The DOM structure looks like this (existing website ... cant modify it):

<table>
<tr><td>
<br><hr size="1"><strong>some heading 1</strong><br>
<br>some text 1<br>

<br><hr size="1"><strong>some heading 2</strong><br>
<br>some text 2<br>
</td></tr>
</table>

I want to manipulate it so that it looks like this

<table>
<tr><td>
<br><hr size="1"><strong>some heading 1</strong><br>
<br>some text 1<br>
</td></tr>
<tr><td>
<br><hr size="1"><strong>some heading 2</strong><br>
<br>some text 2<br>
</td></tr>
</table>

Using the solution posted here, I am able to get hold of the hr, strong, br tags and move them into new td elements. However, I am not able to get hold of "some text 1" since it is directly contained within the td and using .text() on td will give me both "some text 1" as well as "some text 2".

Any idea?

+1  A: 

Maybe try this, it's not pretty but it should work...

html = $("table tr td").html();
someText1 = html.split("<br>")[3];
someText2 = html.split("<br>")[7];

That will give you the text that you were unable to parse out and you seem to have the rest figured out.

Ryan
Thanks for the reply but I can't use the above since "some text 1" is actually the body of a forum post which can contain 'br' and other tags.
atlantis
A: 

Yeah, jQuery doesn't help much with text nodes. You often have to use regular DOM methods. Something like:

// Split on each `<hr>` inside a table cell except the first
//
$(mytablecell).children('hr').slice(1).each(function() {
    // Create the next row
    //
    var rowi= mytablecell.parentNode.rowIndex;
    var newrow= $(mytablecell).closest('table')[0].insertRow(rowi+1);
    var newcell= newrow.insertCell(0);

    // Move all nodes starting with the current `<hr>` into the next row
    //
    var node, next= this;
    while (node= next) {
        var next= node.nextSibling;
        newcell.appendChild(node);
    }
});
bobince
Got an exception at parentNode. Didn't probe further since Arrix's code worked.
atlantis
parentNode should be fine. `mytablecell` should be a DOM Node; if it's a jQuery wrapper, get a `[0]` from it to get the node.
bobince
It was a jQ wrapper. Thanks for the correction.
atlantis
+2  A: 

You can use .contents() to collect all children including text nodes. The following code searches for the second hr (to be robust) and moves the preceding br and everything behind to the newly created td. I've tested it in google chrome.

$('table tr td').each(function() {
    var firtHrSeen = false;
    var indexOfSecondHr = -1;
    var allChildren = $(this).contents();
    allChildren.each(function(index) {
        if ($(this).is('hr')) {
            if (firtHrSeen) {
                indexOfSecondHr = index;
                return false; // break out of each()
            } else {
                firtHrSeen = true;
            }
        }
    });

    if (indexOfSecondHr != -1) {
        var newTd = ($('<tr><td></td></tr>').insertAfter(this.parentNode))[0].firstChild;
        allChildren.slice(indexOfSecondHr - 1).each(function(index) {
            newTd.appendChild(this);
        });
    } else {
        // not found. something went wrong
    }
}); 
Arrix
Thanks!! This did it. I just inserted a new tr and put the new td in this new tr.
atlantis
I am referring to the printable version of myBB based threads. What I am trying to do is, put each response of the thread into its own row so that I can highlight certain rows based on username etc. I tried to adapt the above code to put it into a loop so that all responses (which are separated by hr tags) are put into separate rows but it gives me weird results. If you have any insights do let me know.
atlantis
I must have misread the requirement. I've corrected the code so that it inserts a table row instead of a column.
Arrix