7

I'm trying to display a block only if there are Global messages in the JSF Queue.

I tried to use rendered="#{not empty facesContext.getMessageList(null)}", but it's always evaluated to false.

Only way I found is to create a custom EL function and test it in java.

eg. : my el function :

public static boolean isFacesGlobalMessages() {
  return ! FacesContext.getCurrentInstance().getMessageList(null).isEmpty();
}

JSF page :

<h:panelGroup class="block1" layout="block" rendered="#{el:isFacesGlobalMessages()}">
  <div class="block-warn-body">
    <rich:messages id="msg" globalOnly="true"/>
  </div>
</h:panelGroup>

I'm using Mojarra 2.1.5.

Am I missing something ? Thanks !

Edit : tried the following suggestions, but no luck so far :

  • #{not empty facesContext.getMessageList(null)} -> always false
  • #{! facesContext.getMessageList(null)} -> error
  • #{! empty facesContext.getMessageList(null)} -> always false
  • #{fn:length(facesContext.getMessageList(null)) > 0} -> always false
  • #{not empty facesContext.messageList(null)} -> Error : Method messageList not found
  • #{not empty facesContext.messageList} -> returns true if it's a validation error (I only want true on global error)
  • #{! facesContext.getMessageList(null).isEmpty()} -> throws IllegalAccessException: Class javax.el.BeanELResolver can not access a member of class java.util.Collections$UnmodifiableCollection with modifiers "public"
gonzalad
  • 73
  • 1
  • 1
  • 6

3 Answers3

17

no need for custom EL function

try this

rendered="#{not empty facesContext.messageList}"

EDIT

Haven't tried it myself , but try

rendered="#{not empty facesContext.messageList(null)}"

An idea...

 rendered="#{not facesContext.validationFailed and not empty facesContext.messageList}"
Daniel
  • 36,833
  • 10
  • 119
  • 200
  • 2
    The `FacesContext#getMessageList()` returns **all** messages, also the non-global messages. – BalusC Jul 31 '12 at 10:54
  • Tried #{not empty facesContext.messageList(null)} but it generates an exception (see edit above for more info) – gonzalad Jul 31 '12 at 18:12
  • in case you want to pinpoint the situation when you got messages in the msgs list and no validation failure at the same time , take a look at my edited answer.... – Daniel Jul 31 '12 at 18:30
  • Thanks very much Daniel ! Last proposition works fine. The only corner case I find is if I add local jsf messages from java code (e.g. Messages.addError("form:nom", "Erreur spécifique")). But you solution will do really fine, and I'll drop my custom el function. – gonzalad Jul 31 '12 at 20:30
2

I know this is an old thread, but after struggling searching for an elusive solution, I found an explanation for this behaviour, and since I cannot find this explanation anywhere (dunno why), I think this could be helpful.

I made an el function slight different:

public static boolean hasMessages(String clientId) {
    return !FacesContext.getCurrentInstance().getMessageList(clientId).isEmpty();
}

The difference is the parameter clientId. The behaviour of this function is exactly the same as using #{not empty facesContext.getMessageList(clientId)}. Debugging the code, I noticed that when I called the function with clientId = null, the value of clientId inside the function actually is "" (empty string).

After that, I consulted the EL 3.0 Spec, and found:

Section 1.23 - Type conversion

Every expression is evaluated in the context of an expected type. The result of the expression evaluation may not match the expected type exactly, so the rules described in the following sections are applied. [...]

Section 1.23.2 - Coerce A to String

If A is null: return "" [...]

So, I don't think that there's a way to request messages with clientId = null passing the null value as a parameter. The only way is to have a function that does that without using a parameter or testing if the parameter was set to the empty string.

Luciano
  • 53
  • 6
  • Nice catch. This is a known bug in Oracle EL impl and fixed in a.o. WildFly 8.2 / GlassFish 4.1 and newer. Tomcat later reintroduced same bug in Apache EL which never got "fixed" and requires a custom EL resolver. Related: http://balusc.omnifaces.org/2015/10/the-empty-string-madness.html – BalusC Apr 12 '16 at 07:14
  • @BalusC I'm actually using Glassfish 4.1 with Oracle EL impl (v. 3.0.1-b03). Maybe it's not considered a bug because is in the spec, but it is awful for sure to be obligated to implement custom functions/resolvers just to do simple things like this. – Luciano Apr 14 '16 at 12:03
  • It's fixed in 3.0.1-b05. Perhaps it's in 4.1.1 instead. – BalusC Apr 14 '16 at 12:04
1

Try this:

rendered="#{not empty facesContext.getMessageList(null)}

instead of:

rendered="#{not empty facesContext.messageList(null)}"

in the Daniel's answer.

Or this one:

rendered="#{not empty facesContext.getMessageList('inputForm')}

where 'inputForm' is:

<h:form id="inputForm">
...
</h:form>

if you want to address it to only one of the several forms on your page.