Reputation: 36327
In many cases you want to add HTML-Controls or Facelets to your Website, but how easy is it really to just access these when you call upon an action?
I have the following commandLink to execute an Action
<h:commandLink action="#{MyBean.save}" value="">
<f:verbatim><input type="button" value="Save"/></f:verbatim>
<f:param name="id" value="#{MyBean.id}"/>
</h:commandLink>
The Param is there to save the QueryString-state so my application won't crash.
Now, imagine you have a <input type="text" />
or <h:inputText value="hello" />
now these components are fundamental to get your site up and running, especially if you are creating some dynamics.
However, if the Controls are not Bound to anything, or if you have a Listbox which you can add elements to with JavaScript, how do you access these when you execute the commandLink or commandButton? Do you Have to bind the controls to your Bean or is it possible to access this FaceContext in another way to retreive the values of either a listbox, input text or whatever else you would want to have?
Upvotes: 0
Views: 1910
Reputation: 108959
It can be difficult to treat a JSF-rendered page as a big glob of HTML and JavaScript (which, I think, is at the heart of the question). You cannot add arbitrary form controls to the application on the client and expect the JSF framework to interpret them. JSF uses pre-defined components, so a component would have to know how to interpret the extra data coming from the request. Because it all ends up as a HTML form interpreted by a servlet, the data sent from the client will still end up in the parameter map - but, these values won't pass through the JSF lifecycle, so won't benefit from validation/data binding/etc.
A JSF control tree looks much like any other widget tree (like Swing or SWT):
UIViewRoot
|_HtmlForm
|_HtmlInputText
|_HtmlCommandButton
A JSF control basically works like this:
Renderer
writes markup to the outputUIComponent
(which may in turn push it to a value binding for the model)Taking your specific example of a listbox - this is a tricky one. JSF provides a HtmlSelectManyListbox which ends up as a SELECT
element in HTML. It is possible to add OPTION
children to the DOM using JavaScript on the client, but this doesn't do any good when it comes to submitting the form. If you read the HTML spec, it says:
Only selected options will be successful. When no options are selected, the control is not successful and neither the name nor any values are submitted to the server when the form is submitted.
So, when the form is submitted, only the list elements that are selected by the user would be transmitted to the server. You would need some hidden fields to get all the new data to the server. There isn't a control in the core set that will help you with this.
You have a few options:
Upvotes: 2
Reputation: 11550
You can retrieve values from "non-JSF" controls on your page using the standard request parameter map that can be accessed with
FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()
in whatever action you call eg. MyBean.save()
Upvotes: 1