aspose file tools*
The moose likes JSF and the fly likes form in h:outputText Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » JSF
Bookmark "form in h:outputText" Watch "form in h:outputText" New topic
Author

form in h:outputText

at rias
Greenhorn

Joined: Mar 18, 2013
Posts: 5

hello to all

I am developing a project using JSF and I have a problem.

I have a h:form that sends data to a session Bean and calls a new page that gets the result from the Bean using h: outputText with escape="false" because the returned value is HTML formated

I have done this following the example here on step 8:
http://netbeans.org/kb/docs/web/jsf20-intro.html#response

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 have found out that I may use regular html form elements (<input type="text">) and then use javascript to copy the contents of these elements to h:inputHidden to submit the second form and send its data to the Bean but this does not seem like a nice solution to me and it is complicated to use.

Is there a better way to do what I need?

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16308
    
  22

Welcome to the JavaRanch, "At"!

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 client submits 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.


Customer surveys are for companies who didn't pay proper attention to begin with.
at rias
Greenhorn

Joined: Mar 18, 2013
Posts: 5

first of all thank you for your reply!

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?

thanks in advance to anyone that cares to help
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16308
    
  22

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.
at rias
Greenhorn

Joined: Mar 18, 2013
Posts: 5

I knew it!

There had to be something that could do the kind of "looping" I had in mind!
(output all the rows of the table!)

It seems that dataTable is what I was looking for!

thank you for your help!
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16308
    
  22

Useful hints:

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!
at rias
Greenhorn

Joined: Mar 18, 2013
Posts: 5

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.

One solution was to use javascript to unselect all other radio buttons when a button is clicked
Another was to use javascript and valueChangeListener to uncheck other radio buttons
Another was to use javascript to "copy" button selections to hidden inputs.
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.


Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16308
    
  22

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.

However, you can attach an AJAX event to a radio button. In JSF2, that can be done by associating an f:ajax element with the button of interest. In JSF1, you'll need the help of a third-party function such as the RichFaces a4j:support element, or else you'll have to do it the hard way manually via hand-coded JavaScript or a JavaScript AJAX library such as jQuery.

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.
at rias
Greenhorn

Joined: Mar 18, 2013
Posts: 5

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
I did not test the ajax solution yet but it seems that the quick-and-dirty solution using javascript is the most easy one.
I will continue research but I believe that in the end I will use javascript with custom html table
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16308
    
  22

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.

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: form in h:outputText