Dynamically add components according to request parameters
Hello!
I've been developing quite a big JSF application in the last months, using Studio Creator 2. This was the first serious project I developed in JSF therefore I followed the guidelines I learned in various tutorials. Now that I need to do something outside these guidelines I realized I lack some basic concepts!
I need to specify a request parameter (say, /MyPage.jsp?category=2) and dynamically append several components to a panel:
public PanelLayout getPanel(){
buildNeededComponents();// This queries a DB and appends the appropriate components to this.panel
return this.panel;
}
Of course I need to generate different components according to the 'category' parameter. The problem is that the getPanel method is called just the first time the page is requested.
Can anyone please tell me what's the problem? How can I solve it?
Thanks!
[1061 byte] By [
davide] at [2007-11-26 9:20:21]

# 4
Thanks! BUt...
I know init() gets called each time, the problem is that the graphical components' getXXX() don't!
Specifically, I have a PanelLayout in the JSP:
...
<ui:panelLayout binding="#{Documents.panelLayout}" id="panelLayout" rendered="#{(SessionBean1.contact)}">
<ui:markup tag="a" extraAttributes="name=top"/>
<ui:staticText binding="#{Documents.staticTextGoTo}" id="staticTextGoTo" text="View All: "/>
<ui:dropDown binding="#{Documents.ddAvailableDocs}" id="ddAvailableDocs" items="#{Documents.availableDocTypesDataProvider.options['category,tbdoctypes.doctypeName']}" onChange="document.location='Documents.jsp?cat='+this.value;"/>
</ui:panelLayout>
...
Inside the backing bean I used:
...
private PanelLayout panelLayout=new PanelLayout();
public PanelLayout getPanelLayout(){
buildDocsTables();// This is the private method where I add the components
return this.panelLayout;
}
public void setPanelLayout(PanelLayout pl){
this.panelLayout=pl;
}
...
public void init(){
...
try{
if(getSessionBean1().isContact()){// To bind some items to the DropDown list above
availableDocTypesDataProvider.getCachedRowSet().setLong(1, getSessionBean1().getUser());
availableDocTypesDataProvider.refresh();
}
...
}catch(SQLException sex){
...
}
...
}
Inside buildDocsTables I read the request parameters which come with the HTTP request and use them to generate the appropriate code.
Debugging, I noticed that getPanelLayout() is called just the first time the page is requested, so I tried two things:
private PanelLayout panelLayout=null;// Set to null
public PanelLayout getPanelLayout(){// Removed
return this.panelLayout;
}
...
public void init(){
...
try{
if(getSessionBean1().isContact()){// To bind some items to the DropDown list above
availableDocTypesDataProvider.getCachedRowSet().setLong(1, getSessionBean1().getUser());
availableDocTypesDataProvider.refresh();
panelLayout=new PanelLayout();
buildDocsTables();
}
...
}catch(SQLException sex){
...
}
...
}
I just saw that buildDocsTables actually sees that the request parameters change, but again, getPanelLayout isn't called, so the net effect for the user is that nothing changed on the page!
The second thing I tried is adding visible="#{Documents.visiblePanel}" and the corresponding method (which returns always true) inside the backing bean, to try to force evaluation of the component. Again, no changes!
I also tried to 'Clean and Build the Main Project', as Sun suggests in the documentation if one sees 'strange things'... I strongly hope this is my fault!
Please!! If I'm using the wrong approach, What can I do to generate components at runtime according to what I get from the request parameters?
Thank you!
PS:
I even tried to add meta tags to the page:
<ui:meta httpEquiv="pragma" content="no-cache"/>
<ui:meta httpEquiv="cache-control" content="no-store, no-cache, must-revalidate"/>
<ui:meta httpEquiv="expires" content="0"/>
Result: nothing changed!!!
# 5
Hi,
My cowoker is finishing up a tutorial on building a Tree component from database values. While this tree has the same structure every time, I still think you might be able to do something similar using the same patterns.
Here is the tutorial's code that goes in the prerender method.
try {
// If nbrChildren is not 0 then this is a
// postback and we have our tree already
int nbrChildren = displayTree.getChildCount();
...
List children = displayTree.getChildren();
children.clear();
// Execute the SQL query
tripDataProvider.refresh();
// Iterate over the rows of the result set.
ADD CHILDREN TO THE PANEL LAYOUT HERE
Leave the follow as is and add the children to the panel layout similar to above
private PanelLayout panelLayout=new PanelLayout();
public PanelLayout getPanelLayout(){
return this.panelLayout;
}
public void setPanelLayout(PanelLayout pl){
this.panelLayout=pl;
}
Just a guess that this migh help,
Chris