jsf ajax request recreates viewscoped bean - ajax

I use JSF 2.2 and Primefaces 3.5, and I have a problem with ajax request when I update parent component:
<h:panelGroup id="PAG_CARTELERA" layout="block">
<h:form id="FRM_CARTELERA">
<h:panelGroup rendered="#{!carteleraController.existeCookieCinePref}">
<ui:include src="/paginas/cartelera/cinePreferidoIn.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{carteleraController.existeCookieCinePref}">
<ui:include src="/paginas/cartelera/carteleraOut.xhtml" />
</h:panelGroup>
</h:form>
</h:panelGroup>
In the page carteleraOut.xhtml I have:
<p:calendar id="CART_FECHA" value="#{carteleraController.fechaConsulta}"
maxlength="10"
size="10"
locale="es"
pattern="dd/MM/yyyy"
navigator="true"
showOn="button"
showButtonPanel="true">
<f:converter converterId="calendarConverter" />
<p:ajax process="#this" update=":PAG_CARTELERA" event="dateSelect" listener="#{carteleraController.consultarOtroDiaAction}" />
In the "consultarOtroDiaAction" listener I set the "existeCookieCinePref" boolean field and return void to stay in the same view ("carteleraController" is a ViewScoped a bean).
However the first ajax request when I change the value of the p:calendar component works fine, but the following requests recreates the ViewScoped bean.
Why is this?
Thank you.
NOTE: If in the p:calendar ajax request I update a component of the carteleraOut.xhtml itself, it works, but if I update the whole PAG_CARTELERA panelgroup, it recreates the bean.

can you try h:panelGroup inside of h:form
<h:form id="FRM_CARTELERA">
<h:panelGroup id="PAG_CARTELERA" layout="block">
<h:panelGroup rendered="#{!carteleraController.existeCookieCinePref}">
<ui:include src="/paginas/cartelera/cinePreferidoIn.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{carteleraController.existeCookieCinePref}">
<ui:include src="/paginas/cartelera/carteleraOut.xhtml" />
</h:panelGroup>
</h:panelGroup>
</h:form>

Related

JSF f:ajax listener not called when used with composite component and execute="#this"

I have a following test composite component:
<composite:interface>
<composite:clientBehavior event="click" targets="#{cc.clientId}:label"
name="click" />
</composite:interface>
<composite:implementation>
<h:outputLabel value="click here" id="label" style="background-color: red" />
</composite:implementation>
and when I use it attaching f:ajax client behavior my listener method is not called on server side, but POST request reaches the server. I noticed that when I don't specify f:ajax's execute attribute or specify it as "#this" listener is not called, but with execute="#form" or "#all" it works.
These examples don't work:
<h:form>
<t:testComposite>
<f:ajax event="click" listener="#{bean.test}" />
</t:testComposite>
</h:form>
<h:form>
<t:testComposite>
<f:ajax event="click" listener="#{bean.test}" execute="#this"/>
</t:testComposite>
</h:form>
These examples work:
<h:form>
<t:testComposite>
<f:ajax event="click" listener="#{bean.test}" execute="#form" />
</t:testComposite>
</h:form>
<h:form>
<t:testComposite>
<f:ajax event="click" listener="#{bean.test}" execute="#all" />
</t:testComposite>
</h:form>
<h:form id="form">
<h:panelGroup id="group">
<t:testComposite>
<f:ajax event="click" listener="#{bean.test}" execute=":form:group" />
</t:testComposite>
</h:panelGroup>
</h:form>
I tested it on tomcat 7 with myfaces 2.1.12 and jboss as7 with mojarra 2.1.18.
My question is: why doesn't f:ajax work with execute="#this" when attached to a composite component?
The base of the targets is implicit, so targets="#{cc.clientId}:label" is not necessary. You should use targets="label" instead.
It is hard to explain, but the reason why targets="#{cc.clientId}:label" does not work is because the EL expression is calculated ouside the context or is evaluated before the component tree is built, so in this case for example, when it tries to derive the parent component, the child has not been attached to the view yet.
The general rule is don't call getClientId() when facelet is building the tree (inside a facelet TagHandler for example), and instead use a listener attached to PostAddToViewEvent for that.

rich:calendar not triggering f:ajax

I'm new to jsf, and I'm writing my first application using richfaces. I'm having trouble with the ajax tag that I use to update the associated managed bean property on server for rich:calendar components. This is the code:
<rich:panel header="Computing Options">
<h4>Time Interval</h4>
<h:panelGrid columns="4" width="100%">
<h:outputText value="From" />
<rich:calendar id="intervalFrom" value="#{scenarioEditor.intervalFrom}" popup="true" showApplyButton="true" datePattern="yyy-MM-ddTHH:mm">
<a4j:ajax execute="#this" event="change" render="outFrom" />
</rich:calendar>
<h:outputText value="To" />
<rich:calendar id="intervalTo" value="#{scenarioEditor.intervalTo}" popup="true" showApplyButton="true" datePattern="yyy-MM-ddTHH:mm">
<a4j:ajax execute="#this" event="change" render="outTo" />
</rich:calendar>
<h:outputText id="outFrom" value="From: #{scenarioEditor.intervalFrom}" />
<h:outputText id="outTo" value="To: #{scenarioEditor.intervalTo}" />
</h:panelGrid>
<h4>Algorithms</h4>
<h:panelGrid columns="2">
<h:selectBooleanCheckbox value="#{scenarioEditor.visibilityClashes}" id="clash" >
<f:ajax execute="#this"/>
</h:selectBooleanCheckbox>
<h:outputLabel value="Visibility Clashes Evaluator" for="clash" style="width:170px" />
<h:selectBooleanCheckbox value="#{scenarioEditor.xBandInterference}" id="xband" >
<f:ajax execute="#this"/>
</h:selectBooleanCheckbox>
<h:outputLabel value="X-Band Interferences Evaluator" for="xband" style="width:170px"/>
</h:panelGrid>
</rich:panel>
checkboxes works fine, but the calendars do not. Why? I`ve tried both f:ajax and a4j:ajax without luck.
To better clarify, I want that right after the user has finished entering a value into the calendar, an ajax request is made that call the setter method for the associated property. And this, for the calendar does not happen while for the checkboxes, it does.
The ajax event is failing because of T in datePattern="yyy-MM-ddTHH:mm" is not a valid date formatting pattern. If you add a <rich:messages/> component to your field, you'll see that a conversion error is occurring on each ajax request. Remove the T and you'll be fine

a4j commandlink not working after rerender

The text with id=txt is inserted outside the commandlink after rerendering.
And therefore the link is broken. A refresh of the page gets it back.
Could somebody please help?
<h:form id="frm">
<h:selectOneMenu value="#{myBean.currentId}">
<f:selectItems value="#{myBean.selectListA}" />
<a4j:support event="onchange" action="#{myBean.changeSomething}"
reRender="priceGroup,idLink" />
</h:selectOneMenu>
<h:panelGroup id="priceGroup">
<a4j:commandLink id="idLink">
<h:outputText id="txt" value="#{myBean.someValue}" />
</a4j:commandLink>
</h:panelGroup>
</h:form>

selectBooleanCheckbox ajax event fires but the listener is never executed

The selectBooleanCheckbox ajax event fires but the listener is never executed.
If I remove the c:forEach and just call the first one in the list it works.
<p:selectBooleanCheckbox value="#{Controller.graphFilter.get(0).checked}" >
<p:ajax listener="#{Controller.addMessage}" />
</p:selectBooleanCheckbox>
notes:
graphFilter is a list where container has the sets/gets for checked and description.
controller is a viewscoped managed bean.
addMessage public function that puts a message for the growl.
Everything is in the same form.
<h:form id="form" prependId="false">
<p:growl id="growl" showDetail="true"/>
<c:forEach items="#{Controller.graphFilter}" var="Gc">
<h:outputText value="#{Gc.description}" />
<p:selectBooleanCheckbox value="#{Gc.checked}" >
<p:ajax listener="#{Controller.addMessage}"/>
</p:selectBooleanCheckbox>
</c:forEach>
</h:form>
You should wrap your components with a p:column:
<p:column>
<h:outputText value="#{Gc.description}" />
<p:selectBooleanCheckbox value="#{Gc.checked}" >
<p:ajax listener="#{Controller.addMessage}"/>
</p:selectBooleanCheckbox>
</p:column>
But replacing the whole structure with a p:dataList would be more elegant.

JSF, refresh periodically a component with ajax?

I'm working on an application JSF and i want to refresh periodically a component with ajax Like facebook notification zone behaviour.
How can i do that?
Poll is what you need to use
Poll component make ajax calls in a specified interval.
For example Primefaces Poll
<h:form id="form">
<h:outputText id="txt_count" value="#{counterBean.count}" />
<p:poll interval="3" listener="#{counterBean.increment}" update="txt_count" />
</h:form>
Link to showcase Primefaces Ajax Poll
Pure JSF approach would be to use js timer that will invoke periodical document.getElementById('someFormId:idOfButton').click();
or jquery $("#someFormId\\:idOfButton").click();
while the button will look like this
<h:commandButton id="idOfButton">
<f:ajax render="txt_count"></f:ajax>
</h:commandButton>
something like this
setInterval(function(){$("idOfButton").click()},3000);
More about timer JavaScript Timing Events
In RichFaces there is a poll component as well. Here is a nice example they provide
<a4j:region>
<h:form>
<a4j:poll id="poll" interval="1000" enabled="#{userBean.pollEnabled}" reRender="poll,grid"/>
</h:form>
</a4j:region>
<h:form>
<h:panelGrid columns="2" width="80%" id="grid">
<h:panelGrid columns="1">
<h:outputText value="Polling Inactive" rendered="#{not userBean.pollEnabled}" />
<h:outputText value="Polling Active" rendered="#{userBean.pollEnabled}" />
<a4j:commandButton style="width:120px" id="control" value="#{userBean.pollEnabled?'Stop':'Start'} Polling" reRender="poll, grid">
<a4j:actionparam name="polling" value="#{!userBean.pollEnabled}" assignTo="#{userBean.pollEnabled}"/>
</a4j:commandButton>
</h:panelGrid>
<h:outputText id="serverDate" style="font-size:16px" value="Server Date: #{userBean.date}"/>
</h:panelGrid>
</h:form>

Resources