ChartProblems
ChartProblems

Reputation: 437

Table column to change color upon hover

I have been piecing together a table format by using a range of templates that I have found online (am not a skilled programmer myself). I am trying to create a table that will highlight both the entire row and column when you hover over a specific table cell while it also includes a scrolling feature with the top row fixed. I have figured out how to highlight the row but am having difficulties with the column.

I have created a JSFiddle, which should reveal the problem: https://jsfiddle.net/n2p0zj6m/4/

I am using the code below to add the relevant classes to the table upon hover of a table cell. I am very sure that the error lies in this code somewhere but I can't figure out why this doesn't work.

  (function ($) {
    "use strict";
    $('.column100').on('mouseover',function(){
        var table1 = $(this).parent().parent().parent();
        var table2 = $(this).parent().parent();
        var verTable = $(table1).data('vertable')+"";
        var column = $(this).data('column') + "";

        $(table2).find("."+column).addClass('hov-column-'+ verTable);
        $(table1).find(".row100.head ."+column).addClass('hov-column-head-'+ verTable);
    });

    $('.column100').on('mouseout',function(){
        var table1 = $(this).parent().parent().parent();
        var table2 = $(this).parent().parent();
        var verTable = $(table1).data('vertable')+"";
        var column = $(this).data('column') + "";

        $(table2).find("."+column).removeClass('hov-column-'+ verTable);
        $(table1).find(".row100.head ."+column).removeClass('hov-column-head-'+ verTable);
    });
  })(jQuery);

I will also include a snippet of the HTML structure below:

  <div class="tbl-header">
    <table data-vertable="ver1" cellpadding="0" cellspacing="0" border="0">
      <thead>
        <tr class="row100 head">
          <th class="column100 column1" data-column="column1">Code</th>
          <th class="column100 column2" data-column="column2">Company</th>
          <th class="column100 column3" data-column="column3">Price</th>
          <th class="column100 column4" data-column="column4">Change</th>
          <th class="column100 column5" data-column="column5">Change %</th>
        </tr>
      </thead>
    </table>
  </div>
  <div class="tbl-content">
    <table data-vertable="ver1" cellpadding="0" cellspacing="0" border="0">
      <tbody>
        <tr class="row100">
          <td class="column100 column1" data-column="column1">AAC</td>
          <td class="column100 column2" data-column="column2">AUSTRALIAN COMPANY </td>
          <td class="column100 column3" data-column="column3">$1.38</td>
          <td class="column100 column4" data-column="column4">+2.01</td>
          <td class="column100 column5" data-column="column5">-0.36%</td>
        </tr>

Upvotes: 0

Views: 1243

Answers (2)

Matthew Moore
Matthew Moore

Reputation: 866

One thing, is there's no need to separate the various levels of the table into different divs - this creates issues, and will confuse any robots/accessibility technology. In my snippet below, I've merged it into a single table. Using thead and tbody instead.

Also, with the approach I use (collecting the index of the cell - thus its column) there's no need for extra data-x or classes for tracking. And if your goal is for styling purposes, you should look into :nth-child() to create alternating rows and the like.

$('tbody td').on('mouseover', function() { // Triggers when a table cell is hovered under a tbody
  column = $(this).index(); // Find which column the cell belongs to (its index amongst its siblings)

  $(this).parent().siblings().each(function() { // loop over all rows except current (the siblings)
    $(this).children().eq(column).addClass('colHover'); // addClass to the cell in the same column
  });
});

$('tbody td').on('mouseout', function() { // Triggers when leaving a table cell
  $(this).parent().siblings().each(function() {
    $(this).children().removeClass('colHover'); // removeClass from all children, of all siblings
  });
});
table thead tr {
  background-color: #AAA;
}

table td,
table th {
  padding: .5em .75em;
}

table tr td:nth-child(n+2) {
  text-align: center;
}

table tbody tr:hover,
table tbody tr td.colHover {
  background-color: #FFDDFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tblFinance">
  <table data-vertable="ver1" cellpadding="0" cellspacing="0" border="0">
    <thead>
      <tr>
        <th>Code</th>
        <th>Company</th>
        <th>Price</th>
        <th>Change</th>
        <th>Change %</th>
      </tr>
    </thead>
    <tbody>
      <tr class="row100">
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr class="row101">
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr class="row102">
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr class="row103">
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
    </tbody>
  </table>
</div>

EDIT: I've built an extra function, which attaches an event to scrolling. Once the user has scrolled to (or past) the top of the table, the <tr> inside the <thead> becomes "sticky" - it applies position: fixed, and adjusts the table to handle the missing row without bouncing the page around.

NOTE: This is NOT very scalable, in its current form. It will only really support a single "sticky" element, in the specific table.

$(document).ready(() => {
  var tblObject = $('table#tblFinance');
  var tblTop = tblObject.offset().top; // Find Table's offset from the top of the page
  var tblSticky = false; // reduce redundant conditional spam

  $(window).scroll(() => {
    if (!tblSticky && $(document).scrollTop() >= tblTop) {
      // If Sticky is OFF, and user scrolls to/below the table's top

      tblObject.find('thead tr').css('position', 'fixed'); // Set Position: fixed
      tblObject.css('padding-top', tblObject.find('thead tr').outerHeight() + 'px'); // Add padding to table, to account for <tr> being removed from the flow
      tblSticky = true; // Enable Sticky

    } else if (tblSticky && $(document).scrollTop() <= tblTop) {
      // If Sticky is ON, and user scrolls to/above the table's top

      tblObject.find('thead tr').css('position', 'static'); // Set Position: Static
      tblObject.css('padding-top', '0'); // Remove padding; <tr> is back in the flow
      tblSticky = false; //Disable Sticky

    }
  });
});

$('tbody td').on('mouseover', function() { // Triggers when a table cell is hovered under a tbody
  column = $(this).index(); // Find which column the cell belongs to (its index amongst its siblings)

  $(this).parent().siblings().each(function() { // loop over all rows except current (the siblings)
    $(this).children().eq(column).addClass('colHover'); // addClass to the cell in the same column
  });
});

$('tbody td').on('mouseout', function() { // Triggers when leaving a table cell
  $(this).parent().siblings().each(function() {
    $(this).children().removeClass('colHover'); // removeClass from all children, of all siblings
  });
});
table {
  text-align: center;
}

table thead tr {
  top: 0;
  background-color: #AAA;
}

table td,
table th {
  padding: .5em .75em;
}

table td:first-child,
table th:first-child {
  width: 80px;
}

table td:nth-child(2),
table th:nth-child(2) {
  width: 300px;
}

table td:nth-child(n+3),
table th:nth-child(n+3) {
  width: 100px;
}

table tbody tr:hover,
table tbody tr td.colHover {
  background-color: #FFDDFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <h1>Title</h1>
  <p>Some content, to push the table down a bit.</p>

  <table id="tblFinance" data-vertable="ver1" cellpadding="0" cellspacing="0" border="0">
    <thead>
      <tr>
        <th>Code</th>
        <th>Company</th>
        <th>Price</th>
        <th>Change</th>
        <th>Change %</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>AAA</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>BBB</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>CCC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>DDD</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
      <tr>
        <td>AAC</td>
        <td>AUSTRALIAN COMPANY </td>
        <td>$1.38</td>
        <td>+2.01</td>
        <td>-0.36%</td>
      </tr>
    </tbody>
  </table>
</div>

Upvotes: 2

Kamae
Kamae

Reputation: 551

If I understood correctly, I think your problem is in the CSS. Your columns are getting the right class hov-column-ver1, but in the CSS you are only giving the green background to the elements under tbl-header:

.tbl-header .hov-column-ver1 {
  background-color: green;
}

You need to add the style for the elements under tbl-content. Add this in your CSS block:

.tbl-content .hov-column-ver1 {
  background-color: green;
}

Is this what you meant?

P.S. Please consider to review the closest() element in jQuery. Instead of using .parent().parent().parent() you could use .closest("table"). IMHO it is really useful in case the HTML structure changes as it will not affect your JS code. It is also more friendly to read :)

Upvotes: 1

Related Questions