Problem rendering a dynamically populated tree in a postback

I'll try and keep this as simple as possible...

On page1 I have a table with a button column. When the user presses one of the buttons, the ID for that row is saved in a variable in the session bean, then navigates to page2.

In the init() function of page2 I generate a new tree object using parent/child data retrieved from a database using the ID saved in the session bean. Then I use setTree1(newTree); to apply the data to the component on the page.

The first time a user presses a button on page1, page2 is displayed with the correct data in the tree. If the user navigates back to page1 and presses a different button, page2 is displayed with the tree data from the initial button that was pressed.

I have a number of static text components on page2. The values are updated in the same function that the tree is generated, and all of these get updated correctly in the postback.

Still with me?!

I understand that in the first stage of the lifecycle if the page request is an initial request the the JSF implementation creates an empty view and advances to the render response phase. - eg the first time a button is pressed page2 is shown with the correct tree.

If the page request is a postback a view for this page already exists and the JSF implementation restores the saved view. - eg the second time a button is pressed page2 is shown with the tree data from the first button press.

So my question to you JSF gurus...

Is there some way to make sure that getTree1() is called somewhere in the postback to update the values in the tree, and render the changes on the page.

...or can I make every request to page2 an initial request so that the view isn't saved?

I hope I've been clear on what I'm trying to do here. I've been banging my head against my desk for afew days tryin to figure this out! Thanks in advance for any help

Olly

[1925 byte] By [NievO] at [2007-11-26 8:42:49]
# 1

Hi,

I have only worked with pages where the tree is on the first, not second page. So, I will blurt out my first thoughts and then, when I have some time, test a project where the tree is on the second page.

The first question that pops in my head is "why are you building the tree in the init and not the prerender" I am thinking that simply moving the code to prerender might solve your problem.

The following is an excerpt from a blog that I wrote on the lifecycle methods

"init. Use this method to initialize resources, such as constants and bean properties. Do not use this method to get or set component values (such as getText() and setText()). When init is called, the page's components may have values, but these values can be stale. If the page is being displayed after submission, the values will not reflect the submitted values. Therefore, the init method is not a good place to reference component values. Nor is it a good place to set component properties. This is because the values can get overwritten after the init method completes."

So, let me know if that makes any difference. If not, then, like I said, I will try to modify my project to build the tree on the second page based on a parameter supplied by the first page.

Chris

http://blogs.sun.com/roller/page/divas

jetsons at 2007-7-6 22:22:48 > top of Java-index,Development Tools,Java Tools...
# 2

Hi Chris,

I tried building the tree in prerender(), preprocess(), and init(), and it didn't seem to make a difference. I have a bunch of static texts on the page which I also change the value of dynamically in the same function I build the tree and these are updated fine.

I will double check what I have done tomorrow with a clear head to make sure its not just a silly mistake.

Cheers for your input.

NievO at 2007-7-6 22:22:48 > top of Java-index,Development Tools,Java Tools...
# 3

Ok, this is what I have done to debug...

I dragged a message group component onto the page2, altered the get statement for my tree to include a message

public Tree getTree1() {

info("GETTING TREE");

return tree1;

}

and added another message to the end of the function that generates the tree

info("Tree: " + tree1);

When I run my app I get the following messages on the page for the first button click (initial page request):

Tree: com.sun.rave.web.ui.component.Tree@3bf486

GETTING TREE

and this message for the second button click (postback):

Tree: com.sun.rave.web.ui.component.Tree@d569b5

It looks to me that the tree is being populated fine as the component has a different IDs for each request, but whatever calls getTree1() to display the tree only does it on the initial page request.

I double checked where I was calling my function from, and it was prerender(). My static text is updated ok still.

I checked it again in init(), and you were right Chris, this doesn't work. I was obviously v.tired and had major brain ache last nite.

I hope this adds abit of clarity to my problem.

I am completely stumped now, and have no idea what to do next?

Olly

NievO at 2007-7-6 22:22:48 > top of Java-index,Development Tools,Java Tools...
# 4
hey - I've worked through similar issues now... you replied to one of my earlier posts - please let me know if you're still having trouble and I might be able to assist...kevin
yukhntr at 2007-7-6 22:22:49 > top of Java-index,Development Tools,Java Tools...
# 5

Hi Kevin,

yes, I am still having problems. I think the problem you were working only involved one page with a dynamically generated tree in each one of your tab panels? I have managed to get my tree to populate correctly if I only use one page, but the problem is I need 2 pages, which doesn't work for some reason?!

Any input is greatly appreciated, as I don't have long left to finish this project.

Cheers,

Olly

NievO at 2007-7-6 22:22:49 > top of Java-index,Development Tools,Java Tools...
# 6

True, I'm using one page with tabs and one tree. Are you using the same tree for each of your two pages, or separate trees for each page?

Wouldn't your page code be the same for each different page, just using different tree data to build with?

Maybe I don't understand exactly what you're trying to do...

yukhntr at 2007-7-6 22:22:49 > top of Java-index,Development Tools,Java Tools...
# 7
I have 2 pages. On page 1 there is a table with a button column. When a button is pressed, page2 is opened with additional data related to that row in the table, including a dynamically generated tree. So there is 1 tree.
NievO at 2007-7-6 22:22:49 > top of Java-index,Development Tools,Java Tools...
# 8

> I understand that in the first stage of the lifecycle

> if the page request is an initial request the the JSF

> implementation creates an empty view and advances to

> the render response phase. - eg the first time a

> button is pressed page2 is shown with the correct

> tree.

>

> If the page request is a postback a view for this

> page already exists and the JSF implementation

> restores the saved view. - eg the second time a

> button is pressed page2 is shown with the tree data

> from the first button press.

If you have this

Page1 Button Pressed > Page 2 > Return to Page 1 via Link or Button > Page 1 > Page 1 Button Pressed Page 2

Then the second time you got to Page 2, that is not a postback.

This is an example of a postback:

Page1 button pressed > button returns null > Page 1 redisplayed

or

Page 1 > Something selected from DropDown with AutoSubmit on Change set to True > Page 1 redisplayed.

jetsons at 2007-7-6 22:22:49 > top of Java-index,Development Tools,Java Tools...
# 9

I set up a test where I use the Travel db and pass a person id from page 1 to page 2. I build a tree of that person's trips in Page 2. Every time I go to Page 2, I get the tree of trips for that person.

On page 2 I have a tree from which I have deleted all nodes. Its ID is displayTree.

Here are excerpts from my prerender code.

// If nbrChildren is not 0 then we have our tree already

int nbrChildren = displayTree.getChildCount();

if (nbrChildren == 0) {

// List of outer (person) nodes

List outerChildren = displayTree.getChildren();

// Erase previous contents

outerChildren.clear();

// List of inner (trip) nodes

List innerChildren = null;

// Execute the SQL query

...

< in my loop where I iterate through the query>

TreeNode personNode = new TreeNode();

personNode.setId("person" + newPersonId.toString());

personNode.setText(

(String)tripDataProvider.getValue(

"PERSON.NAME"));

// If the request bean passed a person id,

// expand that person's node

personNode.setExpanded(newPersonId.equals(thisPersonId));

outerChildren.add(personNode);

innerChildren = personNode.getChildren();

}

// Create a new trip node

TreeNode tripNode = new TreeNode();

tripNode.setId("trip" +

tripDataProvider.getValue("TRIP.TRIPID").toString());

tripNode.setText(

tripDataProvider.getValue("TRIP.DEPDATE").toString());

// Set "action" property to use for navigation

tripNode.setAction(

getApplication().createMethodBinding

("#{Page1.tripNode_action}", null));

innerChildren.add(tripNode);

jetsons at 2007-7-6 22:22:49 > top of Java-index,Development Tools,Java Tools...
# 10

Cheers for all you help Chris, I have managed to figure it out now.

When I was creating the tree in the prerenderer I created a new tree:

Tree newTree = new Tree();

Then after I had populated it with data I did:

tree1 = newTree;

This worked great for the first time the page was accessed, but not for any time after.

To fix it I just edited tree1 in the prerenderer, by clearing its nodes

List topLevelNodes = tree1.getChildren();

topLevelNodes.clear();

Then I populated it with new data and all was good.

Thanks again for all your help.

Olly

NievO at 2007-7-6 22:22:49 > top of Java-index,Development Tools,Java Tools...