Retaining the state (collapsed/expanded nodes) of a NestedTree when using BookmarkablePageLink - java

I have a problem that I can't find an elegant solution for. I want to use a NestedTree (or something similar) as a simple menu for my page. Each node links to a Page that shows content that is identified by an ID. To get nice URLs and easy bookmarking I'd like to use BookmarkablePageLinks to link to these pages.
But doing it that way creates a completely new Page each time, thus destroying and recreating the tree, resetting it's state. So with each link click the complete tree collapses and the user has to open it again to choose another link.
I can't find a solution, that satisfies these criteria:
Each tab/window retains a separate state
Opening a new tab copies the state from the tab it's opened from, but is then independent
Easy to use, meaning you don't have to manually set and restore state for each link
It would be okay if the state is not restored when the bookmarked URL is called.
With Wicket 1.4 I was able to use the pageMapName to maintain a map of PageMaps and their menu states in the session. But that functionality got altered substantially with Wicket 1.5 (I'm using 6.8 now).
I would be quite grateful for solutions or tips on how to do this.

But doing it that way creates a completely new Page each time, thus
destroying and recreating the tree, resetting it's state. So with each
link click the complete tree collapses and the user has to open it
again to choose another link.
The tree collapses because its model is being recreated on page load. You are probably keeping the tree's model as a member variable on the page. To get around this issue you should store the tree's model in the session object instead. This way you can retain the state across multiple pages.

You can manage your own pageMaps in Wicket 1.5.x and 6.x. All you need is a little Javascript, see AjaxNewWindowNotifyingBehavior for inspiration.
Then you can keep the expansion state of your tree in your session under pageMap-specific keys.

Related

In Page Object Model, should an overlay modal window be treated as a separate Page Class or within the "Parent" Page Class?

As I train myself on Selenium, I'm using Page Object Model as my design. My practice site is https://www.beeradvocate.com (I like beer and it's presenting some testing challenges I was looking for).
Once such instance is a page overlay or modal window.
I know in POM each page has it's own Class where the page objects are located and the corresponding methods/actions to be taken upon them. Furthermore, if I click a link that navigates to another page, that would return a new page object in the function such as:
return new HomePage();
When the Login link is clicked it generates an overlay modal window. It seems that Frames aren't treated as their own Page Class. It takes a switchToFrame() action. Would the same apply for this overlay? Perhaps just a getWindowHandles() action to navigate to it?
I'm working on this too, and the main problem is that you need to find a way to login to the website. If you are not logged in, you can get only actually receive the first 25 reviews..
I would suggest creating a separate class to represent your modal, especially if it's shared by other pages or may be moved out of that page one day.
But if the modal is super-simple and only included on one page and really specific to that page, then it could be represented by a group of functions within that POM. However you'd need to recognise those methods as a "region" or a sub-group in some way, like namespacing the methods, or using decorators, which I always think in OO terms smells like there's a sub-object here which needs dividing out!
Dividing and composing is pretty cheap in Java so there's not much penalty. But having a big page object with tons of "sub components" can get messy. It probably depends on how well sub-structured the site itself is which will guide your decision. Like if the selector for the modal is relatively clean and separate from the host page itself, it's less "owned" by the page.
This similar answer points out that a "POM" is more of a module reprentation than an entire "page" (whatever that means these days!).
https://stackoverflow.com/a/47141290/209288
This answer also asks the same question.
https://stackoverflow.com/a/49002231/209288
I came looking for a similar answer, and have just made my mind up to decompose my modals, while reading these discussions. (So my answer is based on 15 minutes of thought, not experience!)

Checkboxes Inside A File Tree

So the issue is that I'm getting a runtime error about checkboxes generated inside a file tree needing to be inside a form element. Thing is, it is inside a form element but the form element is wrapped around the tree like so:
<t:Form t:id="form>
<t:Tree t:id="tree" model="model" node="node">
<p:label>
${node.label}
<t:Checkbox value="checkboxNode.selected" />
</p:label>
</t:Tree>
</t:Form>
The root level of nodes generate the checkboxes without issue. However, when I select the plus to expand the tree branch it throws the error for the branch checkboxes. This goes away if I refresh the page and it remembers which branches are expanded. If I go to expand more, then it throws the error again. The same thing happens if I minimize a branch and then expand it again.
I suspect this has to do with how expanding the tree generates its fields using an AJAX call and it not being able to detect the form wrapped on the outside. Two possible work around I've thought of are:
Default the nodes as expanded and disable the minimizing functionality. I lose out on one of the interaction and organization advantages of a file tree doing this though.
Put a form inside the label. This creates a lot of unnecessary extra forms though and I'm not quite sure how to consolidate this into the end goal of creating a list of groups to send emails out to based on the selected labels.
Anyone here have any insight about a better work around for this issue or maybe a way to tell the generated checkboxes to recognize the outer form without needing to reload the page?
Ended up using a different route. The issue I ran into with the checkboxes that was a deal breaker was I couldn't think of a way to tell the booleans on the server side to update based on the client side's checkboxes.
The reason for that was that the booleans were generated based on need instead of being a fixed set on the Java side of the page. Tried a work around by linking unique IDs to the booleans on the server side, but even then I could not determine a way to associate those IDs to the checkboxes on the client side.
So instead I went with eventlinks, which can take a context. I just passed in the generated tree node IDs as a context, which could search for the node in the eventlink and be added to a "selected" list on the server.
As JavaDoc for the Tree component states:
Tree is not a form control component...
Have a look at the source code of AjaxFormLoop and the way it handles AJAX form updates, I believe you need to build a custom component for your needs.

Spring MVC 3.0 - multiple forms or one?

I'm building a page that has a search box that will populate a grid on the same page. There is also a button the user can select to bring up a "window" (JQuery UI "pop-up" in the same page) that lets the user configure said grid.
These are two separate forms but I don't want what was submitted as part of one to undo the other (so when the user submits to change the grid layout the search needs to re-run as well.
I'd rather not store things in session for this since that brings with it its own issues (search results may be large, shouldn't be saved when the page is re-entered later, etc.).
I've considered doing "one large form" (i.e. surrounding all the inputs) for the entire page that is backed by a form backing bean. I would then use which button is clicked to determine the action to take. There will eventually be other buttons on the page as well to add more functionality. This would be similar to how .NET (non-MVC) handles things.
I'm interested in how others may have solved similar challenges. Are there potential issues with my approach that I'm not seeing? Better ways that work with the framework?
What do you mean with:
but I don't want what was submitted as part of one to undo the other
. Are you referring to posting the form and loading the whole page, which in turn will "reset" the other form?
If that is the case I would still keep one page with two forms and make the posts using Ajax (as you may know jQuery makes this a breeze). Upon receiving a response for either call you will need to update the other form accordingly.
Note that you may still have your forms in two separate views if it helps keeping the code clean and then pull their html with Ajax calls into another view. But my point is that at the end I would still keep both in one page since it sounds like they depend on each other so updating one when the other changes may be easier this way,
Let me know if I misunderstood your question.

GWT - how to build a tree that dynamiclly bring the sons from the server?

I'm new to GWT , and I want to create a tree that every time that a node is opened (the user clicked on "+" next to the node) , the actions calls a service with the node id , and the returned results is the list of sons.
Which Class do I need to extend in order to change the behaviour of the "expand" action?
Also , can this be done via smartgwt? How?
Thanks
See the "dynamiac tree" in http://gwt.google.com/samples/Showcase/Showcase.html#!CwTree (click on "source code" to see the source of the sample.
You might also be interested in http://gwt.google.com/samples/Showcase/Showcase.html#!CwCellTree
CellTrees are a bit more complex (and thus harder to grasp) but they perform much better than Trees.

AJAX delay on richfaces tree selection

I have a JSF 2 application which uses a Richfaces 4 tree control. The tree is set to use the "AJAX" switch type. On each selection an AJAX call is made to the server to update the selection value of the tree's backing bean.
On clicking a node there is a delay between the click and the node appearing as selected. The documentation does state that using this method may cause a slight delay, but I wonder why it doesn't just update the style of the node before issuing the AJAX request, so that the user isn't left wondering if the click has been registered.
I've been trying to figure out a way to update the node on a javascript onclick event, but I don't see an id on the span that I'd have to change. Has anyone else tried something similar? Am I going to have to find the parent div and work down to the second span? Surely there's a better way?
Note that using the "client" switch type is not an option, as we need to be able to query for child nodes dynamically. Building the entire tree in one go is not practical in this instance, so it has to be either "server" or "Ajax".
Answering my own question - and contradicting my "no client switching" stipulation a little bit.
Since we're using RichFaces 4, I'm able to specify that tree node expansion should use ajax (allowing the tree to be populated "lazily"), and selection should be client-side only. However, we still had a requirement to store the current selection state in the tree's backing bean. To do so, I added an a4j:jsfunction to the page ...
<a4j:jsFunction name="onSelection">
<a4j:param name="param1" assignTo="#{treeBean.selectedNodeID}" />
</a4j:jsFunction>
... and called it from the "onmousedown" event on each tree node ...
onmousedown="onSelection('#{node.id}')"
This way the tree updates visually without waiting for the ajax request to complete, and feels a lot snappier to the user.
The only problem with this seems to be that the onmousedown event is fired when clicking on the toggle as well, so expanding a node causes it to be "selected" without updating its style. Unfortunately "onselected" doesn't seem to be implemented in the current milestone build.

Categories