You are viewing limited content. For full access, please sign in.

Question

Question

Tool Tip to Table Rows

asked on January 6, 2017 Show version history

I'm looking to add some type of tool tip to my table rows. I know this functionality isn't available right now. but is there any work around that can be created. I have looked on http://www.w3schools.com/ and haven't had any luck. Any help would be great.

0 0

Answer

SELECTED ANSWER
replied on January 6, 2017 Show version history

The rows aren't given unique IDs like the columns are. However you could use pseudoselectors on the tr elements of the table. I gave the table element in Forms the ".table" class for reference, then used the following JavaScript:

$(document).ready(function () {
  $('.table tr:first-child').attr('title','The "Get it" row comes first.');
  $('.table tr:nth-child(2)').attr('title','Next comes the "Want it" row, second.');
  $('.table tr:last-child').attr('title','Last of all comes the "Capacity" row.');
});

This had the result in the attached video table-tooltip.swf. (I wasn't actually clicked into the browser at first, so there's a little delay in the beginning.)

A couple of notes:

  1. As-written, the above will cause the tooltip to appear when the cursor is moused over anywhere in the row. You can add "td:first-child" to each selector if you want it only on the row labels.
  2. The pseudoselectors I used work well here because you have a fixed number of rows; a little more logic is required if the tooltip should be based on row number for a dynamic number of rows.
  3. (Another note) For pedagogic purposes I chose to use each of the different pseudoselectors :first-child, :nth-child() and :last-child; if you prefer, you could use :nth-child(1), :nth-child(2) and :nth-child(3). You can get really fancy with :nth-child(); it has a page in the W3Schools documentation.

Hope this helps!

Update: A more involved method is necessary to apply custom formatting to the tooltips.

table-tooltip.swf (374.87 KB)
1 0

Replies

replied on January 6, 2017 Show version history

Hi Chynna,

If I remember correctly you can get a basic browser tooltip by adding a "title" attribute to an HTML element, which can be done using JavaScript. Can you elaborate on what you mean by adding the tooltip to a table row? For instance, what would be moused over to display the tooltip and what does it need to show?

Edit: The JavaScript to use would be for example:

$(document).ready(function () {
  $(/*selector*/).attr("title","Sample Tooltip");
});
2 0
replied on January 6, 2017

I want the table rows to be able to have a tooltip option but that isn't available. I want to show a description of each row. A definition of each type of evaluation value.

0 0
replied on January 6, 2017

So the /*selector*/ is where I would put the row id #? Not sure what they are because they are blank. I am a tad confused when it comes to the table reference id's.

0 0
SELECTED ANSWER
replied on January 6, 2017 Show version history

The rows aren't given unique IDs like the columns are. However you could use pseudoselectors on the tr elements of the table. I gave the table element in Forms the ".table" class for reference, then used the following JavaScript:

$(document).ready(function () {
  $('.table tr:first-child').attr('title','The "Get it" row comes first.');
  $('.table tr:nth-child(2)').attr('title','Next comes the "Want it" row, second.');
  $('.table tr:last-child').attr('title','Last of all comes the "Capacity" row.');
});

This had the result in the attached video table-tooltip.swf. (I wasn't actually clicked into the browser at first, so there's a little delay in the beginning.)

A couple of notes:

  1. As-written, the above will cause the tooltip to appear when the cursor is moused over anywhere in the row. You can add "td:first-child" to each selector if you want it only on the row labels.
  2. The pseudoselectors I used work well here because you have a fixed number of rows; a little more logic is required if the tooltip should be based on row number for a dynamic number of rows.
  3. (Another note) For pedagogic purposes I chose to use each of the different pseudoselectors :first-child, :nth-child() and :last-child; if you prefer, you could use :nth-child(1), :nth-child(2) and :nth-child(3). You can get really fancy with :nth-child(); it has a page in the W3Schools documentation.

Hope this helps!

Update: A more involved method is necessary to apply custom formatting to the tooltips.

table-tooltip.swf (374.87 KB)
1 0
replied on January 6, 2017

Thanks James!!!! This is exactly what I needed and the reason why I couldn't get it to work. I was looking for id's!

0 0
replied on January 11, 2017 Show version history

James if I wanted to change the css styling of the tooltip I would use?

.tooltip or .attr('title')

1 0
replied on January 11, 2017

Hi Chynna,

I had a feeling you would ask the good question...the short answer is no: the default "tooltip" styling using the title attribute is not actually an element which can be manipulated; it does not exist in the document object model (DOM) of the page.

The long answer is "No, but you can implement your own tooltips using custom CSS and JavaScript".

Step 1. Find another way to associate the tooltips with each row.

If we're implementing our own tooltips, we'd prefer not to have the browser default show through, so we shouldn't set the title attributes. I shoved them into a different attribute, "tooltip". The browser should ignore this. Modifying the JavaScript from my original reply:

$(document).ready(function () {
  $('.table tbody tr:first-child').attr('tooltip','The "Get it" row comes first.');
  $('.table tbody tr:nth-child(2)').attr('tooltip','Next comes the "Want it" row, second.');
  $('.table tbody tr:last-child').attr('tooltip','Last of all comes the "Capacity" row.');
});

All I did was change the attribute from 'title' to 'tooltip'. But now that the browser is ignoring this, we need another way to display it.

Step 2. Insert the contents of the tooltip attribute into the document.

Since we ultimately want to apply our own formatting to the tooltip, it'd be nice to wrap it in some element with a class we can set. There's a default class called ".tooltip" that Forms already implements, so to avoid clashing with that, I'll use the class ".custom-tooltip".

The logic is as follows: for every table row with the tooltip attribute, when the mouse is over it, insert a <div> element with class ".custom-tooltip" and content the value of the tooltip attribute. When the mouse leaves the row, remove this element. The selector for any table row with the tooltip attribute is "tr[tooltip]". We will also be using the .hover() jQuery function. The first function handler specified in .hover() runs on the "mouse over" event, and the second runs on the "mouse off" event.

$(document).ready(function () {
  /*
    stuff from before
  */
  
  $('tr[tooltip]').hover(
    function() { // runs on mouse over
      $(this).append('<div class="custom-tooltip">' + $(this).attr('tooltip') + '</div>');
    },
    function() { // runs on mouse off
      $('.custom-tooltip').remove();
    }
  );
});

If you preview the form now, you still won't see anything happen. However, if you open the DOM Explorer in Developer Tools (F12) you'll notice the <div> element being added and removed on mouse over and mouse off. Now to make it actually appear.

Step 3. Add CSS so the custom tooltip actually shows up.

Since we now know that our custom tooltip has the ".custom-tooltip" class, we can use that selector to reference it.

There is one other consideration: we want this to appear on top of anything else, so we need to display this <div> element outside of the normal flow of elements. This actually takes care of the original issue of it not appearing at all: browsers won't generally render a <div> that's by itself outside of a <td> element in a table --- it's just not proper.

To do this, we'll use the CSS position property. You can read more about it here, but we'll want to give this the value "absolute" so we can have it show up relative to other elements, like the table row. Then we can also set the z-index property, which is what controls which elements are overlaid on top of which on the screen. The following CSS should do the trick:

tr[tooltip] {
  position: relative;
}
.custom-tooltip {
  background-color: black;
  color: white;
  padding: 5px 10px;
  position: absolute;
    top: 20px;
    left: 20px;
    z-index: 2;
}

I added some padding and made it white text on a black background; the .custom-tooltip is where you'll put whatever formatting you'd like.

We have to specify tr[tooltip] to have "relative" position so that the "absolute" position of the custom tooltip is relative to the parent element. So in theory, this should appear 20px down and to the right of the table row, for demonstration purposes.

Except...it doesn't in most browsers. This is because most browsers don't actually let you apply the "position: relative" rule to most table elements, including in particular table rows. So the tooltip actually appears in the top left corner of the screen. Bummer.

Step 4. Fix the positioning of the custom tooltip.

Since there are no (valid) parent elements with non-static position value, the absolute positioning will treat everything as relative to the top-left corner of the page. (The "absolute" page, not the view of the browser.) We can actually use this to our advantage, to make it so the tooltip appears by the cursor.

First let's get rid of the useless CSS:

.custom-tooltip {
  background-color: black;
  color: white;
  padding: 5px 10px;
  /* You DO need to keep the two rules below! */
  position: fixed;
    z-index: 2;
}

Then we'll add this code in the custom JavaScript to get the position of the mouse cursor. With this code, we'll save the horizontal position to the variable mouseX and the vertical position to mouseY.

var mouseX, mouseY;
$(document).mousemove(function(e) {
    mouseX = e.pageX;
    mouseY = e.pageY;
}).mouseover();

$(document).ready(function () {
  /*
    stuff from before
  */
});

These are all measured from the top-left of the screen...how convenient. If you noticed in the new CSS above, I changed the value of .custom-tooltip position to "fixed" so now the values of top and left properties (which we'll adjust dynamically with JavaScript) will also be relative to the current view on the screen.

The code below shows how we can put the JavaScript so far all together to base the custom tooltip position on the mouse cursor. I added some adjustments so the tooltip will be centered horizontally on the cursor, and appear slightly above.

var mouseX, mouseY;
$(document).mousemove(function(e) {
    mouseX = e.pageX;
    mouseY = e.pageY;
}).mouseover();

$(document).ready(function () {
  $('.table tbody tr:first-child').attr('tooltip','The "Get it" row comes first.');
  $('.table tbody tr:nth-child(2)').attr('tooltip','Next comes the "Want it" row, second.');
  $('.table tbody tr:last-child').attr('tooltip','Last of all comes the "Capacity" row.');
   
  $('tr[tooltip]').hover(
    function() {
      $(this).append('<div class="custom-tooltip">' + $(this).attr('tooltip') + '</div>');
      /*** BEGIN NEW STUFF ***/

      // modifications to figure out the top-left corner of the new tooltip
      tooltipX = mouseX - ($('.custom-tooltip').width() / 2);
      tooltipY = mouseY - $('.custom-tooltip').height() - 15;

      // actually setting the top and left CSS properties
      $('.custom-tooltip').css({
        'left':tooltipX,
        'top':tooltipY
      });

      /*** END NEW STUFF ***/
    },
    function() {
      $('.custom-tooltip').remove();
    }
  );
});

You can try it out now and it should work! Sorta.

Step 5. Improve the timing of the tooltip showing up.

We're used to there being a bit of delay before a tooltip shows up. There's an aspect of positioning dependent on this, too. Right now, we're determining where to display the tooltip based on the position of the cursor as soon as we mouse over the table row --- so our "anchor point" is always going to be around the edge!

Worse, if you move the mouse quickly, it's actually possible to engineer situations where the tooltip can appear outside of the table altogether...not very helpful then.

So for our final tweak to the code, we'll add a 1-second delay before displaying the code. This is more familiar behavior, and will give the user some time to rest the cursor before displaying anything. We'll also want to make sure that we cancel displaying the tooltip if the user moves their cursor away from the table row before the one second is up.

We'll use the JavaScript function setTimeout() for setting the delay, and the corresponding clearTimeout() for cancelling the function on mouse out. To make this easier, I'm going to remove all the code so far that corresponds to actually showing the tooltip to its own function:

$(document).ready(function () {
  /*
    wait for it...
  */
});

function showTooltip(element) {
  element.append('<div class="custom-tooltip">' + element.attr('tooltip') + '</div>');
  tooltipX = mouseX - (element.find('.custom-tooltip').width() / 2);
  tooltipY = mouseY - element.find('.custom-tooltip').height() - 15;
  element.find('.custom-tooltip').css({
    'left':tooltipX,
    'top':tooltipY
  });
}

Some translation is required. Because this function will be a parameter of setTimeout(), we won't be able to use the $(this) jQuery selector anymore. So instead, this helper function showTooltip will take one argument, the element corresponding to the table row.

Now in the main loop, we call this function and set the delay. We define a variable "timer" so we can reference this action and cancel it on mouse out.

// required for the element reference-juggling later
var element = null;

var mouseX, mouseY;
$(document).mousemove(function(e) {
    mouseX = e.pageX;
    mouseY = e.pageY;
}).mouseover();

$(document).ready(function () {
  $('.table tbody tr:first-child').attr('tooltip','The "Get it" row comes first.');
  $('.table tbody tr:nth-child(2)').attr('tooltip','Next comes the "Want it" row, second.');
  $('.table tbody tr:last-child').attr('tooltip','Last of all comes the "Capacity" row.');

  // make sure we can reference the time  
  var timer;  
  $('tr[tooltip]').hover(
    function() {
      // make sure we can still reference the table row inside setTimeout
      element = $(this);
      // delay showing the tooltip for 1 second = 1000 milliseconds
      timer = setTimeout(function() {showTooltip(element);},1000);
    },
    function() {
      // cancel the tooltip if the user moves away before 1 second
      clearTimeout(timer);
      $('.custom-tooltip').remove();
    }
  );
});

function showTooltip(element) {
  /*
    see above
  */
}

Once that's done, you should be able to see the behavior in the attached video, custom-tooltips.swf. Feel free to tweak at will; the positioning can be modified based on tooltip padding or overall aesthetic.

Appendix A. Custom CSS (Final, un-commented)

.custom-tooltip {
  background-color: black;
  color: white;
  padding: 5px 10px;
  position: fixed;
  	z-index: 2;
}

Appendix B. Custom JavaScript (Final, un-commented)

var element = null;
var mouseX, mouseY;
$(document).mousemove(function(e) {
    mouseX = e.pageX;
    mouseY = e.pageY;
}).mouseover();

$(document).ready(function () {
  $('.table tbody tr:first-child').attr('tooltip','The "Get it" row comes first.');
  $('.table tbody tr:nth-child(2)').attr('tooltip','Next comes the "Want it" row, second.');
  $('.table tbody tr:last-child').attr('tooltip','Last of all comes the "Capacity" row.');
  
  var timer;  
  $('tr[tooltip]').hover(
    function() {
      element = $(this);
      timer = setTimeout(function() {showTooltip(element);},1000);
    },
    function() {
      clearTimeout(timer);
      $('.custom-tooltip').remove();
    }
  );
});

function showTooltip(element) {
  element.append('<div class="custom-tooltip">' + element.attr('tooltip') + '</div>');
  tooltipX = mouseX - (element.find('.custom-tooltip').width() / 2);
  tooltipY = mouseY - element.find('.custom-tooltip').height() - 15;
  element.find('.custom-tooltip').css({
    'left':tooltipX,
    'top':tooltipY
  });
}

Hope this helps! (And apologies for the long post.)

Disclaimer: it's possible there are typos...while most of the code is copied-pasted, there may have been errors introduced when arranging for the sake of the step-by-step format.

custom-tooltips.swf (324.94 KB)
2 0
replied on January 12, 2017

@████████ I wasn't expecting this, but I appreciate you figuring out a way to make this work. I will test it out today. 

0 0
replied on January 12, 2017

@████████ works great!

1 0
replied on January 12, 2017

Glad to hear you could get it to work for you! I leave it to your discretion which answer you want to mark for others as the "canonical" one.

0 0
replied on February 20, 2017

This was very helpful!

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.