How can I remove all rows from a table except rows where first TD value is equal to "Revisions Required – CM" using jquery?

//Code that I have tried but it doesnt work:
$('#historyOfStatus table td').not(':contains("Revisions Required – CM")').parents("tr").remove(); 
<div id="historyOfStatus">
   <table>
      <tbody>
         <tr>
            <th>Value</th>
            <th>Date Time</th>
            <th>By</th>
         </tr>
         <tr>
            <td class="Data1">Draft</td>
            <td class="Data1">2022-11-14 13:34:31</td>
            <td class="Data1">Muhammad Akhtar</td>
         </tr>        
         <tr>
            <td class="Data1">Revisions Required – CM</td>
            <td class="Data1">2022-11-14 13:40:18</td>
            <td class="Data1">a</td>
         </tr>
         <tr>
            <td class="Data2">Under CFF Contracts Manager Review</td>
            <td class="Data2">2022-11-14 13:41:38</td>
            <td class="Data2">aa</td>
         </tr>
         <tr>
            <td class="Data1">Under CFF Compliance Review</td>
            <td class="Data1">2022-11-14 13:41:43</td>
            <td class="Data1">aaaa</td>
         </tr>
         <tr>
            <td class="Data2">Revisions Required – CM</td>
            <td class="Data2">2022-11-14 13:41:48</td>
            <td class="Data2">bb</td>
         </tr>         
         <tr>
            <td class="Data2">Revisions Required – CM</td>
            <td class="Data2">2022-11-14 13:43:10</td>
            <td class="Data2">cc</td>
         </tr>
      </tbody>
   </table>
</div>


Hi,

The syntax would be like this:

$('#historyOfStatus table td:not(:contains("Revisions Required – CM"))').parent().remove()

Notice the use of the :not selector, as opposed to the .not method.

However, looping through every td like this wont work, as every row will contain a td element that doesn’t contain the text “Revisions Required – CM”, so this will just remove everything.

You could do this:

$('#historyOfStatus table td:first-child:not(:contains("Revisions Required – CM"))').parent().remove();

This selects the first td in every tr, but TBH this is ugly and hard to parse.

I would be tempted to do something like the following:

$('#historyOfStatus table tr').each(function() {
  const textContentOfFirstCell = $(this).find('td').first().text();
  if (!textContentOfFirstCell.match(/Revisions Required – CM|^$/)) {
    this.remove();
  }
});

Also, you used jQuery in your question, but this is not strictly necessary. In vanilla JS you could do something like this:

const tableRows = document.querySelectorAll('#historyOfStatus table tr');
tableRows.forEach(function(el) {
  const firstCell = el.querySelector('td');
  if (!firstCell) return; // Leaves the header intact

  if (firstCell.innerText !== 'Revisions Required – CM') {
    el.parentNode.removeChild(el);
  }
});
1 Like

Txs, it works.