Ajax – Can you update an h:outputLabel from a p:ajax listener

ajaxjsfjsf-2primefaces

I'm trying to use a p:ajax tag and then in that listener, i'm setting a value called "periodRendered". then i'm trying to update an h:outputLabel tag via an update from the p:ajax tag. It's not updating ajaxily and i'm thinking it's because a primefaces ajax tag can't update a standard jsf outputLabel tag.

Is my assumption correct and is there a more appropriate tag i should be using instead of h:outputLabel ?

<h:outputLabel for="addProgramTo" value="Add Program To" />
<p:selectOneMenu value="#{ppBacker.grantProgram.grant_project_id}" id="addProgramTo" size="1" styleClass="listBoxMedium">
    <p:ajax process=":addProgram:addProgramTo" update=":addProgram:periodGrid, :addProgram:periodLabel" event="change" listener="#{ppBacker.addProgramListener}" />
    <f:selectItems value="#{ppBacker.grantProjectDropDownList}" />
</p:selectOneMenu>            

<h:outputLabel for="period" value="Period" id="periodLabel" rendered="#{ppBacker.periodRendered}"> 

Best Answer

You cannot update elements which are not rendered , rendered=false "is a JSF way to" to remove elements from the DOM Tree ,

its not like css display:none or visibility:hidden <- this two will keep the elements in the DOM tree but hidden , while the JSF rendered=false wont even render (keep) the element in the DOM tree (you wont even see it in the "view source" of the page)

So in you case you need to wrap the outputLabel with `panelGroup' and update the id of the wrapper

<h:panelGroup id="periodLabelWrapper">
    <h:outputLabel for="period" value="Period" id="periodLabel" rendered="#{ppBacker.periodRendered}">
</h:panelGroup>

and refer to the wrapper (which always be in the DOM tree) id in the <p:ajax update attribute, like this:

<p:ajax process=":addProgram:addProgramTo" update=":addProgram:periodGrid, :addProgram:periodLabelWrapper" event="change" listener="#{ppBacker.addProgramListener}" />

Another solution would be the update the entire form like this <p:ajax update="@form" ... that way you don't need the wrap the outputLabel

regarding your comment question

how does @form update the un-rendered elements, but targeting them directly through id's does not?

You can't target an element in update which is not present in the page (rendered=false) "its not there"

But when you use update="@form" or update="someWrapperID" the form/wrapper "re evaluates" all its inner elements , including the ones with rendered="#{someBean.someCondition}" and the condition gets "re evaluated" so if it result to true the elemet will be displayed...

Related Topic