-1

I am formatting some tooltips in my datagrid and everything works great until I go to the next page using an Ajax call. Here is the basic code I am using. I think I should use "on", but several attempts haven't worked well. I'm assuming that this is a basic jQuery answer, but I can post the Ajax paging code too if necessary.

    <script type='text/javascript' src='http://code.jquery.com/jquery-1.9.1.js'></script>
    <script type="text/javascript" src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>  
    <link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">  
    <link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">



  <style type='text/css'>
    .ui-tooltip {    
        padding: 10px 20px;
        border-radius: 20px;
        font: bold 14px"Helvetica Neue", Sans-Serif;
        font-size: 0.75em;
        box-shadow: 0 0 7px black;
        width:210px;
        z-index:1000;
    }
    .ui-tooltip.PE {
        color: #000000;
        background: #E680B2 !important;
    }
    .ui-tooltip.PC {
        color: #000000;
        background: #B2D1FF;
    }
    .ui-tooltip.PU {
        color: #000000;
        background: #7A0099;
    }

      </style>


<script type='text/javascript'>    //<![CDATA[ 
    $(function() {
        $('td.tips').each(function() {
            var style = $(this).data('info');
            $(this).tooltip({
                content: function() {
                    return '<em>' + $(this).attr('title') + '</em>';
                },
                tooltipClass: style,
                show: "slideDown",
                open: function(event, ui) {
                    ui.tooltip.hover(function() {
                        $(this).fadeTo("slow", 0.5);
                    });
                }
            });
        });

    }); //]]>  

</script>  

The HTML would be something like this:

  <table border="1">
<tr>
    <td title="(Incomplete P/N, Wrong P/N, Invalid P/N, etc...)" data-info="PC" class="tips"><span id="grdNoGoods_ctl12_lblBuyerComments">10/16/2014 - Req to be cancelled per PC</span></td>
<td title="test1" class="tips" data-info="PE">John Black</td>
<td title="test2" class="tips" data-info="PU">John Black</td>
</tr>
<tr>
                <td colspan="3">
<table border="0">
                    <tr>
                        <td><b>Page Size: </b><select name="grdNoGoods$ctl15$ctl01" onchange="javascript:setTimeout('__doPostBack(\'grdNoGoods$ctl15$ctl01\',\'\')', 0)">
                            <option selected="selected" value="10">10</option>
                            <option value="25">25</option>
                            <option value="50">50</option>
                            <option value="75">75</option>
                            <option value="100">100</option>
                            <option value="150">150</option>
                            <option value="200">200</option>

                        </select></td><td><span>1</span></td><td><a href="javascript:__doPostBack('grdNoGoods','Page$2')">2</a></td><td><a href="javascript:__doPostBack('grdNoGoods','Page$3')">3</a></td><td><a href="javascript:__doPostBack('grdNoGoods','Page$4')">4</a></td><td><a href="javascript:__doPostBack('grdNoGoods','Page$5')">5</a></td><td><a href="javascript:__doPostBack('grdNoGoods','Page$6')">6</a></td><td><a href="javascript:__doPostBack('grdNoGoods','Page$7')">7</a></td><td><a href="javascript:__doPostBack('grdNoGoods','Page$8')">8</a></td><td><a href="javascript:__doPostBack('grdNoGoods','Page$9')">9</a></td>
                    </tr>
</table>
</tr>
</table>
Caleb Kleveter
  • 11,170
  • 8
  • 62
  • 92
rahkim
  • 911
  • 2
  • 9
  • 17
  • Can we see the ajax call? It's hard to tell without looking at the code where the problem actually occurs. – Calvin Scherle Oct 28 '14 at 17:23
  • I'm using asp.net update templates. It's really just a datagrid inside that update template (which makes the ajax call for paging, etc.) Do you think that would give any insight? – rahkim Oct 28 '14 at 17:25
  • @CalvinScherle - wouldn't the ajax part be irrelevant? I would think that the issue is strictly jQuery where the event handlers are binding on the page load, but not for the partial postbacks. My understanding of jQuery is pretty basic at this point, but the only thing that changes after the paging is clicked, is the grid contents - html. At that point, the tooltips show without the formatting. Even if I go back to the first page, the tooltips are not formatted. Thanks! – rahkim Oct 28 '14 at 18:32
  • Why the down vote? – rahkim Sep 07 '16 at 11:57

2 Answers2

1

Exploring my previous answer, I realized that solution would not work in your case. The reason is .tooltip() doesn't actually show the tooltip the first time it's called.

In fact, there's nothing wrong with the code you have posted right now. The problem likely lies in your ajax code. Since you never posted your ajax code, I'll just assume you don't have anything like this and give you the complete solution I came up with.

Here it is in a simplified form. Also look at this jsFiddle for a working solution using your style & code.

In short, you need a function to add the tooltip property to your elements. Then, you'll run that function on the initial page load and on every successive loading of new elements from your ajax callback.

var setupTooltip = function (tooltippy_thing) {
    // Configure tooltips according to the style in your old code.
    tooltippy_thing.tooltip(...);
};

$(function () {
    // Apply the tooltip formatting to all the td.tips on page.
    $('td.tips').each(function () {
        setupTooltip($(this));
    });
});

var ajax_callback = function (ajax_html) {
    // Replace the table rows with the new ajax ones.
    $('table').html(ajax_html);

    // Apply the tooltip formatting to the new td.tips.
    ajax_html.find('td.tips').each(function() {
        setupTooltip($(this));
    });
});
mklbtz
  • 773
  • 7
  • 17
  • This solution ended up working for me - http://stackoverflow.com/questions/256195/jquery-document-ready-and-updatepanels – rahkim Nov 07 '14 at 18:53
  • I'll accept this since it closely resembles what I was wanting to accomplish and my original post didn't include the update panel information. – rahkim Nov 10 '14 at 13:22
0

If your ajax call is loading new td.tips elements onto the page, those elements won't be loaded with the jQuery event handlers you specify. To get around this, instead of attaching the tooltip function to each of the existing td.tips elements, you want to attach it to an element that is always present on the page — maybe <body> or the <table> itself. In the .on method, be sure to put a selector that targets only the elements you want the tooltip to show on.

In other words, something like this:

$('body').on({
    mouseenter: function () {
        // show the tooltip
    },
    mouseleave: function () {
        // hide the tooltip
    }
}, 'td.tips');

(Edit: removed last function from .on call. See: http://api.jquery.com/on/#on-events-selector-data)

mklbtz
  • 773
  • 7
  • 17
  • The ajax call is indeed loading new td.tips elements and that is the issue. Are you suggesting that I don't use ('td.tips').each at all? I've tried $('td.tips').on('mouseover', function() {}); but that doesn't help either. – rahkim Oct 29 '14 at 12:18
  • Exactly, ``('td.tips').each`` is only going to bind to each of the elements that are already loaded onto the page but not to any new elements that get added to the DOM. – mklbtz Oct 29 '14 at 18:03
  • Switching from ``('td.tips').each`` to ``('td.tips').on`` wouldn't help because they suffer from the same problem: both are binding to ``('tips.each')``. – mklbtz Oct 29 '14 at 18:05
  • Updated [your jsfiddle](http://jsfiddle.net/pT3ed/38/) with a button to add new ```` elements, demonstrating your problem. Forked [my own jsfiddle](http://jsfiddle.net/7o2zpneq/2/) and added my solution. – mklbtz Oct 29 '14 at 18:37
  • Your fiddle changes the (this) elements html to 'tooltip!' on mouseenter and 'John black' on mouseleave, but the tooltip has no formatting. – rahkim Oct 30 '14 at 13:25
  • I'll leave that as an exercise for you ;-) The point is, if you add new elements in my implementation, the mouseenter function will run on those new elements. – mklbtz Oct 30 '14 at 15:47
  • So you know for a fact that the method you suggest will address my issues? Kind of hard to know if your method is worth pursuing without a working example (with formatting, etc) of some sorts. – rahkim Oct 31 '14 at 14:37
  • I'm using update panels in asp.net. I think that might have something to do with it. Update panels completely replace the contents of the panel and therefore break any binding with the new elements on the page. I basically need to find a way to rebind the new elements each time the panel is refreshed. – rahkim Nov 07 '14 at 14:40