Adityaz7
Adityaz7

Reputation: 61

p:tooltip doesn't work when form containing it is rendered-rerendered

Tooltip doesn't show up on mouseover if the form containing it is re-rendered with f:ajax.

<h:form id="childForm">
    <div class="form-body form-body-margin-top">
        <div class="row form-group col-md-12">
                <h:selectOneMenu styleClass="form-control" value="#{bean.someCondition}">
                    <f:selectItem itemLabel="Yes" itemValue="true" />
                    <f:selectItem itemLabel="No" itemValue="false" />
                    <f:ajax execute="@this" render="childForm" />
                </h:selectOneMenu>
        </div>
    </div>
    <t:div styleClass="row form-group col-md-12" rendered="#{!bean.someCondition}">
        <label>Choose Catalog
            <sup><h:outputText id="tip1" class="fa fa-info-circle blue"/></sup> <p:tooltip for="tip1" value="Choose a category" position="top right" />
        </label>
    </t:div>

    <t:div rendered="#{bean.someCondition}">
        <label>Hello 
            <sup><h:outputText id="tip2" class="fa fa-info-circle blue"/></sup> <p:tooltip for="tip2" value="Choose a name" position="top right" />
        </label>
    </t:div>
</h:form>

Issue is simple: When page is loaded for the first time "Yes" is selected in dropdown, tooltip for "choose a name" is visible works correctly. When I select "No" in the dropdown form is re-rendered, tooltip for "choose a category" is visible but doesn't show up. again if i change it back to "Yes", tooltip for "choose a name" is visible and doesn't work correctly.

Summary: Tooltip works only once the page loads, And then stop working for subsequent re-rendering of the form. Looks like a DOM issue to me. As if whatever is in the "for" attribute of tooltip isn't availble in the DOM on re-render. Any Solution?

Upvotes: 1

Views: 1239

Answers (2)

Adityaz7
Adityaz7

Reputation: 61

I couldn't find a pure JSF approach so used JS to achieve this, The issue according to me is that component tip1, tip2 are not present in the DOM when PF try searching for them (possibly a jsf lifecyle thing) because rendered attribute remove component it is applied on from the DOM. What I did was using a css class .hide which sets visibility to hidden. It keeps the component in the DOM instead of removing it:

.hide {
 visibility: hidden;
}

now for above "rendered" attribute I just replaced with a comditional expression which applies hide class in the same way we want it to render.

<t:div styleClass="row form-group col-md-12 #{!bean.someCondition?'':'hide'}>
    <label>Choose Catalog
        <sup><h:outputText id="tip1" class="fa fa-info-circle blue"/></sup> <p:tooltip for="tip1" value="Choose a category" position="top right" />
    </label>
</t:div>

this helps to render just the things we want when page loads. Now for the dynamic behavior when value from the drop down is selected i've used js to toggle hide class from the t:div. I call a function on onchange of h:selectonemenu.

function changepage(select) {
        if(select.value == 'false') {
          $("#onno").removeClass('hide');
          $("#onyes").addClass('hide');
        }
        else if(select.value == 'true') {
          $("#onyes").removeClass('hide');
          $("#onno").addClass('hide');
        }
    }

So the complete page now looks like this:

<script>
    function changepage(select) {
        if(select.value == 'false') {
        $("#onno").removeClass('hide');
        $("#onyes").addClass('hide');
        }
        else if(select.value == 'true') {
        $("#onyes").removeClass('hide');
        $("#onno").addClass('hide');
        }
    }
</script>

<style>
.hide {
visibility: hidden;
}
</style>


<h:form id="childForm">
<div class="form-body form-body-margin-top">
    <div class="row form-group col-md-12">
            <h:selectOneMenu styleClass="form-control" value="#
            {bean.someCondition}" onchange="changepage(this)">
                <f:selectItem itemLabel="Yes" itemValue="true" />
                <f:selectItem itemLabel="No" itemValue="false" />
                <f:ajax execute="@this" render="childForm" />
            </h:selectOneMenu>
    </div>
</div>

<t:div id="onno" styleClass="row form-group col-md-12 #{!bean.someCondition?'':'hide'}">
    <label>Choose Catalog
    <sup><h:outputText id="tip1" class="fa fa-info-circle blue"/></sup> 
    <p:tooltip for="tip1" value="Choose a category" position="top right" />
    </label>
</t:div>

<t:div id="onyes" styleClass="#{bean.someCondition?'':'hide'}">
    <label>Hello 
    <sup><h:outputText id="tip2" class="fa fa-info-circle blue"/></sup> 
    <p:tooltip for="tip2" value="Choose a name" position="top right" />
    </label>
</t:div>
</h:form>

In this way no components are removed from dom they are just invisible. And so they are available when "for" attribute of p:tooltip refers them.

Upvotes: 1

pwain
pwain

Reputation: 279

It could be a problem with the id="tip2". Please try to write the complete path in the tooltip. something like

<p:tooltip for=":childForm:....:tip2" ... />

(I am not sure if t:div gets an id, but if so please set the id by yourself and try your tooltip with the complete id path)

Upvotes: 0

Related Questions