I have a strange problem with a JSF2 application. I'll try to describe it in detail.
My home page has eight links: 5 on the header and 3 on the footer. I also have a search component which I need to show -- once the user is logged in -- for 3 of those pages. The way I'm doing it is by passing a "fromPage" attribute in the session, and making a decision to show, or hide the search component.
When I am using <h:commandLink> for all my home page links it all works fine. But another problem arises: the JSF url's are trailing by one click. This is a known issue so I wont' go into detail explaining it, but simply put when I click on "Contact Us" from the "Home" page the pages changes to the Contact Us page but in the URL I'm still on the home page. Which creates a completely unintuitive environment for the user.
So I moved all my links to <h:link>. Now the url's change every click and it behaves normally. But now all the "outcome" methods -- for all 8 links on the home page -- are called from left to write, top to bottom ON EVERY CLICK TO WHICHEVER PAGE. The url changes correctly and the page is displayed correctly but the "fromPage" attribute in the session is always for the last link called: the one at the bottom right.
To make things even more bizarre, my Search component is always showing, because the last link on the header is for one that it should show for. When I test this by putting another link on the page -- at the top right, just before the Search component -- for a page the Search shouldn't show for, the Search doesn't show. Ever. No matter which page I'm clicking to.
I can simply give up on the url's showing the correct page, switch back to commandLinks, and move on with my life. But I want to get it right, and help my users. Is there a solution?
(If this is not clear enough and you need more information please let me know!)
I'm not clear on all of that, but I can provide a few observations, for whatever they may be worth.
First, as you already know, depending on URLs for guidance in JSF is a sub-optimal approach.
Secondly, it's more likely that you're interested in what mode the user is in than where they came from when it comes to making components visible. So rather than play URL games, I'd keep that information in a managed bean. If it's a common context, I would then either make my views reference that bean or I'd inject that bean into the primary backing bean(s) on the views. Or both, depending on what works best.
An IDE is no substitute for an Intelligent Developer.
Joined: Feb 16, 2010
Thanks for replying, Tim. I solved my issue by using the viewId, which you can get like this:
Instead of checking the session for which page I'm on, I'm simply doing it like this.
OK. But as a general rule, any time you start referencing any object or interface in javax.faces other than the faces model classes, you should always make certain that there isn't a simpler, cleaner way. JSF is designed to do most of its work with POJOs, and one of the biggest offences that people commit is diving into JSF internals when they don't need to.
That's not recommended. It makes your code dependent on a platform and on a version of the platform. Which ups the cost of maintenance, since platform-specific code may require serious modification on new releases of the platform. It also ups the cause of testing, since you can't use simple jUnit-style testing once you start referencing framework components. Not unless you have a unit-test system that can reliably mock up the framework. Which, even if you do, is generally a pain to set up and a drag on productivity, since POJO tests run faster (since they don't have to build and tear down the mock framework).
Joined: Feb 16, 2010
Thank you, Tim. This sounds like a really good tip, I'll keep it in mind.