icza
icza

Reputation: 417592

Switching rows of table only works for 2nd time

Here's a simple HTML <table> with 2 rows, each row having links to move the row up/down:

<table border=1>
    <tr>
        <td>Row A</td>
        <td>
            <a href="javascript:void(0)" onclick="up(this)">Up</a>
            <a href="javascript:void(0)" onclick="down(this)">Down</a>
        </td>
    </tr>
    <tr>
        <td>Row B</td>
        <td>
            <a href="javascript:void(0)" onclick="up(this)">Up</a>
            <a href="javascript:void(0)" onclick="down(this)">Down</a>
        </td>
    </tr>
</table>

<script>
    function up(link) {
        var row = link.parentNode.parentNode;
        var prevRow = row.previousSibling;
        if (prevRow != null) {
            row.parentNode.insertBefore(row, prevRow);
        }
    }
    function down(link) {
        var row = link.parentNode.parentNode;
        var nextRow = row.nextSibling;
        if (nextRow != null) {
            row.parentNode.insertBefore(nextRow, row);
        }
    }
</script>

Why is it that clicking on Down link of the first row does nothing at first (no errors), but works for second click? Similarly clicking on the Up link of the 2nd row does nothing at first, but starts working afterwards?

Moreover, if I click on a link that cannot be executed (e.g. Up of the first row or Down of the last row), then the other link of the same row that should work (Down of the first row) doesn't work on subsequent click, but works if clicked again?

What should I do / change so that links work on first click as they should be?

Upvotes: 0

Views: 61

Answers (1)

Lixus
Lixus

Reputation: 511

Because whitespace is also a node previousSibling / nextSibling returns #text on your first call to any of your functions, after that it fixes itself. So to get it to work the first time change to previousElementSibling / nextElementSibling

<table border=1>
    <tr>
        <td>Row A</td>
        <td>
            <a href="javascript:void(0)" onclick="up(this)">Up</a>
            <a href="javascript:void(0)" onclick="down(this)">Down</a>
        </td>
    </tr>
    <tr>
        <td>Row B</td>
        <td>
            <a href="javascript:void(0)" onclick="up(this)">Up</a>
            <a href="javascript:void(0)" onclick="down(this)">Down</a>
        </td>
    </tr>
</table>

<script>
    function up(link) {
        var r = link.parentNode.parentNode;
        var rp = r.previousElementSibling;
        if (rp != null) {
            r.parentNode.insertBefore(r, rp);
        }
    }
    function down(link) {
        var r = link.parentNode.parentNode;
        var rn = r.nextElementSibling;
        if (rn != null) {
            r.parentNode.insertBefore(rn, r);
        }
    }
</script>

Upvotes: 3

Related Questions