Keep Rich-Faces modal panel open when form validation errors occur
Keeping a model panel open after form validation produced errors is a bit puzzling. I found some good hints in the Rich-Faces Developer Guide
-you need a few lines of JavaScript though;(
The guide refers to a Rich-Faces Wiki article and a forum posting.
I have slightly modified the solution. On top of the page (outside the modal panel) I added a hidden form field that just indicates if validation messages exist.
The method property hasMessages is implemented as follows:
public boolean isHasMessages() {
return FacesContext.getCurrentInstance().getMessages().hasNext();
}
The button uses the oncomplete attribute to test the hasMessages element with a little bit of Javascript.
Create FacesMessage within a get-method
Lately I had problems with displaying a FacesMessage. I suspected that it was due to creating it inside a property get-method. As a proof I created a simple demo application.
public class CreateFacesMessageController {
public String newFacesMessage() {
new FacesMessageSupport().error("TEST");
return "success"
}
public String getFacesMessage() {
System.out.println("get-method");
return newFacesMessage();
}
}
The class above contains an action method that creates FacesMessage instance and adds it to the FacesContext through some helper class. A get-method (for pseudo property facesMessage) calls this action method.
A JSP view is using these methods to show the effect described.
The JSP contains a button that triggers the action method, every time it is clicked a faces message is shown.
It also shows the property facesMessage which is bound to the method getFacesMessage.
So one would think that every time the view is show, it also produces a faces message on top of the form – it doesn’t. Here is why:
- getFacesMessage gets called (typically) during the phase RENDER_RESPONSE
- The messages tag is at the very top of the form whereas the outputText element that is bound to the facesMessage property is somewhere below
As a result the messages have alread been rendered when the new faces message is created. You only have 2 choices to remedy. Either you move the messages tag to the very bottom of the form or you make sure that any method that is possibly creating a faces message is invoked in an earlier phase than the RENDER_RESPONSE phase!
JSF Navigation handler
The JSF navigation handler has some implicit rules that cause the same view to be displayed again after processing a post back. For example if a JSP a.jsp executes an action #{controllerBean.actionMethod} and no explicit navigationrule is matching either the action or an outcome, then the navigation handler will display a.jsp again. This is convenient as no navigation rules have to be coded.
On top of that JSF has a built-in behaviour to keep form input values for a previous post if the view id remains unchanged (which is the case here!). To be more specific: if submitted data is available it is displayed otherwise the values of properties bound to a backing bean are displayed (submitted data is only reset when an explicit navigation rule is executed!) This feature is required for supporting the JSF form validation mechanisms. If any form validator reports a validation error, the ooriginating form will rdisplay the form with the values as they were entered before.
However this can get tricky for some special occasions. Next I will describe such a scenario in which this is causing troubles:
I was trying to implement a simple table for selecting a table row and editing the selected row in a form in a different way than I did it before. Table and form are rendered through the same JSP (see below) such that no navigation rules are required.
This does not behave as expected-> when a row is selected, its data is shown in the form. After returning back to the table and selecting a different row, the form shows the same row data as before BUT NOT the data for the new selection.
listController.select is implemented like shown below
public String select() {
setSelectedEntity((T) getDataModel().getRowData());// this injects the selected object into the form controller
return OUTCOME_SELECT;
}
So considering the above described JSF behaviour a navigation rule must be added in order to get this working
/experimental/listformcontroller.jsp
/experimental/listformcontroller.jsp
JSF Days 08 will be held in Vienna from 12.3.08-14.3.08
JSFDays will take place on March 12th to 14th in the premises of FH Technikum Wien. The conference is hosted by IRIAN Solutions Gmbh.
Among the speakers are Edward J. Burns, Kito Mann, Alexander Jesse.
FacesMessage: show summary only
For displaying only the summary for a FacesMessage instance you have two options
- <h:messages showDetail=”false”/>
- Pass no detail to the FacesMessage constructor
The above options have their problems. Let’s say you don’t know if a FacesMessage will be generated with or without detail information but need to show it if available. You can’t go for option 1, you have to set showDetail=”true”. For this case you have to consider how JSF is displaying FacesMessage instances. Let’s look at the implementation of FacesMessage.getDetail.
public String getDetail() {
if (this.detail == null) {
return (this.summary);
} else {
return (this.detail);
}
}
This means that if you instantiate a FacesMessage with detail set null, JSF will display the summary (i.e you will see the summary text twice). To avoid this instantiate FacesMessage with an empty detail String!
JSF RI 1.2_x configuration parameters
The JSF 1.2_x reference implementation is using a couple of configuration parameters that are not easy to find. So I did a source code search and found them in the
com.sun.faces.config.WebConfiguration class.
JSF life-cycle – the trap?
I’m doing quite a lot of JSF demos and prototypes for my consulting and coaching engagements. So (some months ago) I started with a simple framework to speed up things.
One of the classes in this mini-framework is providing a query-by-example style user interaction
- fill in a query form
- perform a query based on the query fields
- show a table with the query matches or show a form if a single row matched
For providing the query result I’m working with a DataModel that is implemented through a property model.
protected DataModel model = new ListDataModel(Collections.EMPTY_LIST);
@Override
public DataModel getModel() {
model.setWrappedData(service.queryByExample(example));
return model;
}
An instance of the class providing the property above is bound as a request scoped managed-bean. Everything is working fine, but as the JSF life-cycle allows a property to be read multiple times as the view is processed. In a simple GET request it would be called once only – during the RENDER_RESPONSE phase. In a post-back it would be called at least during APPLY_REQUEST_VALUES and RENDER_RESPONSE so the database would be hit at least twice.
As I further analyzed this it got clear that the first hit is not returning the right result as the query form attributes have not yet been applied to the bound managed bean properties (this would only happen after the UPDATE_MODEL_VALUES phase).
Only the second query execution returns the desired result.
So I was like this: why not suppress the first query make my database’s life not miserable. Using the beforePhase and afterPhase method binding of the
BUT now my command links for each row were not working anymore.
Creating JSF SelectItem
Creating SelectItem lists for dropdown and list controls is a pretty boring task. Everytime you do it, it’s like why isn’t this already part of JSF – it’s the same stupid task again and again.
So I was like – I should help myself and create something reusable, a component! I have been using JSF now for a while but only slowly I’m starting to write my own JSF components (creating a JSF component is a pretty heavy task, this should get easier in future releases of the JSF specification!).
This time it came to my mind that JSP allows to create EL functions that only require a class with a static method, a tag library descriptor and can be packaged easily into a JAR. So I’d wish a function that can be used in a JSF JSP to convert any collection like type such that JSF can display it through one of its selectOne, selectMany, etc. components.
<%@ taglib uri="http://at.martinahrer.blueprint.faces.el.si" prefix="si"%>
So the selectItem function would just do it’s job and no longer my presentation logic would get polluted with all this collection iterations and SelectItem instantiations.
Sounds interesting, but what is required to implement this function?First we need a tag library descriptor that is dropped somewhere into the WEB-INF folder. And we need the Java code that is actually doing all the heavy job.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
1.0.0
si
http://at.martinahrer.blueprint.faces.el.si
selectItems
at.martinahrer.blueprint.faces.el.SelectItems
java.util.Map selectItems(java.lang.Object,java.lang.String,java.lang.String)
public class SelectItems {
public static Map selectItems(Object value, String labelExpression, String variable) {
assert (variable != null);
Collection
Well, while implementing this stuff I found several other solutions. JBoss Seam is providing some enhanced JSF controls like MyFaces. If you don’t want to pull in their libraries I guess my solution is pretty compact and easy to deploy as well!
Migration to JSF 1.2
Tonight I have successfully migrated my JSF 1.1 / Trinidad 1.0.1 based application to JSF 1.2_04 / Trinidad 1.2.1. I had only a minor problem with a type cast. that resulted from JSF 1.2 now utilizing Java5 generics. Finally JavaEE 5 starts adopting Java5 language features:)
As JSF 1.2 is based on the new Servlet 2.5 and JSP 2.1 spec I deployed to a Tomcat 6.0.13 installation where I previously had a 5.5.23 installation.
Overall I’m impressed how easy this was. Of course I need to run all my test suite to judge quality but I’m confident.
So now I can start with some of the new JSF features and especially the JSP features like unified EL. Finally I can utilize deferred EL expressions in JSP and thus tag file can implement simple JSF components as well without requiring all the heavy lifting for creating some full-blown JSF component.
JavaServer Faces. The Complete Reference
A few days ago I received a book that I have been wating for a while: “JavaServer Faces. The Complete Reference”. It is covering both JSF 1.1 and JSF 1.2 and plenty of advanced techniques for getting the most out of JSF! After going over a few pages I soon got the impression that the book was a good choice. Many of the Tips regarding JSF 1.2 should help me to switch to JSF 1.2 as soon as possible.
Just an example: With JSF <= 1.1 there is always the issue with initializing managed beans especially reading data from some data source. You can’t do it in an accessor method (aka. getter method) as the JSF life-cycle does not guarantee that the method is only called once (actually it can be called multiple times in different phases of the life cycle). In this special situation with reading data from a data source you would hit the database multiple times and thus stress the database. So you always had to find ways to avoid this situation. There are some solutions out that can help with this issue.
With JSF 1.2 this has been adressed by adding the beforePhase and the afterPhase attributes to the f:view tag.
