Max Katz heads Developer Relations for Appery.io, a cloud-based mobile app platform. He loves trying out new and cool REST APIs in mobile apps. Max is the author of two books “Practical RichFaces” (Apress 2008, 2011), and is a frequent speaker at developer conferences. You can find out what Max is up to on his blog: mkblog.exadel.com and Twitter: @maxkatz. Max is a DZone MVB and is not an employee of DZone and has posted 72 posts at DZone. You can read more from them at their website. View Full User Profile

An Introduction To JBoss RichFaces

08.25.2008
| 421078 views |
  • submit to reddit

One thing you probably noticed is that you have a blue color schema while my screen shots have red color schema. I'm using a different skin. If you would like to change the skin, that's very easy to do. Open WEB-INF/web.xml file and change the skin parameter to ruby:

<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>ruby</param-value>
</context-param>


Save and restart the server.

One thing that's still different is the font size. If you also want to change that, check out this blog entry.

Adding a modal panel


We will first create the modal panel. The modal panel has to be placed outside the original form, because it must have its own form:

<rich:modalPanel id="useredit">

<f:facet name="header">

User

</f:facet>

<h:form>

<h:panelGrid id="userinfo">

<h:outputLabel for="nameInput" value="Name:"/>

<h:inputText id="nameInput" value="#{userBean.selectedUser.name}"/>

<h:outputLabel for="emailInput" value="Email:"/>

<h:inputText id="emailInput" value="#{userBean.selectedUser.email}"/>

<h:panelGrid columns="2">

<a href="#" onclick="#{rich:component('useredit')}.hide();return false">

Close

</a>

<a4j:commandLink oncomplete="#{rich:component('useredit')}.hide();return false">

Save

</a4j:commandLink>

</h:panelGrid>

</h:panelGrid>

</h:form>

</rich:modalPanel>

The code is rather simple, I will talk about the Close and Save links shortly.

Next, we need to open the popup. To do that, we are going to add another column to the table. The column will contain a button to open the popup. We will make this column first. The coding looks like this:

...
<h:column>
<a4j:commandButton value="Edit"
oncomplete="#{rich:component('useredit')}.show()"
reRender="userinfo">
<f:setPropertyActionListener value="#{user}"
target="#{userBean.selectedUser}" />
</a4j:commandButton>
</h:column>
...

For both showing and hiding the modal panel, we use the RichFaces client-side function called #{rich:component('id')} to get a reference to the component (in our case, it’s the modal panel). Once we have a reference, we call the JavaScript API on that component. In our case, it is show() to open and hide() to close the modal panel. Later, we will be calling a save method when the Save button is clicked in the modal panel.

How do we know which row was selected which corresponds to the user we would like to edit. To accomplish that we use a standard JSF tag called f:setPropertyActionListener. It's basically a listener that will take the object in the current row and assign it to userBean.selectedUser property inside the managed bean. We don't yet have this property, so let's add it.

private User selectedUser;

public User getSelectedUser() {
return selectedUser;
}
public void setSelectedUser(User selectedUser) {
this.selectedUser = selectedUser;
}

Before we test this, there is one more thing to mention. Notice that the Edit button’s definition has a reRender attribute set to "userinfo". This is needed in order to rerender the selected user information. We first pass the selected user to the server. When the page is rendered back to the browser, we would like to rerender that property (userSelected) in order to display the selected user.

Go ahead and run the application as we did before. Before you run, make sure everything is saved and all the changes have been deployed. Your page should look like this:

We are now able to click on a particular row and display the user information in the modal panel. What we ultimately want to do is be able to edit user information, but only update the particular row for that user, instead of updating the whole table.

Legacy
Article Resources: 
Published at DZone with permission of Max Katz, author and DZone MVB.

(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

Sorry, just one sortBy attribute. I tried it with RichFaces 3.2.2, it worked for me. What version are you running?

Greg Fasnacht replied on Mon, 2008/11/17 - 10:32am

I'm attempting to set up your project in Eclipse 3.4 (Ganymede). I installed the JBoss Tools plugin (Stable Release 2.1.2 GA) then tried to create a new project (JBoss Tools Web->JSF->JSF Project). I named the project and then chose the "JSF 2.0" JSF environment (other choices were" JSF 1.1.0.2 Reference Implementation", "JSF 2.0 with Facelets" and "MyFaces 1.1.4"). I chose the template "JSFKickStartWithoutLibs" then clicked on "Next" which brought me to the runtime setup window. I chose servlet version 2.5, then tried to create a new Runtime (since the associated text box was empty). Clicking on the "New" button had no effect. Similarly, the Target Server choice list is empty, and the "New" button again has no effect.  Do you have any ideas as to what the problem might be?

Max Katz replied on Mon, 2008/11/17 - 12:42pm in response to: Greg Fasnacht

If you look under Installation section, JBoss Tools 2.1.2 only works with Eclipse 3.3. You need to use JBoss Tools 3.0 with Eclipse 3.4 . You also need to install the custom template (link available in this tutorial) in order to get JSF 1.2, Facelets, RichFaces enviroment available for this tutorial. Let me know if you have other questions.

Greg Fasnacht replied on Mon, 2008/11/17 - 2:12pm in response to: Max Katz

So if I'm understanding you correctly, I can't use the Eclipse Plugin for JBoss Tools, since the plugin shows the latest stable release as being 2.1.2 GA. Am I correct? BTW, thank you for your quick response.

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

I also have an exception when i click "save" button. The "save" method can't be found. can you help me?

Max Katz replied on Wed, 2008/11/19 - 11:37am

Do you have this tag on the page:

<a4j:keepAlive beanName="userBean"/>

 

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

Please post the exception, JSF page and managed bean code.

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

Make sure you have set ajaxKeys attribute on rich:dataTable. ajaxKeys points to rows to be re rendered.

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

[quote=Cold-Gin]

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

There is some info here on how to do that: http://www.jboss.org/community/docs/DOC-11436 . There is also an example in my book, Practical RichFaces. I have a few free PDF copies left, send me an email if you want one (reference this post).

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

[quote=augusto]

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

There is currently no option to time out keepAlive objects. You can try do to it programmatically, it's an attribute of UIViewRoot. Seam converstations would be a better solution.

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

currentRow can be an Integer (or small int). It is the row number in the model you want to delete. I'll post something on my blog on how to delete from a table (http://mkblog.exadel.com).

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()">
<f:setPropertyActionListener value="#{obj}" target="#{tableDataSource.selectedRow}"/>
</a4j:commandLink>
  on 'Yes' button on confirmation modalPanel:
 actionListener="#{backingBean.delete}"

and finally backingBean.delete:

 this.getTableDataSource().remove(this.selectedRow);

 works like a charm :-)

Any downsides to my solution?

Thanks :-)

Max Katz replied on Fri, 2009/01/30 - 12:21pm

Looks good!

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

 

<rich:modalPanel id="mp" resizeable="false" moveable="false" >
<f:facet name="header">
<h:outputLabel value="Move this" />
</f:facet>
<h:outputText value="Try to resize" />
</rich:modalPanel>

 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

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.