Dmitry Chornyi
Dmitry Chornyi

Reputation: 1871

Preserve JSF messages between AJAX calls

There is a JSF 1.2 page with <rich:messages> and <a4j:poll> components on it. When a message is placed in FacesContext it is only shown briefly, until the poll sends the next request. Is it possible to preserve messages across AJAX requests?

Upvotes: 2

Views: 1933

Answers (2)

Jacob S
Jacob S

Reputation: 26

Add the following to your facelets:

<ui:define name="metadata">
  <f:event type="preRenderView" listener="#{ajaxBacking.displayMessages}" />
</ui:define>

Create a backing bean to persist the messages through ajax calls:

@ManagedBean
@ViewScoped
public class AjaxBacking {

Map<String, List<FacesMessage>> messages;

public AjaxBacking(){
    messages = new HashMap<String, List<FacesMessage>>();
}

public static AjaxBacking getCurrentInstance() {
    AjaxBacking ajaxBacking = null;
    FacesContext context = FacesContext.getCurrentInstance();
    if ((ajaxBacking = (AjaxBacking) context.getViewRoot().getViewMap().get("ajaxBacking")) == null){
        ajaxBacking = (AjaxBacking)context.getApplication().evaluateExpressionGet(context,"#{ajaxBacking}",AjaxBacking.class);
    }
    return ajaxBacking;
}

public void displayMessages(){
    FacesContext facesContext = FacesContext.getCurrentInstance();
    for (String component : messages.keySet()){
        for (FacesMessage message : messages.get(component)) {
            if (!facesContext.getMessageList(component).contains(message)){
                facesContext.addMessage(component, message);
            }
        }
    }
}

public void putMessages(String component, List<FacesMessage> facesMessage){
    List<FacesMessage> messages = new ArrayList<FacesMessage>();
    for (FacesMessage message : facesMessage) messages.add(message);
    this.messages.put(component, messages);
}

public Map<String, List<FacesMessage>> getMessages() {
    return messages;
}
}

And finally add this line to the bottom of any bean method that adds a FacesMessage.

AjaxBacking.getCurrentInstance().putMessages(messages,facesContext.getMessageList(messages);

Upvotes: 1

Max Katz
Max Katz

Reputation: 1582

Possible, but you would need to save the message yourself. Messages in JSF are request scoped, and thus cleared between requests.

Upvotes: 3

Related Questions