This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
The problem is that I need to include a form in the data returned from the Bean in which the user should make selections.
This form would pass the user selections to the Bean and call a new page to display the results.
How can I make this possible?
I have tried to add h:inputText elements in the html string returned from the Bean but these are not rendered as form elements
I'm going to be a pedantic pompous ass (as usual), but I think it might help if you think about the problem in the proper terms.
In JSF you don't "have a form that sends data". The clientsubmits the form, JSF acts as the MVC Controller, and it posts the form data to the backing bean(s) referenced in the form. If - and only if - all values on the form are valid.
The form does not "call a new page". If you are using JSF properly, the form submit process fires an action method and/or listener(s) designated by whichever submit control (commandButton, commandLink) in that form the user selected (since there can be more than one). The action method returns navigational information that JSF - operating again as Controller - uses to construct a new View (page) from whatever View Template the action has designated for the next page display. That page can contain form(s) of its own and the cycle repeats on and on.
In most cases a static View Template is sufficient. If you need the new View to contain varying elements and not a fixed form definition, then there are 2 options:
1. For simple variations, you can create a greatest-common-denominator form and use the "rendered=" attribute to show/hide selected controls from this form.
2. For really dynamic forms, you can build UI elements in java code and attach them to a prototype View Template. This is not a thing to be done lightly, as it blurs the Separation of Concerns contract for MVC, makes the application more expensive to create and maintain, and is more likely to break when future versions of JSF are developed than POJO code would be.
Note that Solution #2 is the wrong way to go if you simply want to repeat elements a variable number of times. JSF can do that in a much simpler and safer way. 95 times out of 100, you shouldn't be using Solution #2.
An IDE is no substitute for an Intelligent Developer.
Regarding the way forms and JSF work I would like to thank you for properly phrasing what I ment in my first post
The way I use JSF is exactly what is described in the netbeans tutorial appearing on the link I posted above.
I hope this is the correct way to use it although the h: outputText with escape="false" outputing html does not seem very correct to me and this is the reason of this topic
Also I would like to mention that my Java experience is about 5 weeks long (and mostly weekends - no business days)
My project is a web page that allows to search data from a timetable of bus routes stored in a database
In the first page the user enters search criteria (origin , destination , oneway/roundtrip , dates)
With this data the database is searched and all applicable routes are displayed in the second page
But this second page is a new form where the user selects the bus routes he requires and then submits this data to be stored in the DB again (along with his name , etc)
So the form on the second page has to be dynamically created.
The general view of the 2nd page contains two tables (one for depart routes one for return routes)
Each table has many routes displayed (either direct routes or routes that have stops and bus changes)
I am using templates and template clients (as described in the tutorial).
I believe that my projects falls in the 2nd category of what you described above, do you agree?
Or maybe my little knowledge of JSF leads me to think like that and all I need is a better tutorial on JSF
Particularly something refering to loops in JSF pages to see if i could get 2 lists of route objects containing all the information to be displayed.
what is your opinion?
could you point me to a better source of information now that my project requirements are more clear?
It's funny that that's the sort of app you are working on. I have a "technology sandbox" webapp that I use to try out new Java technology and to showcase my talents to potential customers and that's exactly what it is - a mass transit management system.
It does not use dynamic page design, although I do use Google Maps to display the routes and allow the user to add new transit points to the routes via mouse events.
A View should NOT contain executable code, and that's what "looping" is to me. When I display a bus schedule, it's a table - a 2-dimensional display element, and whether or not some software iterated through the stops to produce it or the whole thing was generated by some other means (such as parallel computation) is immaterial to the view definition. I use the standard dataTable construct to display the schedule.
Speaking as a user, having more than one route displayed at a time doesn't fit well on the screen or in my eyeballs, so that's all I attempt to present when listing schedules. If I were to provide the ability to list multiple schedules, I'd probably store the search results in a session-scope backing bean and use it as the basis for rendering successive pages, wizard-style. I wouldn't bother to keep that sort of information in the database.
1. A lot of people try and bind an array or Collection directly to the value= attribute of a dataTable. The dataTable actually requires a special JSF Model class object to wrap an array or a Collection. This (DataModel) object contains stuff needed both to render the table and to figure out which row in a table an action is being fired from. If you do not supply this Model object yourself, JSF2 will create an anonymous one and use it (JSF version 1 would consider it to be an error).
The problem with having an anonymous model is that if you need to access information in the model itself (such as the "currentRow" value), it's quite complicated and painful and adds a whole lot of extra JSF-specific code to your backing bean. So I recommend building an explicit model object, wrapping it around your data and using that as the backing property rather that simply shoving the raw table source data at the dataTable.
2. You might want to google for the IBM DeveloperWorks series "JSF for NonBelievers" by Rick Hightower. Although it's rather old, it still applies to current versions of JSF. It also just happens to do something very similar to what you're describing!
I have been experimenting with dataTable and I could get the data displayed and now I am back to my original problem!
How to select a row from this table (using a radio button) and submit this selection through a form.
(actually there are two radio buttons on each row but that's another issue!)
All the radio buttons on the table belong to the same group.
I initially thought that it would be easy to use h: selectOneRadio tag arround the dataTable and f: selectItem on each row but this does not seem to work.
I found out some different solutions about this problem.
These solutions rely too much on the client browser.
also to use such a way to solve the problem would mean that I could work with my original thought of html form in an outputText element and no dataTable would be required
A last solution was to create a custom radio button element but this seemed extremely complicated for such a trivial requirement!
Also on later pages i will require checkboxes for multi line selections so this means that a new custom tag would be necessary for this.
I hope that what you mention in your 1st hint (regarding the DataModel object and the ability to get the currentRow value) would be of help to solve this problem but I am currently still researching that.
It's generally a problem to put a separate form on each dataTable row, so in case that had been a thought, forget it. The entire table should be encased within a single h:form.
You cannot fire a server event directly off a radio button. Some people think that that's what listeners do. They are very, very wrong. Listeners don't fire events, they listen to events that have been fired.
The AJAX event will then fire a form submission. For the a4j:support element, its action= reference ties to a public void method with no parameters. For f:javax, the method reference is to a public void method with optional ajaxEvent parameter (which you rarely actually need).
In either case, the AJAX action method can tell what row the button was in by pulling the currentRow from the table's DataModel or by retrieving the DataModel's rowIndex. Usually you'll find it easier to use the currentRow, as typically one of the current row's columns will be the database key for that row.
I tried using t: radio with spread layout and this seemed to solve the problem (I read about this solution in another topic in this forum).
that is until the moment I tried to put a second radio button on each row (all table buttons belonging to the same group).
this again seemed impossible.
Unfortunately with every problem I try to solve one or more new problems appear.
Also I wanted to have some cells with rowspan and as I read this is not possible in either h: dataTable or t: dataTable
If you are working with an AJAX-friendly tagset, it will provide a much cleaner and quicker way to notify the server. Writing your own AJAX from scratch is dirty, but not quick. At least consider jQuery so you don't have to code all the sordid details yourself. And spend half your life battling browser dependencies.
JSF does not support rowspan or colspan, although there are a few extension tagsets that do. Mostly, however, the preferred way of handling the spanning issue is not to span, but simply to embed sub-divided grid controls. Spanning in reverse, as it were.