Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Primefaces <p:tooltip> does not disappear after another Ajax request

Let's say I have some tooltips in my <p:dataTable>. When I change the page of dataTable and while another page laods, I move mouse on any tooltip - it shows up, but after the other page is loaded tooltip never disappears.. I've tried to update this, using p:ajax, p:remoteCommand but nothing helps, actually this made another Ajax request and tooltips also stucked. Only full page reload F5 works.

Has anyone encountered with such problem? Thanks a lot for your help!

like image 203
Rafcik Avatar asked Jul 15 '15 11:07

Rafcik


2 Answers

Incase anybody else struggles with this, I think I found a solution worth trying. In my case, I had a tool tip that showed when I hovered over a commandButton but if I clicked it it would run an ajax request and return, update a component and finish but the tooltip would still remain. This is what I did to fix it.

<p:tooltip id="saveDeleteTooltip" globalSelector="[data-tooltip]" position="top" hideEvent="mouseleave click"/>

Supply two events for the hideEvent attribute and seems to recognize and use both. The first is for normal mouseout but the second does fire when I click on my commandButtons it does hide the tooltip like it was supposed to do.

like image 87
MarkyMarksFunkyBunch Avatar answered Oct 26 '22 14:10

MarkyMarksFunkyBunch


This looks like a PrimeFaces bug, but you can work around it by hiding tooltips on pagination events via JS.

<p:dataTable value="#{bean.val}" var="row" rowIndexVar="rowIndex" rows="10" paginator="true">
    <p:ajax event="page" oncomplete="hideTooltips();" />

    <p:column>
        <h:outputText id="text" value="#{row}" />
        <!--
            since p:tooltip is located inside an iterative component (p:dataTable), we can't
            just define a static widgetVar value, because there will be a widget instance for
            each iteration, and each instance must have a unique widgetVar value, so we'll
            use rowIndex to achieve that
        -->
        <p:tooltip widgetVar="textTipVar#{rowIndex}" for="text" value="Tip" />
    </p:column>
</p:dataTable>
<script>
    function hideTooltips() {
        /*
            we've defined a bunch of widgetVars with a dynamic name, so we'll iterate over
            all widgets on the page and find the ones we need by looking for a known
            widgetVar prefix
        */
        for (var w in PrimeFaces.widgets) {
            if (w.indexOf('textTipVar') === 0) {
                PrimeFaces.widgets[w]._hide();
            }
        }
    }
</script>

This uses an undocumented Tooltip widget method _hide, keep that in mind when updating to another PrimeFaces version, e.g. the method's name could change. The PrimeFaces.widgets object is undocumented too.


Update. As russellelbert points out in comments, the method's name is just hide since PrimeFaces 7.0 - no underscore.
Also since PrimeFaces 10.0 both PrimeFaces.widgets and Tooltip#hide are part of documented Client API.

like image 28
Vsevolod Golovanov Avatar answered Oct 26 '22 14:10

Vsevolod Golovanov