I'm new to JSF. I've just started working on a JSF webapp with lots of page fragements (.jspf). Almost all of our jsp files are .jspf and are added to tabs with something like this:
This has worked pretty well, but now we've run into a problem. We want multiple tabs to use the same page fragment JSP to provide the same view to a different collection of data. When I do this, I get duplicate component id errors. I assume this is because some of the component IDs are specified in the page fragment JSPs.
I'm not sure how to tackle this problem. I've done some googling and brainstorming and haven't made much progress. Is there a good way to do it? Should we do a major refactoring and get rid of the page fragments in tabs architecture to accomplish this? Any examples on the web of providing the same view on multiple tabs with a different set of data on each tab?
I was thinking of trying this but it seems kind of crazy: When a new HtmlTab is needed, programatically create it. Then grab all the child components off another HtmlTab and clone them and set unique IDs in the clones, and then add them programatically to the new HtmlTab. This seems like a lot of work, and probably would run it to problems.
Yup, you're in a world of pain with your Java ServerFaces apps.
It's displaying as tabs, but JSF is seeing it all as one page in one form. You need to break up that data into separate forms. Unfortunately, those tabs likely need to be in the same, single, form tag, so there's no way around it. You've got to make the ids unique in that form.
Validation is another issue. I've seen where validation on empty forms in one tab stop the tab on which the user is working submit their data.
So, I hit similar problems and came up with no really effective solution.
I don't think I have a 100% accurate visualization of this, but I'm working on an app right now that shares components like that.
First off, there exists the concept of a naming container in JSF. In XML, it's an absolute requirement that id's be unique in their namespace, but the "real" id for a JSF component is a composite consisting of its low-level ID plus the ids of its naming containers. One of the naming containers is an HtmlForm. So id's within a form have to be unique, but can be non-unique within other naming containers.
I had an especial annoyance where I had a form that pulled 4 separate views based on the same JSF code. I made the shared code into a Facelets component file that I included as needed. Because of the need for unique ID's, I synthesized the IDs from parameters using EL on the id attributes.
That actually wasn't the cleanest solution. It would have been better to encapsulate the component in naming containers, but I had other distractions at the time.
An IDE is no substitute for an Intelligent Developer.
Joined: May 21, 2009
Thanks for the responses. I'm trying to do a simple demo with all the features we'll need, then apply the solution to our project (assuming i get the demo working). I've hit a snag early in the demo. When the user presses a button, the demo creates a new tab with code like this:
That works fine. Now I'd like to include a .jspf on this new programatically created HtmlTab (ht). I haven't been able to figure out how to include a JSP on a JSF component created programatically instead of statically in a JSP file. How do I programatically do this?
Here's the only thread I've found googling that I thought was related to my problem, and unfortunately it didn't offer any clear solution:
Can anyone offer some advice on how to do this? Assuming I can get over this roadblock, our plan for the demo is to then use scriptlet code in our .jspf files to generate unique component ids for all the components in the included .jspf files.