Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I highlight only the innermost table row of a nested table?

I have several nested tables and I want to highlight the innermost row that is below the mouse pointer. How can I do that?

Some pointers: I use nested tables to display recursive tabular data. The tables can be nested 10 levels deep. The nesting is just like you would expect:

<table><tr><td>
   <table><tr><td>
      <table><tr><td>
          ...

There are can be rows which don't have nested tables. I want the highlight on the deepest / innermost <tr> that is under the mouse cursor.

I can use CSS or jQuery.

like image 661
Aaron Digulla Avatar asked Sep 18 '13 14:09

Aaron Digulla


People also ask

Can tables be nested table inside another table?

A table can be created within another table by simply using the table tags like <table>, <tr>, <td>, etc., to create our nested table. Since nesting tables can lead to higher complexity levels, remember to begin and end the nesting tables within the same cell.

How do I nest a table within a table?

To create a nested table, we need to create a table using the <table> tag. This table is known as the outer table. The second table that will be nested table is called the inner table. This table is also created using the <table> tag but there is a special thing that must be kept in mind.

What does a nested table look like?

Nested tables are single-dimensional, unbounded collections of homogeneous elements. First, a nested table is single-dimensional, meaning that each row has a single column of data like a one-dimension array. Second, a nested table is unbounded. It means that the number of elements of a nested table is predetermined.


2 Answers

I would like to propose something slightly more elegant (at least shorter):

Using delegated mouse events:

$('#mainTable').on('mouseenter mouseleave', 'tr', {el: false}, function (e) {
    var hl = e.data.el;
    hl && hl.removeClass('hover');

    e.data.el = (e.type === 'mouseenter') ?
        $(this).addClass('hover') :
        $(this).parent().closest('tr:hover').addClass('hover');
});

It stores the currently highlighted node in the (persistent) delegated data object and handles the mouse events, as follows:

  • If the mouse enters an element (the innermost hovered tr), remove the current highlight and highlight current element.
  • If the mouse leaves an element, highlight the closest hovered ancestor tr instead of the current one.

The main advantages of solutions using event delegation (such as $.delegate() and $.on() with a selector) are attaching only a single event listener (compared to potentially dozens, hundreds or more using traditional, per-element, methods) and being able to support dynamic changes to the element.

I chose this solution over the use if the mouseover event since I believe the enter/leave events should provide better performance, as they do not bubble.

JSFiddle.

Note:

It has a problem with jQuery 1.9.x but works with the rest, as far as I tested, including newer and older releases. This is due to an issue with the :hover pseudo-selector in that version.


CSS4

CSS level-4 has a suggested feature that can enable this behavior using CSS only:

tr, !tr:hover tr:hover {
    background-color: transparent;
}
tr:hover {
    background-color: #DDFF75;
}

Of course, since this feature is not currently final and is not supported by any major browser at the moment, this section will serve as future reference.

like image 96
MasterAM Avatar answered Nov 07 '22 09:11

MasterAM


Using javascript mouse events, the event target should be the deepest element:

$('tr').mouseover(function(e){
    $(e.target).parents('tr').removeClass('hover').first().addClass('hover');
});

And this to clear when mouse leaves the table:

$('#main-table').mouseout(function(e){
    $(this).find('tr').removeClass('hover');
});         

http://jsfiddle.net/tN865/1/

like image 40
Hugo Silva Avatar answered Nov 07 '22 10:11

Hugo Silva