Tooltips stop working after ajax call

I am using this jQuery snippet to create tooltips on some JFF elements in a html table.

$(document).ready(function() {

    $('.ui-icon-pencil, .ui-icon-check, .ui-icon-close, .ui-icon-trash').hover(function(e) {    // this is the hover in function 

        // Since the elements have multiple classes, this function gets the one that starts with ui-icon-<something>
        var icon = $(this).attr('class').match(/ui-icon-(?:pencil|check|close|trash)/)[0];
        var title = null;

        if(icon == 'ui-icon-pencil') {
            title = 'Edit';
        } else if(icon == 'ui-icon-check') {
            title = 'Save';
        } else if(icon == 'ui-icon-close') {
            title = 'Cancel';
        } else if(icon == 'ui-icon-trash') {
            title = 'Delete';
        }

        $('body').append('<p class="tooltip">'+title+'</p>');
        $('.tooltip').css('top', (e.pageY-50) + 'px').css('left', (e.pageX-10) + 'px').fadeIn('fast');
    }, function() { // this is the hover out function
        $('.tooltip').remove();
    });

    // this handles the tooltip moving when the mouse moves
    $('.ui-icon-pencil').mousemove(function(e) {
        $('.tooltip').css('top', (e.pageY-50) + 'px').css('left', (e.pageX-10) + 'px');
    });
});

      

This works great, except that if you change / add / remove a row in the table with jsf ajax magic, the tooltips stop working.

How can I keep the tooltips after changing / adding / deleting a row in a table?

I think I should be using jquery's live function to support tooltips, but I'm not sure how I would use them in this case.

enter image description here

+3


source to share


4 answers


Most likely handlers get lost when table row changes (via jsf ajax magic). Try using .on

as below and let us know the results,

Note: Below is version 1.7 for jQuery. Use .live or .delegate

if you are using an older version of jQuery.



$(document).ready(function() {

    $(document).on('mouseenter', '.ui-icon-pencil, .ui-icon-check, .ui-icon-close, .ui-icon-trash', function(e) {    // this is the hover in function 

        // Since the elements have multiple classes, this function gets the one that starts with ui-icon-<something>
        var icon = $(this).attr('class').match(/ui-icon-(?:pencil|check|close|trash)/)[0];
        var title = null;

        if(icon == 'ui-icon-pencil') {
            title = 'Edit';
        } else if(icon == 'ui-icon-check') {
            title = 'Save';
        } else if(icon == 'ui-icon-close') {
            title = 'Cancel';
        } else if(icon == 'ui-icon-trash') {
            title = 'Delete';
        }

        $('body').append('<p class="tooltip">'+title+'</p>');
        $('.tooltip').css('top', (e.pageY-50) + 'px').css('left', (e.pageX-10) + 'px').fadeIn('fast');
    });

    $(document).on('mouseleave', '.ui-icon-pencil, .ui-icon-check, .ui-icon-close, .ui-icon-trash', function() { // this is the hover out function
        $('.tooltip').remove();
    });

    // this handles the tooltip moving when the mouse moves
    $(document).on('mousemove', '.ui-icon-pencil', function(e) {
        $('.tooltip').css('top', (e.pageY-50) + 'px').css('left', (e.pageX-10) + 'px');
    });
});

      

+6


source


Are you adding / removing elements with one of the classes that should show the tooltip on hover after making an ajax call (DOM change)?

Eventlisteners are by default associated with the elements in the DOM at this point. Are you really using live or even better: delegate.



I'll post an answer that restricts the eventlistener to a body, but if you have, for example, a deeper nested wrapper element that will contain all the child elements that should have a tooltip, then you should bind the eventlistener to that.

$("body").delegate('.ui-icon-pencil, .ui-icon-check, .ui-icon-close, .ui-icon-trash', 'click', function(event){
// Just do the things you would do in a normal .hover-event that is binded to these classes
});

      

+1


source


Warning: I don't know JSF

You will need to reset the mousemove event on the loaded content.

JSF will probably offer a callback to achieve this. This link looks promising: http://javaserverfaces.java.net/nonav/docs/2.0/jsdocs/symbols/jsf.ajax.html#.addOnEvent

Apparently Primefaces has an incomplete attribute for this purpose:

 <p:commandButton value="Cancel" actionListener="#{progressBean.cancel}" oncomplete="pbAjax.cancel();startButton2.enable();" /> 

      

Maybe this will help you?

0


source


Hover events are not tied to new elements added by the ajax call. You will have to manually add the hover function to those newly added items.

I'm not really a fan of this, but it will probably work when you run the code you posted above after every ajax call. Just keep in mind that you probably bind the event twice to some elements, which sometimes causes some weird errors.

0


source







All Articles