Tooltips
Although the row highlighting
might be a useful feature, so far it's not apparent to the user that the
feature even exists. We can begin to remedy this situation by giving
all author cells a clickable class,
which we have styled to change the mouse cursor to a pointer when it is
within the cell:
$(document).ready(function() {
var $authorCells = $('table.striped td:nth-child(3)');
$authorCells
.addClass('clickable')
.click(function() {
var authorName = $(this).text();
$authorCells.each(function(index) {
if (authorName == $(this).text()) {
$(this).parent().toggleClass('highlight');
}
else {
$(this).parent().removeClass('highlight');
}
});
});
});
The clickable
class is a step in the right direction, for sure, but it still doesn't
tell the user what will happen when the cell is clicked. As far as the
user of the page knows, that click could just as easily trigger another
behavior, such as sending the user to another page. Some further
indication of what will happen upon clicking is in order.
Tooltips
are a familiar feature of many software applications, including web
browsers. We can address this usability challenge by displaying a
tooltip when the mouse hovers over one of the
Author cells. The text of the tooltip
can describe to users the effect their action will have, with a message
such as Highlight all articles by Rey Bango.
This text will be contained in a<div>, which we can
append to the<body>. The $tooltip variable will be used throughout the script to refer to this
newly created element:
var $tooltip = $('<div id="tooltip"></div>').appendTo('body');
There are three basic
operations we will have to perform repeatedly on our tooltip:
1.
Showing the tooltip when the mouse is over the interactive element,
2.
Hiding it when the mouse leaves the area,
3.
Repositioning the tooltip when the mouse moves.
We'll write functions for each
of these tasks first, then wire them up to browser events using jQuery.
Let's start with positionTooltip, which we'll reference when the mouse moves over any of the Author cells:
var positionTooltip = function(event) {
table appearances, modifyingtooltip, positioningvar tPosX = event.pageX;
var tPosY = event.pageY + 20;
$tooltip.css({top: tPosY, left: tPosX});
};
Here we use the pageX and pageY
properties of the event object to set the top and
left positions of the tooltip. When this
function is invoked in response to a mouse event, such as mousemove,
event.pageX and event.pageY
will give us the coordinates of the mouse cursor, so tPosX and
tPosY will refer to a screen
location 20 pixels below the mouse cursor.
Next we need to write our showTooltip()
function, to place the tooltip on the screen.
var showTooltip = function(event) {
table appearances, modifyingtooltip, placingvar authorName = $(this).text();
$tooltip
.text('Highlight all articles by ' + authorName)
.show();
positionTooltip(event);
};
The showTooltip()
function is rather straightforward. We populate the tooltip's contents
using a string built from the cell contents (which will be the author's
name), and show it.
We then place it in the proper
location on the page with the positionTooltip() function. Since the tooltip has been appended to the body
element, we'll need some CSS to make the it float above the page in the
right location:
#tooltip {
position: absolute;
z-index: 2;
background: #efd;
border: 1px solid #ccc;
padding: 3px;
}
Finally, we write a simple hideTooltip()
function:
var hideTooltip = function() {
table appearances, modifyingtooltip, hiding$tooltip.hide();
};
And now that we have functions
for showing, hiding, and positioning the tooltip, we can reference them
at the appropriate places in our code:
$(document).ready(function() {
var $authorCells = $('table.striped td:nth-child(3)');
var $tooltip = $('<div id="tooltip"></div>').appendTo('body');
var positionTooltip = function(event) {
var tPosX = event.pageX;
var tPosY = event.pageY + 20;
$tooltip.css({top: tPosY, left: tPosX});
};
var showTooltip = function(event) {
var authorName = $(this).text();
$tooltip
.text('Highlight all articles by ' + authorName)
.show();
positionTooltip(event);
};
var hideTooltip = function() {
$tooltip.hide();
};
$authorCells
.addClass('clickable')
.hover(showTooltip, hideTooltip)
.mousemove(positionTooltip)
.click(function(event) {
var authorName = $(this).text();
$authorCells.each(function(index) {
if (authorName == $(this).text()) {
$(this).parent().toggleClass('highlight');
}
else {
$(this).parent().removeClass('highlight');
}
});
});
});
Note that the arguments to the
.hover() and .mousemove() methods are referencing
functions that are defined elsewhere. As such, we omit the parentheses
that would follow calls to the functions. The tooltip now appears when
we hover over an author cell, moves with the mouse movement, and
disappears when we move the mouse cursor out of the cell.
A problem with our current
implementation is that the tooltip continues to suggest clicking on a
cell to highlight the articles even after those articles have been
highlighted:
We need a way to change the
tooltip's text if the row has the highlight
class. We can accomplish this by placing a conditional test in the
showTooltip() function to check for the
presence of the class. If the current cell's parent<tr>
has the highlight class, we want to use the word Unhighlight instead of Highlight when we create the tooltip:
var action = 'Highlight';
table appearances, modifyingtooltip, textstylingif ($(this).parent().is('.highlight')) {
action = 'Unhighlight';
}
$tooltip
.text(action + ' all articles by ' + authorName)
.show();
This correctly chooses
tooltip text when the mouse enters a cell, but we also need to
recalculate the label at the time the mouse is clicked. For that, we
need to call the
function inside the click event handler: showTooltip()
$(document).ready(function() {
table appearances, modifyingtooltip, showTooltip() functionvar $authorCells = $('table.striped td:nth-child(3)');
var $tooltip = $('<div id="tooltip"></div>').appendTo('body');
var positionTooltip = function(event) {
var tPosX = event.pageX;
var tPosY = event.pageY + 20;
$tooltip.css({top: tPosY, left: tPosX});
};
var showTooltip = function(event) {
var authorName = $(this).text();
var action = 'Highlight';
if ($(this).parent().is('.highlight')) {
action = 'Unhighlight';
}
$tooltip
.text(action + ' all articles by ' + authorName)
.show();
positionTooltip(event);
};
var hideTooltip = function() {
$tooltip.hide();
};
$authorCells
.addClass('clickable')
.hover(showTooltip, hideTooltip)
.mousemove(positionTooltip)
.click(function(event) {
var authorName = $(this).text();
$authorCells.each(function(index) {
if (authorName == $(this).text()) {
$(this).parent().toggleClass('highlight');
}
else {
$(this).parent().removeClass('highlight');
}
});
showTooltip.call(this, event);
});
});
By using the JavaScript call() function, we
can invoke showTooltip() as if it
were running within the scope of the click
handler of the cell with the author's name. We need to do this so that
the this keyword refers to the
correct object (this table cell) during the execution of
showTooltip().
Now the tooltip offers a more
intelligent suggestion when the pointer hovers over a row that is
already highlighted.