An Introduction To JBoss RichFaces
Specific row update
Updating the whole table is rather simple. How do we update only the row that has been edited? All data components in RichFaces (including a4j:repeat) come with a feature that allows updating only a subset of rows. All such components expose an ajaxKeys attribute that points to the row or rows that need to be updated.
Let's first go over the changes we need to make on the page.
First, we need to set the ajaxKeys attribute on rich:dataTable (changes shown in bold):
<rich:dataTable value="#{userBean.users}" var="user"
ajaxKeys="#{userBean.rowsToUpdate}">That's all we need to do with the table.
Next we need to call a save method from the modal panel when we make changes to the user information. The updated Save link will look like this:
<a4j:commandLink actionListener="#{userBean.save}"
oncomplete="#{rich:component('useredit')}.hide()"
reRender="name, email">
Save
</a4j:commandLink>
The actionListener points to a listener inside the managed bean which we are going to create next. We also have the reRender attribute pointing to columns in the table. Basically, to achieve partial table update, we need to specify two things. First, which columns to update. In our case we are updating the name and email columns. Second, we need to specify which rows to update. This is done via the ajaxKeys attribute which is bound to a Set object that holds row numbers to update.
Let's see what changes are need in the managed bean.
First, we need to create the Set object to hold rows to update:
private Set <Integer>rowsToUpdate;
public Set <Integer>getRowsToUpdate() {
return rowsToUpdate;
}
Only a getter is needed for this property as this property will never be set from the page.
Next, we need the save() listener.
public void save (ActionEvent event) {
rowsToUpdate.clear();
rowsToUpdate.add(users.indexOf(selectedUser));
}
In the save listener, all we need is to save the row number of the user we are editing.
Finally, we need to initialize rowsToUpdate property inside the init() method, right after we create the users:
rowsToUpdate = new HashSet<Integer>();
The only other change we need is to add an a4j:keepAlive tag to the page. This is poor's man conversation scope (like in Seam). Basically, we need to keep the list of users alive for longer than a request and so a4j:keepAlive does just that. Right before the modal panel, add the following:
<a4j:keepAlive beanName="userBean"/>
Make sure everything is saved, redeploy, and run the application. You should now be able to open a modal panel, edit user information, and save the changes. When the changes are saved, only that particular row is updated.
Summary
I'm hoping this example showed you a little bit more than just Hello World. We have used a table component together with a modal panel. These are two components that very often used in real applications. I have also showed you how to edit a particular record inside a table via the modal panel and then only update that particular row. Of course, updating just a specific row is a feature of RichFaces data components.
To point out another thing, when we created an AJAX-based application here, we didn't have to deal with any JavaScript (well, besides the very simple client-side function available in RichFaces). RichFaces takes care of generating all the necessary (and usually quite complicated) JavaScript.
With RichFaces, you can continue using a JSF component-based approach, but with a large set of extra components to build applications with a rich user interface.
About the Author
Max Katz is a Senior Systems Engineer at Exadel. He has been helping customers jump-start their RIA development as well as providing mentoring, consulting, and training. Max is a recognized subject matter expert in the JSF developer community. He has provided JSF/RichFaces training for the past three years, presented at many conferences, and written several published articles on JSF-related topics. Max also leads Exadel's RIA strategy and writes about RIA technologies in his blog, http://mkblog.exadel.com. He is an author of Practical RichFaces book (Apress). Max holds a BS in computer science from the University of California, Davis.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Max Katz replied on Mon, 2008/10/27 - 12:35pm
in response to:
Christian Lehmann
Greg Fasnacht replied on Mon, 2008/11/17 - 10:32am
Max Katz replied on Mon, 2008/11/17 - 12:42pm
in response to:
Greg Fasnacht
Greg Fasnacht replied on Mon, 2008/11/17 - 2:12pm
in response to:
Max Katz
Max Katz replied on Mon, 2008/11/17 - 2:41pm
in response to:
Greg Fasnacht
It's not that you can't use, you can use the beta version. This is how the versioning works:
Eclipse 3.3 --> JBoss Tools 2.1.2
Eclipse 3.4 --> JBoss Tools 3.0.0 beta 1
Robert Wojcikiewicz replied on Wed, 2008/11/19 - 10:39am
Hi Max,
Firstly, your tutorial is realy useful - one of the best I found. Everything would be ok but I hava a small problem. When I click Edit and fill modal window's fields after clicking Save, the edited row table doesn't display my changes. Why? In faces-config.xml I change value of <managed-bean-scope> tag on: session. Before that I had an exception after clicking save button.
I hope you will help to solve my problem.
Best regards,
Robert
rui chagas replied on Wed, 2008/11/19 - 11:34am
Max Katz replied on Wed, 2008/11/19 - 11:37am
Do you have this tag on the page:
rui chagas replied on Wed, 2008/11/19 - 12:09pm
in response to:
Max Katz
yes i do, right before <rich:modalPanel id="anunedit"> . When i click the "save" button the tomcat gets an exception that says "can't find "save" method..
Max Katz replied on Wed, 2008/11/19 - 12:34pm
in response to:
rui chagas
Robert Wojcikiewicz replied on Thu, 2008/11/20 - 3:22am
Hi Max,
I add tag <a4j:keepAlive beanName="userBean"/> after the line <a4j:commandButton value="Edit"...
Now when I click Save app doesn't throw an exception but new value form fields is not saved.
There is one thing. Whitout tag <a4j:keepAlive beanName="userBean"/> and changing bean scope from request to session, changes were present but after when I refreshed web page.
Can you help or suggest some solution?
Regards,
Robert
Max Katz replied on Thu, 2008/11/20 - 11:29am
Brendan Farragher replied on Fri, 2008/12/05 - 11:41am
Hi. What version of JBoss AS are you using? I am using JBoss 4.2, and I cannot get the @PostConstruct method to fire on a simple managed bean. There are no EJBs involved. Just a simple pojo, configured as a managed bean, with one annotated method that has @PostConstruct. I have tried with both request and session scoped beans, but the message that I print to the log never shows up.
Thanks so much.
Max Katz replied on Fri, 2008/12/05 - 12:06pm
in response to:
Brendan Farragher
Hi. What version of JBoss AS are you using? I am using JBoss 4.2, and I cannot get the @PostConstruct method to fire on a simple managed bean. There are no EJBs involved. Just a simple pojo, configured as a managed bean, with one annotated method that has @PostConstruct. I have tried with both request and session scoped beans, but the message that I print to the log never shows up.
Thanks so much.
[/quote]
I used Tomcat 6.
Juliane Gambke replied on Mon, 2008/12/08 - 12:08pm
Hi!
Thanks for the thorough introduction which gave me a good start. I'm expanding the modal panel functionality to behave like a wizard. That means when clicking on the edit button the first page of the modal panel opens, there I can either close the panel or proceed to the next page within the modal panel by clicking the respective button. Now when i close the panel and click another items edit button the panels last page gets displayed instead of the first page. Also the lasts pages values are not refreshed. I've been searching for a solution for several hours now. Do you have any hint for me?
Thank your very much!
Max Katz replied on Mon, 2008/12/08 - 1:13pm
Juliane Gambke replied on Tue, 2008/12/09 - 5:57am
Thanks for the quick reply!
I found another interesting post solving the modal panel navigation/ refresh problem described in my first post. In case anyone is interested:
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4062036#4062036
Augusto Sellhorn replied on Tue, 2008/12/16 - 11:34am
I think I followed all the steps correctly, and I downloaded the latest of everything but I'm getting;
"Core library location for version JSF 1.2, Facelets, RichFaces is not correct."
On the "create JSF project" dialog. Don't know how to get more information on this, anybody have any ideas what I'm doing wrong?
I got the JBoss tools v 3.0.0Beta1 with Eclipse 3.4.1
Augusto Sellhorn replied on Tue, 2008/12/16 - 3:12pm
Whoops, never mind.
I have one of these unzipping programs that won't zip all things out by default if you have an item highlighted, so it seems I missed the lib/ folder!
Max Katz replied on Tue, 2008/12/16 - 6:11pm
in response to:
Augusto Sellhorn
Whoops, never mind.
I have one of these unzipping programs that won't zip all things out by default if you have an item highlighted, so it seems I missed the lib/ folder!
[/quote]
Glad it's working.
Dragan Mijailovic replied on Thu, 2009/01/22 - 8:11am
In my Intranet application I use RichFaces with RestFaces and I use keepAlive tag for my backing beans. All it is ok, but I am afraid of memory overflow because of:
KeepAlive - serializes and stores request beans IN SESSION and restores it after request. ( http://www.jroller.com/a4j/ )
I saw that You used keepAlive tag in Your example. What do You think?
Best regards
Max Katz replied on Thu, 2009/01/22 - 11:31am
That's the intended behavior. a4j:keepAlive tag is used to keep objects alive for longer than request but less than session (basically a very simple idea of a conversation, like in Seam). The bean pointed to by a4j:keepAlive tag is added to the UI component tree and is saved with the tree (either in session or client, depending on javax.faces.STATE_SAVING_METHOD param). When the UI tree is restored, the bean placed back in request scope with all its values. Hope this helps.
Now, I'm not sure about memory overflow - are you talking about a memory leak?
Dragan Mijailovic replied on Fri, 2009/01/23 - 2:31am
Thanks a lot. Yes, I am talking about a memory leak.
But, there is timeout for a conversation in Seam. Is there timeout for "keepAlive objects"? When does JSF(RichFaces) remove old "keepAlive objects"? If it is the answer: when session timeout happens, I think that is not good for memory resources. It is very important.
Max Katz replied on Fri, 2009/01/23 - 11:32am
marius batrinu replied on Thu, 2009/01/29 - 7:31am
hi Max,
What about the delete part of your tutorial? Using this example:
http://livedemo.exadel.com/richfaces-demo/richfaces/dataTable.jsf?tab=editDataTable&cid=1049955
it seems that in order to delete a row we need to add rowKeyVar="row"to the databatable and on the delete button
<f:setPropertyActionListener value="#{row}" target="#{dataTableScrollerBean.currentRow}" />
My question is what type should currentRow be in the backing bean? Can you give us a quick example on how to delete a row.
Thanks
Max Katz replied on Thu, 2009/01/29 - 11:27am
marius batrinu replied on Fri, 2009/01/30 - 11:02am
in response to:
Max Katz
Thanks Max,
I managed to fid the solution myself. Changes:
on delete button/link:
<a4j:commandLink ajaxSingle="true" id="deletelink" oncomplete="#{rich:component('deletePanel')}.show()">on 'Yes' button on confirmation modalPanel:<f:setPropertyActionListener value="#{obj}" target="#{tableDataSource.selectedRow}"/>
</a4j:commandLink>
actionListener="#{backingBean.delete}"and finally backingBean.delete:
works like a charm :-)
Any downsides to my solution?
Thanks :-)
Max Katz replied on Fri, 2009/01/30 - 12:21pm
Harshad Khasnis replied on Fri, 2009/02/06 - 7:57am
Hi Max,
I am using rich:modalPanel
I dont want that modal to be able to resized by user so I have used resizeble="false" attribute.
But it seems there is some bug and it still allows user to resize the modal panel.Can you please help?
here is my code
My development enviorment is
JSF-RI 1.2, Facelets 1.1.15
Richfaces 3.3.0
Thanks
-Harshad
Asma Shah replied on Mon, 2009/02/16 - 8:48pm
Hello,
I've followed the tutorial and on running the http://localhost:8080/richfaces-start/user.jsf page i only get a header saying Just Some Users. It does not load the users as it should be.
I've tried few things we not success. Any leads you can provide?
Thanks a lot in advance