I want to color HTML table rows based on regex and condition

Viewed 180

I have an 'order' table where the first column is the ID of orders. I want to set the background-color dependent on the last number of the ID column.

For example, if the Id is 23433 I want to be the color to be #adcbe3. I've tried the code below, but it's not working.

$(function() {
  $("tr").each(function() {
    var firstCol = $("tr").find("td:first");
    var reg1 = new RegExp("^[0-9]*[0369]$", 'g');
    var reg2 = new RegExp("^[0-9]*[147]$", 'g');
    var reg3 = new RegExp("^[0-9]*[258]$", 'g');
    if (String(firstCol).match(/^[0-9]*[0369]$/)) {
      $(this).addClass('row1'); //the selected class colors the row green//
    } else if (String(firstCol).match(/^[0-9]*[147]$/)) {
      $(this).addClass('row2');
    } else if (String(firstCol).match(/^[0-9]*[258]$/)) {
      $(this).addClass('row3');
    }
  });
});
.row1 {
  background: #adcbe3;
}

.row2 {
  background: #e7eff6;
}

.row3 {
  background: #d0e1f9;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

2 Answers

The issue is because the firstCol variable contains an entire jQuery object. From the context of your question it appears that you expect this to be the innerText of the td you select. In which case you need to use text().

In addition you need to use the this keyword within the each() loop to refer to the current tr only. Your current logic would add the class to every tr in the DOM.

$(function() {
  $("tr").each(function() {
    var firstCol = $(this).find("td:first").text();
    if (firstCol.match(/^[0-9]*[0369]$/)) {
      $(this).addClass('row1');
    } else if (firstCol.match(/^[0-9]*[147]$/)) {
      $(this).addClass('row2');
    } else if (firstCol.match(/^[0-9]*[258]$/)) {
      $(this).addClass('row3');
    }
  });
});
.row1 { background: #adcbe3; }
.row2 { background: #e7eff6; }
.row3 { background: #d0e1f9; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr><td>23433</td></tr>
  <tr><td>23434</td></tr>
  <tr><td>23435</td></tr>
  <tr><td>23436</td></tr>
  <tr><td>23444</td></tr>
</table>

Alternatively you can make the logic more succinct by using a Regex to validate that the Id is a purely numerical value and then using slice() to take its last character to apply the relevant class, something like this:

jQuery($ => {
  $('tr').addClass(function() {
    let id = $(this).find('td:first').text();
    return !id.match(/^[0-9]+$/) ? null : 'row' + ((parseInt(id.slice(-1), 10) || 0) % 3 + 1);
  });
});
.row1 { background: #adcbe3; }
.row2 { background: #e7eff6; }
.row3 { background: #d0e1f9; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr><td>23433</td></tr>
  <tr><td>23434</td></tr>
  <tr><td>23435</td></tr>
  <tr><td>foo</td></tr>
  <tr><td>23436</td></tr>
</table>

You do not need a regex at all - all you are doing is applying a class based on a grouping of each number with a spread of 3 and this can be determined by the modulus operator.

Note that there are three rows that are different and onw row that is replicated.

All you have to do is to get the text of the first column, get the last character of that and because your grouping the items the way you are - the class can be applied through the modulus of 3. The final addition of 1 is purely because the numbers are zero-indexed but your classes are 1-indexed (the first row is row1 not row0).

$(function() {
  $("tr").each(function() {
    var firstCol = $(this).find("td").first().text();
    var lastChar = firstCol.charAt(firstCol.length-1);
    var index = (parseInt(lastChar) % 3)+1;
    $(this).addClass('row'+ index)
  });
});
.row1 {
  background: #adcbe3;
}

.row2 {
  background: #e7eff6;
}

.row3 {
  background: #d0e1f9;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<table>
  <tr><td>23430</td></tr>
  <tr><td>23431</td></tr>
  <tr><td>23432</td></tr>
  <tr><td>23433</td></tr>
  <tr><td>23434</td></tr>
  <tr><td>23435</td></tr>
  <tr><td>23436</td></tr>
  <tr><td>23437</td></tr>
  <tr><td>234338</td></tr>
  <tr><td>23439</td></tr>
  <tr><td>23433</td></tr>
</table>

Related