JSF rendered method is not invoked in the second time - jsf

I have next a4j:jsFunction
<a4j:jsFunction name="renderOnBusinessErrorEvent" execute="#none" bypassUpdates="true" immediate="true"
render="securityForm">
</a4j:jsFunction>
and JSF form with some dialog inside
<h:form id="securityForm">
<h:panelGroup rendered="#{someCondition}">
......
</h:panelGroup>
</h:form>
In my business logic it has to be executed twice consequently. In the first time all is fine. Rendered method is invoked and the expected dialog is present on the page. In the second time rendered method is not invoked, but model has been changed and I expect that dialog will not be present on the page. I supposed that it's some richfaces issue and I tried to use f:ajax
<a4j:jsFunction name="renderOnBusinessErrorEvent" execute="#none" bypassUpdates="true" immediate="true">
<f:ajax event="begin" render=":securityForm"/>
</a4j:jsFunction>
but unsuccessfully. Rendered method still not invoked in the second time. What is it? Some JSF optimization or bug? What's the workaround?
JSF version 2.1.19

The problem was in <h:panelGroup rendered="#{someOtherCondition}">
over h:form which equals false after the first rendering (ON THE SERVER SIDE).
However, this panelGroup is not part of rendering. So, my code:
<h:panelGroup rendered="#{someOtherCondition}">
<h:form id="securityForm">
<h:panelGroup rendered="#{someCondition}">
......
</h:panelGroup>
</h:form>
</h:panelGroup>
<h:form>
<a4j:jsFunction name="renderOnBusinessErrorEvent" execute="#none" bypassUpdates="true" immediate="true"
render="securityForm">
</a4j:jsFunction>
</h:form>
Before calling renderOnBusinessErrorEvent() I'm changing the value of someOtherCondition from true to false, but I don't rerender this element. Actually, on the server side this element is already missing. Looks like it's JSF feature, but is it specificated somewhere?

Related

h:commandButton not working [duplicate]

How to update a div and do partial submission using <h:commandButton>, I have previously used <p:commandButton> to do partial submission by setting the ajax attribute to true and the update attribute to :statusBlock, where the id of the <h:panelGroup> is statusBlock. I am having some designing issues with <p:commandButton> so I cannot use it so I have to use <h:commandButton>.
This is to be done by nesting a <f:ajax> in it.
In effects,
<p:commandButton ... process="#form" update=":statusBlock" />
does exactly the same as
<h:commandButton ...>
<f:ajax execute="#form" render=":statusBlock" />
</h:commandButton>
Note that the subtle difference with the PrimeFaces equivalent is that PrimeFaces defaults to #form in the process/execute, while the <f:ajax> one defaults to #this, so you might need to explicitly specify execute="#form" over all place where you didn't specify the process attribute in the PrimeFaces component.
See also:
Communication in JSF 2.0 - Ajax (asynchronous) POST form
You can just use the standard components alongside f:ajax e.g.
<h:form id="myForm">
<h:commandButton value="Push Me">
<f:ajax execute="myForm" render="statusBlock" />
</h:commandButton>
<h:panelGroup id="statusBlock">
</h:panelGroup>
</h:form>

selectOneMenu of PrimeFaces breaks when calling from ajax

Below is screenshot of selectOneMenu break
Below is my code :
<h:form>
<h:commandLink value="Edit">
<p:ajax event="action" update=":editPanel" listener="#{myBean.open(productItem,'edit')}"/>
</h:commandLink>
</h:form>
<h:panelGroup layout="block" id="editPanel">
<h:form>
<p:selectOneMenu label="hello" value="hello">
<f:selectItems itemLabel="#{mybean.labelvalueList}" itemValue="#{mybean.valueList}"/>
</p:selectOneMenu>
</h:form>
</h:panelGroup>
I am facing problem in display selectonemenu of PrimeFaces when event fire using ajax, as per my observation it will break combobox functionality when ajax call ,one more thing data from back end coming properly there is problem with display only.
Anybody can help me to fix this problem ?
I am using PrimeFaces 5

Pass parameter to f:ajax inside c:foreach loop

I am trying to pass a parameter to an ajax event, this is an example of what I mean:
<h:panelGrid id="pictures" columns="3">
<c:forEach items="#{createProduct.pictures}" var="picture">
<h:graphicImage value="#{picture.source}" />
<h:inputText value="#{picture.alt}" />
<p:commandButton value="Remove">
<f:ajax execute="#form"
listener="#{createProduct.removePicture(picture)}"
render="#form" />
</p:commandButton>
</c:forEach>
</h:panelGrid>
I know this code won't work because you cannot pass a parameter through the ajax listener. Though this is merely an example of what I am trying to accomplish. I have tried using <f:param id="picture" value="#{picture}" /> allong with the ajax tag, though this results in a duplicate component ID form:picture since it is in a loop.
I need this parameter inside the method in order to determine which picture to remove.
How can I solve this with ajax?
I am using a #ViewScoped CDI-bean.
First, I suggest replacing c:forEach with ui:repeat tag. Second, as you are using Primefaces, you should use all its strength. So, commandButton can be more easily written:
<p:commandButton value="Remove" process="#form" update="#form" action="#{createProduct.removePicture(picture)}"/>
and that's it. Don't complicate.
By the way, primefaces commandButton is sends AJAX request by default, you don't need (and you must not use) f:ajax tag.

Setting <f:param> value with <ui:repeat> var

<h:form>
<ui:repeat value="#{sampleManagedBean.food}" var="food">
<h:commandLink value="Name" action="#{sampleManagedBean.outcome}">
<f:param name="name" value="ssd" />
<f:param name="v" value="#{food.boy}" />
</h:commandLink>
<h2>#{food.boy}</h2>
</ui:repeat>
</h:form>
I can't get the the second <f:param> value which is set based on <ui:repeat var>. I can get only the first one which is hardcoded.
The ui:repeat is an UI component while f:param is a taghandler (like JSTL). Taghandlers run during view build time before UI components which run during view render time
(see here).
In our case it means that in the view build phase f:param knows nothing about #{food.boy}. c:forEach will be fine, but if we call some kind of ajax action to change the size of#{sampleManagedBean.food} and rerender the form, we'll not see any changes on page. Because partial rerendering (ajax) affects only UI component tree. c:forEach is somewhere between hardcoding and ui:repeat, we'll have to reload the page to see changes.
try this way,
<h:form>
<ui:repeat value="#{sampleManagedBean.food}" var="food">
<h:commandLink value="Name" action="#{sampleManagedBean.outcome}">
<f:setPropertyActionListener value="ssd" target="#{sampleManagedBean.name}" />
<f:setPropertyActionListener value="#{food.boy}" target="#{sampleManagedBean.v}" />
</h:commandLink>
</ui:repeat>
</h:form>

Why doesn't h:commandButton execute the action method when combined with c:chose?

I've seen a strange problem in my project. It's that <h:commandButton/> does not execute the action method.
<c:choose>
<c:when test="#{empty param.t}">
// HTML
</c:when>
<c:when test="#{param.t eq 'normal'}">
// HTML
<h:form>
<h:commandButton value="ADD" action="#{addBean.doSomething}" />
</h:form>
<c:when>
</c:choose>
When I move <h:form> into first c:when, then the action method is called. Otherwise, it isn't. Why?
I'll ignore the syntax error in your EL (a missing }).
The command button won't be executed when #{param.t eq 'normal'} evaluates to false at the point the form submit request is to be processed. You need to maintain the same parameter for the subsequent request so that the button will be rendered so that JSF can confirm that the enduser is allowed to invoke the action. You can do this by adding a <f:param>:
<h:form>
<h:commandButton value="ADD" action="#{addBean.doSomething}">
<f:param name="t" value="#{param.t}" />
</h:commandButton>
</h:form>
Note that this is supported since JSF 2.0 only. On JSF 1.x you'd need to replace h:commandButton by a h:commandLink if you want f:param support.
Unrelated to the concrete problem, you should try to avoid JSTL as much as possible in your JSF views. If the intent is to render view parts conditionally (not to build view parts conditionally), then you should rather be using the JSF component's rendered attribute instead of a JSTL <c:choose> or <c:if>:
<h:panelGroup rendered="#{empty param.t}">
// HTML
</h:panelGroup>
<h:panelGroup rendered="#{param.t eq 'normal'}">
// HTML
<h:form>
<h:commandButton value="ADD" action="#{addBean.doSomething}" />
</h:form>
</h:panelGroup>

Resources