JSF loop reRender - jsf

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.

Related

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

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.

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 :).

Render a jsf element on mouseover

I have a <h:panelGrid> and a h:commandLink(link is basically a image).Now I want that on mouseover event , Then link should be render(render='true') and on mouseout event, it gets removed render='false'.But I am unable to create the logic that How can I do this with these events as the approach I am using is To set the values of bean true and false on this event.
Here is my code
<h:form>
<h:panelGrid mouseover='** we cannot call a bean method here which changes the bean value **'>
This is the Div On which I want to apply mouseover event
</h:panelGrid>
<h:commandLink id="btn" render={renderBean.renderLink}>
<h:graphicImage url="image.jpg"/>
</h:commandLink>
</h:form>
The default value of renderLink attribute of renderBean is false. Now I want to know the way that How can I change its value to true on mouseover event? Is it possible? OR Anyother solution in JSF w.r.t this requirement
You have to remember in JSF that the page will first be processed server-side by the JSF engine in the web server. At that time all JSF tags will be converted into their HTML equivalent. The render attribute tells the server-side engine whether or not to output an HTML a (anchor) link in the place of the <h:commandLink> element.
The behavior you're looking for, namely responding to mouse events, is client-side functionality. It happens in the browser, not at the web server, so no JSF is involved. The solution is to handle the mouse events in JavaScript, not JSF. You will typically set (or remove) the CSS attribute display:none on the id called btn (unfortunately it's slightly more complex as JSF will mangle the element id a bit). There are lots of posts here on StackOverflow that deal with how to handle client-side events in JavaScript. Using jQuery for example is a really common approach.
I recommend to get started you take a look at the blog of one of our best JSF resources and long-time StackOverflow user BalusC: http://balusc.blogspot.com.
There's a lot to learn and you'll get a good start by going there first (and searching for his posts on SO).
Good luck.

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 Refresh only components in certain 'box'

Say I have a websites with 3 panel grid (just for example..) and I would like to have buttons inside each grid that only cause the contents of that grid to refresh so the rest of the page doesn't necessarily have to refresh.
How do I do that?
I tried to have a form sorround that grid but it seems like the rest of the page still gets refreshed.
A Note - I'm trying to achieve something like what happens when you work with a picklist. when you move the objects between the lists there doesn't seem to be any page refresh...
Thanks!
If you are using RichFaces, you should definitivly check the Ajax chapter of the RichFaces manual. I think you will find everything you need to know there.
Here a small example for partial page rendering:
<a4j:commandButton value="update" reRender="infoBlock"/>
<h:panelGrid id="infoBlock">
<!-- Some content-->
</h:panelGrid>

Resources