user525146 user525146 - 2 months ago 6
Javascript Question

Add image/icon as a row value in datatables

I need to add an image/icon to the last column in the row. And that icon should have a tooltip when I hover on it should display data from the server. I am not sure how to implement this. Any experts who has implemented this feature please help me. Thanks in advance.

EDIT

This is the sample data I have and I need to add an icon for the last column when hovered over displays a tooltip with the "data" in tooltip.

{
"iTotalRecords": 5,
"sEcho": "1",
"aaData": [
[
"V2993ASFKH230943",
"Honda",
"Accord",
"data"
],
[
"V2993A39SNF30943",
"Honda",
"CRV",
"data"
],
[
"V4833A39SNF30943",
"Acura",
"TSX"
],
[
"V4833RE9SNF30943",
"Acura",
"TL",
"data"
],
[
"V9383RE9SNF30943",
"Acura",
"MDX",
"data"
]
],
"iTotalDisplayRecords": 5
}


[update]

The image tag ends up looking like this:

var imgTag = '<span class="mytext" ><span class="ui-icon ui-icon-wrench" ></span>';


A requirement is also to have modal dialog appear on hover. Below is the jquery code to open the modal.

$(".mytext").mouseover(
function() {
var width = 250;
var height = 270;
var posX = $(this).offset().left - $(document).scrollLeft()
- width + $(this).outerWidth();
var posY = $(this).offset().top - $(document).scrollTop()
+ $(this).outerHeight();
//alert(posX + ", " +posY);
$(".mytext").dialog({
resizable:false,
width : width,
height : height,
position : [ posX, posY ]
});
});


This is somehow not working, when I hover on it. Its not triggering the jquery Modal

UPDATE

You are correct there is a timing issue. I fixed that issue. Now when I hover on it is loading up all the images into the modal i.e., the number of rows I have are the number of modal dialogs that are opened. I need to pass the value aData[3] to the jquery modal.

Answer

It would depend a little on how the tooltip is implemented. Each 3rd-party "Fancy" JavaScript tooltip will do things differently. The example here is just showing how to take two pieces of the data (make and model) and push them into the "title" attribute of the cell, which will trigger a browser's built-in tooltips.

I imagine you're going to be using a tooltip plugin or somesuch, so you'll have to take the general principles of the example and adapt them to the specific tooltip. OK, enough preamble.

--

This is all going to happen in the fnRowCallback [update: 1.10 forward just uses "rowCallback"], which is a property in the DataTables object that you can set during initialization. By doing this, what will happen is that as each row is rendered, you have the opportunity to modify the HTML (the nRow) and return it after modification so that it can be pushed into the DOM.

(note: when it helps readability, I tend to make more variables than are strictly necessary. I also keep the iDisplayIndex and iDisplayIndexFull lying around. You should be able to remove them if you want)

"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
  var theMake = aData[1],
      theModel = aData[2];

  var imgTag = '<img href="/images/icon.png" title="' + theMake + ' ' + theModel + '" class="hoverImage"/>'; 
  /* result example: <img href="/images/icon.png" title="Honda CRV" class="hoverImage"/> */

  $('td:eq(3)', nRow).html(imgTag); // replace the word "data" with the new image markup

  return nRow;
}

Now when you hover the image, the tooltip will show Make and Model.

Again, this doesn't do anything for a specific tooltip plugin, though your may be using a plugin that also gets its information from the title, which would be handy. For those plugins, you just need to add a class to the imageTag (class="tooltip" or whatever) that triggers the plugin.

[update]

So using jQuery UI's dialog as an example: many custom dialog functions create a "container" node on the fly, and then call dialog() on it. I prefer to have a generic re-usable container node in the base document, then populate it when needed.

I like to put mine right before the body closes, because that's where jQuery UI is going to stick it when you're done with it anyhow:

  <!-- ... -->
  <div id="dialogContainer"></div>
</body>

In your CSS you would set it to be hidden by default ( #dialogContainer { display:none } ).

Now that you have the container, you can use the .dialog() function on it. Using the original example further above (note I've added the class "hoverImage" to it), you would populate aData[3] into the title of the image instead of whatever's in my example. The title is acting as "storage" for aData[3] data.

Now, totally outside of the DataTables initialization, in your document ready function (you probably already have one), you could bind the mouseenter event:

$('#tableContainer').on('mouseenter', '.hoverImage', function(e) {
  e.preventDefault; // if you want to prevent the browser tooltip
  var dialogContainer = $('#dialogContainer');
  dialogContainer.html(this.title); // replace contents of dialog with the title of the image
  dialogContainer.dialog({ /* options */ });
});