skip to Main Content

I have HTML that looks like this:

<table>
  <tbody>
    <tr><td><button> Split </button></td></tr>
    <tr><td><button> Split </button></td></tr>
    <tr><td><button> Split </button></td></tr>
    <tr><td><button> Split </button></td></tr>
    <tr><td><button> Split </button></td></tr>
    <tr><td><button> Split </button></td></tr>
  </tbody>
</table>

My program should do the following when any one of the buttons are clicked:

  1. Split the ‘tbody’ node into two ‘tbody’ nodes. For instance, if you pressed the second button, the first two rows will be the children of one ‘tbody’ node and the other rows will be the children of another ‘tbody’ node.
  2. Create a new ‘tbody’ node right in between those two ‘tbody’ nodes.
  3. The innerHTML of the new ‘tbody’ node should be
<tr><td><p> Clicked </p></td></tr>

So if you click the second button, the desired html would be

<table>
  <tbody>
    <tr><td><button> Split </button></td></tr>
    <tr><td><button> Split </button></td></tr>
  </tbody>
  <tbody>
    <tr><td><p> Clicked </p></td></tr>
  </tbody>
  <tbody>
    <tr><td><button> Split </button></td></tr>
    <tr><td><button> Split </button></td></tr>
    <tr><td><button> Split </button></td></tr>
    <tr><td><button> Split </button></td></tr>
  </tbody>
</table>

However, my javascript program fails to do this.
This is my javascript code.

$("button").on("click", function() {
    var currentRow = $(this).parent().parent();
  var htmlStr =     "</tbody>";
  htmlStr +=        "<tbody>";
  htmlStr +=          "<tr><td><p>Clicked</p></td></tr>";
  htmlStr +=        "</tbody>";
  htmlStr +=        "<tbody>";
  currentRow.after(htmlStr);
  console.log($("table").html());
});

You can go to this JsFiddle link to test out my code and see what it ends up doing. Also, the last line of my code doesn’t print out html neatly. If you know how to make it print it in a better way, please let me know.

https://jsfiddle.net/kjvpruse/14/

2

Answers


  1. I think, you are targeting the wrong tag, you get the parent tr instead of getting the tbody parent.

    Tell me if this is what you expect ?

    $("button").click(function() {
        var selectedRow = $(this).parent().parent();
        var html = "</tbody><tbody><tr><td><p> Clicked </p></td></tr></tbody>";
      selectedRow.after(html);
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <table>
      <tbody>
        <tr><td><button> Split </button></td></tr>
        <tr><td><button> Split </button></td></tr>
        <tr><td><button> Split </button></td></tr>
        <tr><td><button> Split </button></td></tr>
        <tr><td><button> Split </button></td></tr>
        <tr><td><button> Split </button></td></tr>
      </tbody>
    </table>
    Login or Signup to reply.
  2. You cannot manipulate HTML with partial HTML strings. Any start tag will be completed automatically when you append it

    This was not trivial but works as expected

    $(function() {
      const $table = $("table");
      $table.on("click", "button", function() { // delegate to keep the event handler
        const $currentRow = $(this).closest("tr");
        const $currentTBody = $(this).closest("tbody");
    
        // All the rows before the clicked row
        const $prevRows = $currentRow.prevAll();
        // All the rows after the clicked row
        const $nextRows = $currentRow.nextAll();
    
        // Create and append a "Clicked!" row in a new tbody after the body of the clicked row
        const $clickedTBody = $(`<tbody><tr><td><p>Clicked! ${this.id}</p></td></tr></tbody>`);
    
        const $newPrevTBody = $prevRows.length > 0 ? $("<tbody></tbody>").append($prevRows) : null;
        const $newNextTBody = $nextRows.length > 0 ? $("<tbody></tbody>").append($nextRows) : null;
    
        // Gather elements in order to insert - remember to handle previously inserted tbodies
        const elementsToInsert = [
          ...$currentTBody.prevAll().get().reverse(), // prevAll are reversed
          $newPrevTBody,
          $clickedTBody,
          $newNextTBody,
          ...$currentTBody.nextAll()
        ].filter(Boolean); // Remove any null or undefined elements
    
        // Clear the table and insert the elements in the correct order
        $table.empty().append(elementsToInsert);
    
        // Remove the clicked row (not really necessary since we've already emptied the table and re-added rows, but kept for clarity)
        $currentRow.remove();
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <table id="tbl">
      <tbody>
        <tr>
          <td>
            <button id='x'> Split </button>
          </td>
          <td>
            <label for="x"> Add a new row after this row</label>
          </td>
        </tr>
        <tr>
          <td>
            <button id='y'> Split </button>
          </td>
          <td>
            <label for="y"> Add a new row after this row</label>
          </td>
        </tr>
        <tr>
          <td>
            <button id='z'> Split </button>
          </td>
          <td>
            <label for="z"> Add a new row after this row</label>
          </td>
        </tr>
      </tbody>
    </table>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search