Search code examples
htmljquerycsscss-tables

I need to prepend every tr row of a table with an icon that doesn't ocupy a td cell


I want my table to have an icon in front of every row that isnt in a td cell, so that when i hover over every row, the icon fades in. If i add it as a td to my rows, then my client id cell, which is supposed to be the first cell in every row, won't be the first anymore. So the icon would be "floating" on hover in front of every row.

CSS, html or jquery, which achieves this best and how?

I tried adding a div in front of the first td but it didn't even appear in my table. Also adding a td cell and making the background and border empty doesn't fix my problem, because my table has a box-shadow, already tried that, its not nice.

<table>
    <tr>
        <th>Invoice # <i class="fas fa-angle-down"></i></th>
        <th>Client <i class="fas fa-angle-down"></i></th>
        <th>Amount <i class="fas fa-angle-down"></i></th>
        <th>Balance <i class="fas fa-angle-down"></i></th>
        <th>Date <i class="fas fa-angle-down"></i></th>
        <th>Status <i class="fas fa-angle-down"></i></th>
        <th style="width: 100px">Generate Invoice</th>
    </tr>
    <tr>
        <div><i class="fas fa-angle-down"></i></div><!--this needs to be apart -->
        <td>1</td>
        <td>1</td>
        <td>1</td>
        <td>1</td>
        <td>1</td>
        <td>1</td>
        <td>1</td>
        <td>1</td>
    </tr>
</table>

enter image description here


Solution

  • Consider the following jQuery solution.

    $(function() {
      $("table > tbody > tr").hover(function(e) {
        var pos = $(this).position();
        var icon_wrap = $("<div>", {
          class: "marker"
        }).appendTo("body").hide();
        var icon = $("<i>", {
          class: "fas fa-angle-down"
        }).appendTo(icon_wrap);
        icon_wrap.css({
          top: (pos.top + 6) + "px",
          left: pos.left + "px"
        }).fadeIn("fast");
      }, function() {
        $(".marker").fadeOut("fast", function() {
          $(this).remove();
        });
      });
    });
    .marker {
      width: 8px;
      height: 20px;
      background-color: #99f;
      position: absolute;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <table>
      <thead>
        <tr>
          <th>Invoice # <i class="fas fa-angle-down"></i></th>
          <th>Client <i class="fas fa-angle-down"></i></th>
          <th>Amount <i class="fas fa-angle-down"></i></th>
          <th>Balance <i class="fas fa-angle-down"></i></th>
          <th>Date <i class="fas fa-angle-down"></i></th>
          <th>Status <i class="fas fa-angle-down"></i></th>
          <th style="width: 100px">Generate Invoice</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>1</td>
          <td>2</td>
          <td>3</td>
          <td>4</td>
          <td>5</td>
          <td>6</td>
          <td>8</td>
          <td>9</td>
        </tr>
        <tr>
          <td>1</td>
          <td>2</td>
          <td>3</td>
          <td>4</td>
          <td>5</td>
          <td>6</td>
          <td>8</td>
          <td>9</td>
        </tr>
        <tr>
          <td>1</td>
          <td>2</td>
          <td>3</td>
          <td>4</td>
          <td>5</td>
          <td>6</td>
          <td>8</td>
          <td>9</td>
        </tr>
      </tbody>
    </table>

    This uses .hover(), which has in and out function callbacks. You can simply add a Class and use a :before psudeo element using content: "". With jQuery, you can use easing with .fadeIn() and .fadeOut().