skip to Main Content

I have 4 columns and about 10 rows in a table. I’m trying to have an onclick event that searches through the row that was clicked and removes "T" from that row but right now it’s searching and removing all the "T" from the table, not just the row clicked. What should I change?

$('#table_output tbody').on('click', 'tr', function() {
    console.log(table.row(this).data());
    $(':contains("T")').each(function(){
        $(this).html($this).html().split("T").join(""));
    });
    alert(JSON.stringify(table.row(this).data()));
})

2

Answers


  1. :contains("T") will find every element that contains ‘T’. I replaced that with $(this).find(':contains("T")'), which searches only within the children of the <tr> that was clicked.

    You also had a few typos that I fixed, as well as some unknown variables like table, which I’ve commented out.

    $('#table_output tbody').on('click', 'tr', function() {
        //console.log(table.row(this).data());
        $(this).find(':contains("T")').each(function(){
            //$(this).html($(this).html().split("T").join(""));
            $(this).html($(this).html().split("T").join(""))
        });
        //alert(JSON.stringify(table.row(this).data()));
    })
    <script src="https://code.jquery.com/jquery-3.6.1.js" integrity="sha256-3zlB5s2uwoUzrXK3BT7AX3FyvojsraNFxCc2vC/7pNI=" crossorigin="anonymous"></script>
    
    <table id="table_output">
    <tbody>
    <tr>
        <td>Total</td>
        <td>Tee Time</td>
        <td>Food for Thought</td>
    </tr>
    <tr>
        <td>Total</td>
        <td>Tee Time</td>
        <td>Food for Thought</td>
    </tr>
    <tr>
        <td>Total</td>
        <td>Tee Time</td>
        <td>Food for Thought</td>
    </tr>
    </tbody>
    </table>
    Login or Signup to reply.
  2. Here is another take on the script. I chose to operate solely on actual text nodes (this.nodeType===Node.TEXT_NODE). This will reliably avoid messing up html markup in the process. In my example I replace all lowercase "t" with empty strings (""). Applying a .replaceAll("t","") directly on the innerHTML string of an element containing "t" would mess up the inner table table structure in my second row. By limiting the action on text nodes only everything still stays intact:

    $('#table_output tbody').on('click', 'tr', function() {
      const repl="t";
      $(`:contains(${repl})`,this).contents().each(function(){
        if (this.nodeType===Node.TEXT_NODE && this.textContent.includes(repl))
          this.textContent=this.textContent.replaceAll(repl,"");
      }); 
    })
    <script src="https://code.jquery.com/jquery-3.6.1.js"></script>
    
    <table id="table_output">
    <tbody>
    <tr>
        <td>Total</td>
        <td>Tea time</td>
        <td>Food for thought</td>
    </tr>
    <tr>
        <td>total</td>
        <td>tea time
         <TABLE>
          <tr><TD>attitude</TD><TD>beta</TD></tr>
          <tr><TD>gamma</TD><TD>delta</TD></tr>
         </TABLE>
        </td>
        <td>Food for thought</td>
    </tr>
    <tr>
        <td>Total</td>
        <td>tea time</td>
        <td>Food for Thought</td>
    </tr>
    </tbody>
    </table>

    Just out of interest I looked for a way to find text nodes of an element without using jQuery. And there is such a way:

    function getTextNodesIn(elem, opt_fnFilter) {
      var textNodes = [];
      elem && [...elem.childNodes].forEach(n=>{
        if (n.nodeType == 3 && (!opt_fn()Filter || opt_fnFilter(n, elem))) textNodes.push(n);
        else if ([1,9,11].includes(n.nodeType)) textNodes = textNodes.concat(getTextNodesIn(n, opt_fnFilter));
      });
      return textNodes;
    }
    

    I got this – in a slightly longer form – from Chris West’s Blog.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search