This week's book giveaway is in the OCMJEA forum.
We're giving away four copies of OCM Java EE 6 Enterprise Architect Exam Guide and have Paul Allen & Joseph Bambara on-line!
See this thread for details.
The moose likes JSF and the fly likes Setting a Component readonly Dynamically Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » JSF
Bookmark "Setting a Component readonly Dynamically " Watch "Setting a Component readonly Dynamically " New topic
Author

Setting a Component readonly Dynamically

Mike Dingham
Greenhorn

Joined: Oct 06, 2006
Posts: 8
Hi,

I am trying to traverse JSF Component tree and set all components of type UIInput as readonly.

Once I get the component, is this the right code to make it readonly?

if (component instanceof UIInput)
{
Map attrbs = component.getAttributes();
attrbs.put("readonly", "readonly");
}

It does not do any thing for me...

Thanks,
Mike
Bauke Scholtz
Ranch Hand

Joined: Oct 08, 2006
Posts: 2458
getAttributes() retrieves the key/value pairs of the nested f:attribute tags.
What you need is just the setReadonly(boolean) method of the specific UIInput components. For example:

Also see http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/javax/faces/component/UIComponentBase.html
Mike Dingham
Greenhorn

Joined: Oct 06, 2006
Posts: 8
Great Idea! Thanks...

I tried it in all possible places (Before/After Phase Listeners),
it is invoking setReadOnly also (As I see through debugger),
But it never renders in readOnly mode. If I check the tree before
rendering it still shows as readOnly="false" for all components..

Where do you think is the right place to implement this logic?

Thanks,
Mike
Bauke Scholtz
Ranch Hand

Joined: Oct 08, 2006
Posts: 2458
1) Put this logic in the getters of component binding.
Or, if you don't want to use component bindings,
2) Use a phaselistener which loops through the UIViewRoot and sets the UIInput componentent to readonly. Do it at the RENDER_RESPONSE phase.
Mike Dingham
Greenhorn

Joined: Oct 06, 2006
Posts: 8
This is the code I have which does not do anything



//Render readonly JSP
life.addPhaseListener(new PhaseListener() {

public void afterPhase(PhaseEvent event)
{
System.out.println(event.getPhaseId());

FacesContext facesContext = FacesContext.getCurrentInstance();
Boolean readOnly = (Boolean) facesContext.getApplication()
.createValueBinding(
"#{requestScope." + Constants.READ_ONLY + "}")
.getValue(facesContext);

if (readOnly != null && readOnly.equals(Boolean.TRUE))
{
UIComponentBase comp = facesContext.getViewRoot();

JSFUtils.makeReadOnly(comp);
}
}

public void beforePhase(PhaseEvent event)
{
}
public PhaseId getPhaseId()
{
return PhaseId.RENDER_RESPONSE;
}
});


///JSFUtils.java
public static void makeReadOnly(UIComponentBase component)
{
if (component == null)
{
return;
}

if (component instanceof HtmlInputText)
{
((HtmlInputText)component).setReadonly(true);
}
if (component instanceof HtmlInputTextarea)
{
((HtmlInputTextarea)component).setReadonly(true);
}

int noOfChildComps = component.getChildCount();
List childComps = component.getChildren();

for (int i=0; (i<noOfChildComps) ; i++)
{
makeReadOnly((UIComponentBase) childComps.get(i));
}

}





I tried with beforePhase also, but it does not work...

Any Ideas...

Thanks,
Mike
Bauke Scholtz
Ranch Hand

Joined: Oct 08, 2006
Posts: 2458
And after hitting F5 in the browser?

When doing a fresh start, the UIViewRoot is empty and therefore the components are created in the RENDER_RESPONSE for the first time. But I still don't understand why even the afterPhase() action doesn't work during the first call. Just after the 2nd time rendering and so on, this will work.

I have used this piece of test sample
Benoît de Chateauvieux
Ranch Hand

Joined: Aug 10, 2007
Posts: 183
Hi Bauke,

In the Render Response phase, the afterPhase method will be executed after the page has been displayed.
That's why your change doesn't work.

I resolved this problem implementing a custom renderkit that decorates the renderkit of my JSF implementation.

Hope it helps !

Benoît


SCJP5 | SCBCD5 | SCEA5 Part 1
Daniel Almeida
Greenhorn

Joined: Mar 16, 2010
Posts: 7
Benoît de Chateauvieux wrote:Hi Bauke,

In the Render Response phase, the afterPhase method will be executed after the page has been displayed.
That's why your change doesn't work.

I resolved this problem implementing a custom renderkit that decorates the renderkit of my JSF implementation.

Hope it helps !

Benoît


Hi, can you enter in more details about "decorating the renderkit"? I'm trying to alter components attributes before the renderization.

I have this in my faces-config.xml:


... And this is my custom render kit class:


Is everthing right? What i'm missing?

Sorry for english mistakes,

Thanks
Daniel Almeida
Greenhorn

Joined: Mar 16, 2010
Posts: 7
I resolve this with a custom ViewHandler:

[url=http://www.coderanch.com/t/487645/JSF/java/Authorization-over-UIComponents-with-JSF]
http://www.coderanch.com/t/487645/JSF/java/Authorization-over-UIComponents-with-JSF
[/url]

[]s

Daniel Almeida
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Setting a Component readonly Dynamically