On Thu, 2009-02-19 at 11:16 +0530, Madhav Bhargava wrote:
> On Mon, Feb 16, 2009 at 2:48 PM, Simon Kitching <skitch...@apache.org>
> wrote:
> 
> Madhav Bhargava schrieb:
> 
> > Hi All,
> >
> >
> >
> > I have a requirement wherein I have to disable UI components based
> on
> > whether there are any error messages in the Message Queue
> (t:messages).
> >
> > facesContext is an implicit object so I thought of using it like -
> > #{facesContext.getMessages.hasNext} However when it was not working
> > because you can only specify properties of a class and JSF variable
> and
> > property resolver will then internally try and call the
> getter/setter of
> > that property.
> >
> >
> >
> > I find that rather limiting because I do not find the need to define
> a
> > class level property when all I need is to process and output a
> Boolean.
> > Is there any way apart from overriding the
> > PropertyResolver/VariableResolver?
> 
> >Simon wrote:
> 
> 
> >No, EL does not allow "method calls". It only allows reading/writing
> >properties.
> >
> >However isn't this enough for what you want to do?
> >
> >You could create a simple class:
> >public class MessageChecker {
> >   public boolean isMessagePresent() {
> >     return FacesContext.currentInstance().getMessages().hasNext();
> >   }
> > }
> >
> >Then register this class as an app-scope managed bean.
> >
> >JSF components can then do
> > disabled="#{messageChecker.messagePresent}"
> >
> >Yes this means creating a trivial class, and having an instance of it
> in
> >memory in order to call a static method from the JSF components. This
> >could be considered ugly. But on the other hand, the JSF pages are
> now
> >much better isolated from the details of the implementation.
> >
> >Regards,
> >Simon
> 
> 
> 
> 
> Your solution will not work for messages which get added to the
> FacesContext during the validation phase. Method isMessagePresent()
> will not be called. That is the reason I was looking at accessing the
> messages as an EL expression.
> 
> If there is a validation/conversion exception thrown then it will
> directly go to the render response phase after completing the
> validation phase.
> 
>  
> 
> I will try and use a scriptlet to get access to messages and see if
> that is going to work. Not the best way of doing things but I will
> have to live with that as of now.

I don't think your evaluation is quite right. IMO there is a problem,
but not the one you think.

Am I right in thinking that your pages correctly *render* (ie when using
my suggestion, components do get disabled when rendered), but that you
then have problems when the page later gets submitted back to the
server?

Firstly, "disabled" is probably the wrong thing to use. A "disabled"
HTML component never submits any data back to the server on submit,
which often confuses JSF components. Usually, setting "readonly" is
better than setting "disabled".

Secondly, I presume that you want these "not accessable" input
components to be ignored on the server after postback, ie they should
not be validated. But setting the "disabled" flag is not going to affect
server-side validation at all. The JSF components are still in the
component tree, and are still marked as "rendered", so they will look
for their input in the submitted data (and not find it) then try to
validate themselves. Even if you set "read-only" on the component, it
will still try to do this. The only thing that suppresses the
component's attempts to fetch data from the submitted form data and do
validation is when rendered=false.

And checking the list of *messages* during postback is not really what
you want here. What I think you want is that during postback on the
server, input components are skipped if there were messages present *at
the time the page was rendered*. But that information is simply no
longer available; the messages list is *thrown away* at the end of each
request.

One option is to use "read-only", and ensure that when read-only is set
then the value property is something that will not cause a validation
failure.

Alternatively, you need to somehow store info about whether messages
were rendered or not in some variable that still exists on postback
(unlike the messages list, which has been thrown away). Every JSF
component has a map of attributes that you can store arbitrary data
into, and which is then persisted into the tree. So maybe you could
store an attribute on the view-root to indicate whether the previous
pass had messages or not. Then use this in the "rendered" property of
components, in order to prevent them from attempting to validate
themselves during postback.

There are also a couple of libraries around that extend the validation
facilities of JSF. You might want to search the myfaces wiki for
"validation".

Regards,
Simon


Reply via email to