ALLIGAT0R_BL00D
ALLIGAT0R_BL00D

Reputation: 53

table alternating colored rows. Keep styles on table rows with attribute, skip other tr's. preferably done by CSS

I'm working on a table that has clickable rows. When you click a row, a new row will be appended right after the one you clicked.

// before click
<tr role=row>...</tr>
<tr role=row>...</tr>

//after clicking the 1st tr
<tr role=row>...</tr>
<tr>...</tr>
<tr role=row>...</tr>

What I need is that the rows with role="row" get alternating colors and the trs without the role get ignored.

This is what I have so far:

$('tr[role=row]').click(function () {
  if ($(this).attr('data-toggle') != 0) {
  $(this).after('<tr colspan="4"><td>-</td></tr>')
    .attr('data-toggle', 0);
  }
});
.myclass > tbody > tr[role=row]:nth-child(odd) td {
    background-color: #fad;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="myclass">
  <thead>
    <tr role="row">
      <th>head 1</th>
      <th>head 2</th>
      <th>head 3</th>
      <th>head 4</th>
    </tr>
  </thead>
  <tbody>
    <tr role="row">
      <td>should</td>
      <td>be</td>
      <td>colored</td>
      <td>!</td>
    </tr>
    <tr role="row">
      <td>no</td>
      <td>color</td>
      <td>-</td>
      <td>-</td>
    </tr>
    <tr role="row">
      <td>should</td>
      <td>be</td>
      <td>colored</td>
      <td>!</td>
    </tr>
    <tr role="row">
      <td>no</td>
      <td>color</td>
      <td>-</td>
      <td>-</td>
    </tr>
  </tbody>
</table>

The problem is whenever you add a new row (without role) it still counts for the css selector and the rows with role="row" get wrongly changed.

In short: I want a zebra style only applied on trs with role="row" that keep their color even when a row is inserted

If it can't be done in CSS, jquery is also fine.

Any help & feedback would be appreciated!

EDIT:

  1. Temani Afif's answer is nice, but I need to keep this table as it is.
  2. The third solution of Temani Afif's works best for me.

Upvotes: 4

Views: 202

Answers (1)

Temani Afif
Temani Afif

Reputation: 272771

Redo the table logic using your own elements and you can easily achieve this with nth-of-type if you insert a different type of element:

$('[role=row]').click(function () {
  if ($(this).attr('data-toggle') != 0) {
  $(this).after('<section><span >-</span></section>')
    .attr('data-toggle', 0);
  }
});
.myclass [role=row]:nth-of-type(odd) * {
    background-color: #fad;
}
.myclass {
  display:table;
  border-spacing:2px;
}
.myclass > * {
  display:table-row;
}
.myclass > * > * {
  display:table-cell;
}
header {
  font-weight:bold;
}

tbody > div {
  display:table-row;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="myclass">
    <header>
      <span>head 1</span>
      <span>head 2</span>
      <span>head 3</span>
      <span>head 4</span>
    </header>
    <div role="row">
      <span>should</span>
      <span>be</span>
      <span>colored</span>
      <span>!</span>
    </div>
    <div role="row">
      <span>no</span>
      <span>color</span>
      <span>-</span>
      <span>-</span>
    </div>
    <div role="row">
      <span>should</span>
      <span>be</span>
      <span>colored</span>
      <span>!</span>
    </div>
    <div role="row">
      <span>no</span>
      <span>color</span>
      <span>-</span>
      <span>-</span>
    </div>
</div>

Or a hacky idea (I insist on hacky) is to introduce a different element while keeping the table:

$('tr[role=row]').click(function () {
  if ($(this).attr('data-toggle') != 0) {
  $(this).after('<div><td>-</td></div>')
    .attr('data-toggle', 0);
  }
});
.myclass > tbody > tr[role=row]:nth-of-type(odd) td {
    background-color: #fad;
}

.myclass > tbody > div {
  display:table-row;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="myclass">
  <thead>
    <tr role="row">
      <th>head 1</th>
      <th>head 2</th>
      <th>head 3</th>
      <th>head 4</th>
    </tr>
  </thead>
  <tbody>
    <tr role="row">
      <td>should</td>
      <td>be</td>
      <td>colored</td>
      <td>!</td>
    </tr>
    <tr role="row">
      <td>no</td>
      <td>color</td>
      <td>-</td>
      <td>-</td>
    </tr>
    <tr role="row">
      <td>should</td>
      <td>be</td>
      <td>colored</td>
      <td>!</td>
    </tr>
    <tr role="row">
      <td>no</td>
      <td>color</td>
      <td>-</td>
      <td>-</td>
    </tr>
  </tbody>
</table>

Or simply initialize the coloration using jQuery:

$('.myclass > tbody > tr[role=row]:nth-of-type(odd) td').css('background-color','#fad')

$('tr[role=row]').click(function () {
  if ($(this).attr('data-toggle') != 0) {
  $(this).after('<tr><td>-</td></tr>')
    .attr('data-toggle', 0);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="myclass">
  <thead>
    <tr role="row">
      <th>head 1</th>
      <th>head 2</th>
      <th>head 3</th>
      <th>head 4</th>
    </tr>
  </thead>
  <tbody>
    <tr role="row">
      <td>should</td>
      <td>be</td>
      <td>colored</td>
      <td>!</td>
    </tr>
    <tr role="row">
      <td>no</td>
      <td>color</td>
      <td>-</td>
      <td>-</td>
    </tr>
    <tr role="row">
      <td>should</td>
      <td>be</td>
      <td>colored</td>
      <td>!</td>
    </tr>
    <tr role="row">
      <td>no</td>
      <td>color</td>
      <td>-</td>
      <td>-</td>
    </tr>
  </tbody>
</table>

Upvotes: 3

Related Questions