myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Josué Alcalde González <josuealca...@gmail.com>
Subject Re: Acces the tree component from facesContext
Date Thu, 08 Mar 2007 23:44:56 GMT
I realized I could use FacesContext.getViewRoot() watching at tomahawk
sources but it did not work.

I will try to explain the problem, but I think it would be hard to
solve.

I want to have a component with 4 divs for messages, one div for each
message level.

My first approach was four t:messages using some style hack. Using
infoStyle, fatalStyle, errorStyle and warnStyle I used 'display:none' or
'display:block' to see only the messages I want.

It would be a great feature a discriminator in t:messages to avoid such
a dirty way to hide unwanted messages.

I was not a very good solution, but it works.

When I switch to facelets I discover el functions, so I make some
functions to ask facesContext about messages.
I have functions to know if there is messages of a level and functions
which return the list of messages of a level.
Easy to do using FacesContext.getCurrentInstance().getMessages().

Perfect for me, but there was a problem, ids for inputs in messages are
not replaced by labels.
So I try to solve it. I went to FacesContext api and I found
getClientIdWithMessages() and getMessages(clientId).

Then I only need the viewRoot to use findComponent(clientId) and find
the input and the label.

But it didn't work. The component for clientId is not found. I debug it
and I realize that the facelets tree in the moment the function is
executed has nor the input components neither the label components.

The function is executed from el in something like this:
<li jsfc="ui:repeat" value="#{myfunctions:getInfoMessages()}"
var="message"/>

And the function would have something like this:

Iterator itClientIds =  
FacesContext.getCurrentInstance().getClientIdWithMessages();
while (itClientIds.hasNext()){
Iterator itMessages =
FacesContext.getCurrentInstance().getMessages(it.next().toString());
while (itMessages.hasNext()){
UIComponent component =
FacesContext.getCurrentInstance().getViewRoot().find(component);
// Component is null, so nothing more to do.
[...]
}
}

I don't know too much about component tree, phases and things like that.

I am using javascript to make the client validation show in the same
divs, with the same appearance of server validation, so there would be
very little messages from server with ids (most of them would be custom
messages without component).

Anyway, it would be great to solve this small problem.

Perhaps, The best would be to add renderInfo, renderWarn, renderError or
renderFatal attributes to t:messages. It would be easy, and perhaps it
could be my first patch for tomahawk :)

El vie, 09-03-2007 a las 08:54 +1300, Simon Kitching escribió:
> Josué Alcalde González wrote:
> > I think I could do it if I would have access to the tree from
> > FacesContext.
> 
> This can be done with FacesContext.getViewRoot()
> 
> > 
> > There is a function:
> > facesContext.getClientIdsWithMessages()
> > which gives me all the "clientId" which have messages.
> > 
> > Then, I get all the messages form all the clientIds using:
> > facesContext.getMessages(clientId);
> > 
> > No, if I have clientId as a String, is there any way to access the tree
> > and find the component with that clientId, and then, find its label,
> > with for="clientId"?
> > 
> 
> UIComponent.findComponent(id) can be used to find components.
> 
> This method is really designed to take a "JSF Component Id with path" 
> rather than a "client id" but in basic usage I believe these are the same.
> 
> One case where I know it will not work is for components nested within 
> tables; the same component is reused for each row with a hack used to 
> insert a "row index" into its clientId depending upon what the current 
> rowIndex value is for the table it is nested in - ie what getClientId() 
> returns depends upon what rowIndex is set in the owning table.
> 
> An alternative to using findComponent is to just walk the tree manually, 
> looking for components with clientId values that match the ones you 
> want. Again, however, table components can cause problems. It is 
> possible to deal with the table problem (I implemented exactly this just 
> this week) with about 10 lines of code.
> 
> Regards,
> 
> Simon


Mime
View raw message