First h:form of an a4j:repeat is not rendering correctly - jsf

Let's say that I have a list of objects in my bean and I want to paint them in my page, for that I'm using an <a4j:repeat>, this objects need to be wrapped inside a <h:form> because each one of this objects needs to run a poll to execute some Futures Java objects in the bean to perform some heavy tasks and update them later on.
<a4j:repeat value="#{bean.objectsList}" var="obj">
<h:form id="pollForm">
<a4j:poll id="myPoll" interval="2000"
action="#{myBean.foo1}"
enabled="#{myBean.foo2}"
render="pollForm,myPoll" />
<p>#{obj}</p>
</h:form>
</a4j:repeat>
The code isn't really relevant I think. My code works as excepted in all elements except the first one. All the elements inside the loop render as an html form element except the first one, and for that reason the first one can't never be reRendered by the poll.
I have read in other posts that it seems to be a bug, but I'm also new to JSF 2.2 and RichFaces and maybe I'm misunderstanding something.

Related

primefaces update attribute not working on modal dialog opened from modal dialog [duplicate]

I have a question about the idea behind the fact, that only UIForm got the attribute prependId. Why is the attribute not specified in the NamingContainer interface? You will now probably say that's because of backward compability but I would preferre breaking the compability and let users which implement that interface, also implement methods for the prependId thing.
The main problem from my perspective about the prependId in the UIForm component is, that it will break findComponent()
I would expect that if I use prependId, then the NamingContainer behaviour would change, not only related to rendering but also when wanting to search for components in the component tree.
Here a simple example:
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
Now when i want to get the panelGroup component I would expect to pass the string "group" to the method findComponent(), but it won't find anything, I have to use "test:group" instead.
The concrete problem with that is, when using ajax with prependId="false". The ajax tag expects in the attributes update and process, that the values care of naming containers. It's a bit strange that when I use prependId="false" that I have to specify the full id or path, but okay.
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
<h:form id="test1" prependId="false">
<h:commandButton value="go">
<f:ajax render="test:group"/>
</h:commandButton>
</h:form>
Well this code will render without problems but it won't update the panelGroup because it cannot find it. The PartialViewContext will contain only the id "group" as element of the renderIds. I don't know if this is expected, probably it is but I don't know the code. Now we come to the point where the method findComponent() can not find the component because the expression passed as parameter is "group" where the method would expect "test:group" to find the component.
One solution is to write your own findComponent() which is the way I chose to deal with this problem. In this method i handle a component which is a NamingContainer and has the property prependId set to false like a normal UIComponent. I will have to do that for every UIComponent which offers a prependId attribute and that is bad. Reflection will help to get around the static definition of types but it's still not a really clean solution.
The other way would be introducing the prependId attribute in the NamingContainer interface and change the behaviour of findComponent() to work like described above.
The last proposed solution would be changing the behaviour of the ajax tag to pass the whole id, but this would only solve the ajax issue and not the programmatic issues behind the findComponent() implementation.
What do you think about that and why the hell is it implemented like that? I can't be the first having this problem, but I wasn't able to find related topics?!
Indeed, UIComponent#findComponent() as done by <f:ajax render> fails when using <h:form prependId="false">. This problem is known and is a "Won't fix": JSF spec issue 573.
In my humble opinion, they should never have added the prependId attribute to the UIForm during the JSF 1.2 ages. It was merely done to keep j_security_check users happy who would like to use a JSF form with JSF input components for that (j_security_check requires exact input field names j_username and j_password which couldn't be modified by configuration). But they didn't exactly realize that during JSF 1.2 another improvement was introduced which enables you to just keep using <form> for that instead of sticking to <h:form>. And then CSS/jQuery purists start abusing prependId="false" to avoid escaping the separator character : in their poorly chosen CSS selectors.
Just don't use prependId="false", ever.
For j_security_check, just use <form> or the new Servlet 3.0 HttpServletRequest#login(). See also Performing user authentication in Java EE / JSF using j_security_check.
For CSS selectors, in case you absolutely need an ID selector (and thus not a more reusable class selector), simply wrap the component of interest in a plain HTML <div> or <span>.
See also:
How to select JSF components using jQuery?
How to use JSF generated HTML element ID with colon ":" in CSS selectors?
By default, JSF generates unusable ids, which are incompatible with css part of web standards

bootsfaces b:commandButton in ui:repeat not updating h:graphicImage

I'm using the 0.7 version of bootsfaces to create a simple page, which has something like the following:
<h:form id="some_form">
<ui:repeat id="some_elements" var="property" value="#{someBean.properties}">
<b:commandButton value="ShowProp" ajax="true" actionListener="#{someBean.showProperty(property)}" update=":some_form:some_elements:graphic"/>
<!-- This property is true -->
<ui:fragment rendered="#{someOtherBean.showGraphic}">
<h:graphicImage url="gen_image?id=#{property.id}" id="graphic"/>
</ui:fragment>
</ui:repeat>
</h:form>
Now, the idea is that on clicking the button, a property is updated and the image should be re-generated (in this case a jfreechart graph - but this is besides the point.) I tested this with primefaces commandButton and it works fine (the graph is redrawn..) However with bootsfaces commandButton, nothing happens once the ajax call completes (I can see the call on the server side, but the graph is not reloaded.) I think it's down to how it must reference the image in the repeated block, but now sure what is wrong - has anyone come across this?
(NOTE: reason I don't want to use primefaces is that it does not integrate well with bootstrap)
I've opened a bug on the project's bugtracker (https://github.com/TheCoder4eu/BootsFaces-OSP/issues/135).
Actually, why did you expect the update=":some_form:some_elements:graphic" to work in the first place? This expression is an id that doesn't exist. The id is some_form:some_elements:0:graphic. In other words: it contains the row number. PrimeFaces (and Mojarra and MyFaces) recognizes that the command button is part of a UIRepeat group and guesses the correct row number. But that's just a guess. Obviously a reasonable guess, because most of the time you want to update something that's in the vicinity of the command button.
The next version of BootsFaces is going to guess the correct row number, too :).

Composite component in ui:repeat vs c:forEach using ajax calls

I have a composite component, which represents an item that will be stored in a list. I would like to display these items using <ui:repeat>, but I have problems making ajax calls. The thing is that for <f:ajax> render attribute, I want to give the id of my component through
#{cc.clientId}
However this raises error when I use it with <ui:repeat>, because of the reasons that are explained in this document https://rogerkeays.com/jsf-c-foreach-vs-ui-repeat.
<cc:implementation>
<div id="#{cc.clientId}">
<h:form>
<h:commandLink styleClass="btn btn-info" value="Click me">
<f:ajax execute="#form"
render=":#{cc.clientId}"/>
</h:commandLink>
</h:form>
</div>
</cc:implementation>
Is there a way to make the above component work using <ui:repeat> (for example is there a component which can replace the <f:ajax> tag handler, or are we stuck to <c:forEach> construct)?
<ui:repeat id="myComponent" value="#{backingBean.myComponentItem}" var="item" varStatus="itemIndex">
<components:exampleComponent id="myComponent"/>
</ui:repeat>
So I start using <c:forEach> instead of <ui:repeat>, and I was able to use the id of my component in the render attribute of <f:ajax>. But this time when I make pagination, if the size of the list decreases I start having empty components in my page. For solving this I started doing pagination through ajax calls and this solved the empty component problem.
Just I thought everything was solved I encountered another problem: lets say I have a page listing 10 components, and I went to another page, and from that page I came to the component displaying page again, but for some reason lets say this time I retrieved only 3 items from database, and I just want to display these 3 items through my components but nothing else.. Unfortunately in this scenario, 3 items are displayed correctly, but the page also contains 7 empty components too. For overcoming this I need to redirect to this page one-more time. So I just gave up at this point. Apart from this I also eventually get the exception below, when the number of the components on the page changes.
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.sun.faces.application.view.StateHolderSaver
I tried using the suggestion explained in the post Jsf Error : java.lang.ClassCastException, but it didn't work for me, I started getting another error which is similar to above exception.
<context-param>
<param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
<param-value>/pagename.xhtml</param-value>
</context-param>
So after these long explanations I would just like to learn what is the best approach for creating composite components which are ajax-enabled, who are fully responsible of their own-states and independent of other components, and that can be displayed in the page more than once and the number of components may vary during the page life-cycle (through pagination, navigation etc).
So far the best solution I came up with is, to check number of components in the page and when that number changes through an ajax call or because of a navigation from another page, redirect to the destination page one more time, this refreshes the empty components in the page without creating much disturbance to users. If you come up with any better solution please let us know.

How to use ui:include inside a forEach and use the loop variable inside the included page?

I'm upgrading to JSF 2.0.2 inside Tomcat 7.0.12 and I have a page with a variable number of reusable widgets on it. I used to use t:aliasBean for this purpose, but it doesn't seem to work. I'm now trying the following in my Xhtml:
<c:forEach items="${viewBean.currentView.parts}" var="part">
<t:div styleClass="div#{viewBean.partNumber[part]}">
<c:forEach items="${part.widgets}" var="widget">
<f:subview id="div#{viewBean.widgetId[widget]}">
<ui:include src="widgets/#{widget.widgetPage}">
<ui:param name="widget" value="#{widget}" />
</ui:include>
</f:subview>
</c:forEach>
</t:div>
</c:forEach>
What seems to happen is the next widget from the loop is used in the previous widget's page, so I get errors unless there is only one widget.
Edit: I've tried ui:repeat - it doesn't work. I've also tried removing the ui:include, just as a sanity test; the looping works fine. Also, I'm using Spring 2.5.6.SEC01 - though it shouldn't matter.
I propose to use ui:repeat instead of c:forEach.
Why?
The most important thing to understand
about the jstl tags in Facelets is
that they do not represent components
and never become a part of the
component tree once the view has been
built. Rather, they are tags which are
actually responsible for building the
tree in the first place. Once they
have done their job they expire, are
no more, cease to be, etc etc.
Source [here][1]. I really recommend to read the entire article.
UPDATE:
Please note that I do not say that c:forEach is bad. I want to underline that mixing it with ui:repeat it's not recommended.
[1]: https://rogerkeays.com/jsf-c-foreach-vs-ui-repeat

JSF loop reRender

Hopefully the title isn't too cryptic ...
The problem we have is that we generate a bunch of input controls (h:inputOneMenu, h:inputText etc) from some Java List.
Works fine EXCEPT the requirement is that these inputs validate on the fly. Again not so hard except that as there controls were generated in a loop the only possible reRender action is basically the entire form or an a4j:outputPanel around each loop iteration which is basically the same thing.
Now the above two solutions technically work but they have the nasty side effect of reRendering all the page controls which makes the page feel really twitchy and clunky. We'd like to stop this from happening so ideally the only control that gets reRendered is the control that send the ajax update/validation.
Basically this is our page code:
<ui:repeat value="#{seam-outjected-list}" var="item">
<a4j:outputPanel selfRendered="true">
<h:inputText value=#{item.value}>
<a4j:support event="onblur" ajaxSingle="true" />
</h:inputText>
</a4j:outputPanel>
</ui:repeat>
I've left out a bit of stuff that just renders different controls depending on the item.
As you can see we're currently using the a4j:outputPanel solution so every time any loop generated control is updated all the controls are reRendered.
Thanks in advance if anyone has any thoughts.
My first thought is that you should try replacing your <ui:repeat> with an <a4j:repeat> and take advantage of the ajaxKeys attribute to only reRender certain rows.
From the Richfaces Docs:
The main difference of this component
from iterative components of other
libraries is a special "ajaxKeys"
attribute. This attribute defines row
keys that are updated after an Ajax
request. As a result it becomes easier
to update several child components
separately without updating the whole
page.

Resources