Pass inputText as f:param on button click - jsf

So, I have this jsf code
<h:inputText id="serviceId"/>
<h:commandButton value="Enter" action="agreementDetail.xhtml"/>
I need to send the customer's input in the serviceId field as a f:param to the next page (agreementDetail.xhtml). So, the customer inputs the value, clicks on the "Enter" button, and the next page receives the inputted value as a parameter.

Just use a regular GET form with a regular HTML button instead. JSF as being a POST form oriented framework offers no advantages for you here, so there's not really a point of using a JSF component here.
<form action="agreementDetail.xhtml">
<input name="serviceId" />
<input type="submit" value="Enter" />
</form>
For the case you didn't already know that, you can in the target view agreementDetail.xhtml use <f:viewParam> to process the GET request parameter and set it as a bean property like as if it's a <h:inputText>. See also What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?

Related

Passing "get" parameters doesn't work, parameter not visible in the link

I'm a beginner to JSF and I want to code a little searchbar on my future website.
I made two pages : index.xhtml and search.xhtml, and I try to pass get parameters from index.xhtml to search.xhtml, so I made this little formular :
<!-- index.xhtml -->
<h:form id="Form_search">
<h:inputText class="search_bar_text" binding="#{se}"></h:inputText>
<h:button class="search_bar_button" outcome="search">
<f:param name="search" value="#{se.value}" />
</h:button>
</h:form>
To summarize, I want to send the content of an inputText to search.xhtml
But there's a problem : when I click on the submit button, no parameters are passed, so instead of having /search.xhtml?search=foobar I only have /search.xhtml.
I also tried this, but this doesn't work either :
<!-- index.xhtml -->
<h:form id="Form_search">
<h:inputText class="search_bar_text" binding="#{se}"></h:inputText>
<h:button class="search_bar_button" outcome="search.xhtml?search=#{se.value}">
</h:button>
</h:form>
Can someone explain to me the reason of this problem and how I can fix it?
The <f:param value> and <h:button outcome> are evaluated during rendering the HTML output, not during "submitting" of the form as you seem to expect. Do note that there's actually no means of a form submit here. If you're capable of reading HTML code, you should see it in the JSF-generated HTML output which you can see via rightclick, View Source in webbrowser.
Fix it to be a true GET form. You don't need a <h:form>, <h:inputText>, nor <h:button> here at all. You don't want a POST form. You don't seem to want to bind the input to a bean property. You don't want a plain navigation button.
<form id="form_search" action="search.xhtml">
<input name="search" class="search_bar_text" />
<input type="submit" class="search_bar_button" />
</form>
Yes, you can just use plain HTML in JSF.
If you really, really need to use JSF components for this purpose for some reason, then you could also use this POST-redirect-GET-with-view-params trick.
First add this to both index.xhtml and search.xhtml:
<f:metadata>
<f:viewParam name="search" value="#{bean.search}" />
</f:metadata>
Then use this form:
<h:form id="form_search">
<h:inputText value="#{bean.search}" styleClass="search_bar_text" />
<h:commandButton styleClass="search_bar_button" action="search?faces-redirect=true&includeViewParams=true" />
</h:form>
This would perhaps make sense if you intend to use JSF validation on it. But even then, this doesn't prevent endusers from manually opening the URL with invalid params. You'd then better add validation to <f:viewParam> itself on search.xhtml.
See also:
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for? (scroll to bottom of answer)
How do I process GET query string URL parameters in backing bean on page load?

jsf inputtext to bean

In my JSF Application, I have a page with several inputtext components. When the page is displayed, those inputtext components are populated with data from the database. When I hit the submit button, I want to pass those values as parameters to the next facelet.
What is happening is when I hit Submit, the old values are being passed, and not the updated values that the user has typed in. Here is what one of the inputtext components looks like:
<div align="center">
<h:outputLabel value="Product Quantity " />
<h:inputText id="quantity" value="#{product.quantity}" />
</div>
Then, in the submit button I am trying to get the values that the user types in:
<h:button value="Save Edits" outcome="welcome">
<f:param name="quantity" value="#{product.quantity}" />
</h:button>
Let's say that 100 was the original quantity that the field was populated with. When the user changes it to 110, and hits submit, the welcome facelet still thinks 100 is the value. Any ideas?
Is there any particular reason you've decided to use a <h:button/> instead of an <h:commandButton/>? Because that's the reason why your parameters are not making it to the next page
<h:commandButton/> processes it's enclosing <h:form/>, submitting it's content to the server in a POST request (and the JSF processing lifecycle kicks in e.t.c.) while the <h:button/> will generate a GET request. <h:button/> is generally used for navigation. Stick to <h:commandButton/> if you want to do more than navigate

Difference between h:button and h:commandButton

In JSF 2, what is the difference between h:button and h:commandButton ?
<h:button>
The <h:button> generates a HTML <input type="button">. The generated element uses JavaScript to navigate to the page given by the attribute outcome, using a HTTP GET request.
E.g.
<h:button value="GET button" outcome="otherpage" />
will generate
<input type="button" onclick="window.location.href='/contextpath/otherpage.xhtml'; return false;" value="GET button" />
Even though this ends up in a (bookmarkable) URL change in the browser address bar, this is not SEO-friendly. Searchbots won't follow the URL in the onclick. You'd better use a <h:outputLink> or <h:link> if SEO is important on the given URL. You could if necessary throw in some CSS on the generated HTML <a> element to make it to look like a button.
Do note that while you can put an EL expression referring a method in outcome attribute as below,
<h:button value="GET button" outcome="#{bean.getOutcome()}" />
it will not be invoked when you click the button. Instead, it is already invoked when the page containing the button is rendered for the sole purpose to obtain the navigation outcome to be embedded in the generated onclick code. If you ever attempted to use the action method syntax as in outcome="#{bean.action}", you would already be hinted by this mistake/misconception by facing a javax.el.ELException: Could not find property actionMethod in class com.example.Bean.
If you intend to invoke a method as result of a POST request, use <h:commandButton> instead, see below. Or if you intend to invoke a method as result of a GET request, head to Invoke JSF managed bean action on page load or if you also have GET request parameters via <f:param>, How do I process GET query string URL parameters in backing bean on page load?
<h:commandButton>
The <h:commandButton> generates a HTML <input type="submit"> button which submits by default the parent <h:form> using HTTP POST method and invokes the actions attached to action, actionListener and/or <f:ajax listener>, if any. The <h:form> is required.
E.g.
<h:form id="form">
<h:commandButton id="button" value="POST button" action="otherpage" />
</h:form>
will generate
<form id="form" name="form" method="post" action="/contextpath/currentpage.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="form" value="form" />
<input type="submit" name="form:button" value="POST button" />
<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="...." autocomplete="off" />
</form>
Note that it thus submits to the current page (the form action URL will show up in the browser address bar). It will afterwards forward to the target page, without any change in the URL in the browser address bar. You could add ?faces-redirect=true parameter to the outcome value to trigger a redirect after POST (as per the Post-Redirect-Get pattern) so that the target URL becomes bookmarkable.
The <h:commandButton> is usually exclusively used to submit a POST form, not to perform page-to-page navigation. Normally, the action points to some business action, such as saving the form data in DB, which returns a String outcome.
<h:commandButton ... action="#{bean.save}" />
with
public String save() {
// ...
return "otherpage";
}
Returning null or void will bring you back to the same view. Returning an empty string also, but it would recreate any view scoped bean. These days, with modern JSF2 and <f:ajax>, more than often actions just return to the same view (thus, null or void) wherein the results are conditionally rendered by ajax.
public void save() {
// ...
}
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
When should I use h:outputLink instead of h:commandLink?
Differences between action and actionListener
h:button - clicking on a h:button issues a bookmarkable GET request.
h:commandbutton - Instead of a get request, h:commandbutton issues a POST request which sends the form data back to the server.
h:commandButton must be enclosed in a h:form and has the two ways of navigation i.e. static by setting the action attribute and dynamic by setting the actionListener attribute hence it is more advanced as follows:
<h:form>
<h:commandButton action="page.xhtml" value="cmdButton"/>
</h:form>
this code generates the follwing html:
<form id="j_idt7" name="j_idt7" method="post" action="/jsf/faces/index.xhtml" enctype="application/x-www-form-urlencoded">
whereas the h:button is simpler and just used for static or rule based navigation as follows
<h:button outcome="page.xhtml" value="button"/>
the generated html is
<title>Facelet Title</title></head><body><input type="button" onclick="window.location.href='/jsf/faces/page.xhtml'; return false;" value="button" />
This is taken from the book - The Complete Reference by Ed Burns & Chris Schalk
h:commandButton vs h:button
What’s the difference between h:commandButton|h:commandLink and
h:button|h:link ?
The latter two components were introduced in 2.0 to enable bookmarkable
JSF pages, when used in concert with the View Parameters feature.
There are 3 main differences between h:button|h:link and
h:commandButton|h:commandLink.
First, h:button|h:link causes the browser to issue an HTTP GET
request, while h:commandButton|h:commandLink does a form POST. This
means that any components in the page that have values entered by the
user, such as text fields, checkboxes, etc., will not automatically
be submitted to the server when using h:button|h:link. To cause
values to be submitted with h:button|h:link, extra action has to be
taken, using the “View Parameters” feature.
The second main difference between the two kinds of components is that
h:button|h:link has an outcome attribute to describe where to go next
while h:commandButton|h:commandLink uses an action attribute for this
purpose. This is because the former does not result in an ActionEvent
in the event system, while the latter does.
Finally, and most important to the complete understanding of this
feature, the h:button|h:link components cause the navigation system to
be asked to derive the outcome during the rendering of the page, and
the answer to this question is encoded in the markup of the page. In
contrast, the h:commandButton|h:commandLink components cause the
navigation system to be asked to derive the outcome on the POSTBACK
from the page. This is a difference in timing. Rendering always
happens before POSTBACK.
Here is what the JSF javadocs have to say about the commandButton action attribute:
MethodExpression representing the application action to invoke when
this component is activated by the user. The expression must evaluate
to a public method that takes no parameters, and returns an Object
(the toString() of which is called to derive the logical outcome)
which is passed to the NavigationHandler for this application.
It would be illuminating to me if anyone can explain what that has to do with any of the answers on this page. It seems pretty clear that action refers to some page's filename and not a method.

Conditional rendering in JSF [duplicate]

This question already has an answer here:
Ajax update/render does not work on a component which has rendered attribute
(1 answer)
Closed 7 years ago.
Hello I have this code to conditionally render components in my page:
<h:commandButton action="#{Bean.method()}" value="Submit">
<f:ajax execute="something" render="one two" />
</h:commandButton>
<p><h:outputFormat rendered="#{Bean.answer=='one'}" id="one" value="#{messages.one}"/></p>
<p><h:outputFormat rendered="#{Bean.answer=='two'}" id="two" value="#{messages.two}"/></p>
It gets the answer and renders the component but in order to see it on my page, I need to refresh the page. How can I fix this problem? Any suggestions?
The JSF component's rendered attribute is a server-side setting which controls whether JSF should generate the desired HTML or not.
The <f:ajax> tag's render attribute should point to a (relative) client ID of the JSF-generated HTML element which JavaScript can grab by document.getElementById() from HTML DOM tree in order to replace its contents on complete of the ajax request.
However, since you're specifying the client ID of a HTML element which is never rendered by JSF (due to rendered being false), JavaScript can't find it in the HTML DOM tree.
You need to wrap it in a container component which is always rendered and thus always available in the HTML DOM tree.
<h:commandButton action="#{Bean.method()}" value="Submit">
<f:ajax execute="something" render="messages" />
</h:commandButton>
<p>
<h:panelGroup id="messages">
<h:outputFormat rendered="#{Bean.answer=='one'}" value="#{messages.one}"/>
<h:outputFormat rendered="#{Bean.answer=='two'}" value="#{messages.two}"/>
</h:panelGroup>
</p>
Unrelated to the concrete problem, you've there a possible design mistake. Why would you not just create a #{Bean.message} property which you set with the desired message in the action method instead, so that you can just use:
<h:commandButton action="#{Bean.method()}" value="Submit">
<f:ajax execute="something" render="message" />
</h:commandButton>
<p>
<h:outputFormat id="message" value="#{Bean.message}" />
</p>
I know it's not the central point of the question, but as I had this problem many times in the past, I just post it here to help others who are in need.
For those who uses PrimeFaces there's a component in PrimeFaces Extension called Switch.
Sometimes you need to display different outputs or components depending on a value. Usually you can achieve this by using the ui:fragment tag. With the pe:switch util tag you won't have to declare ui:fragment tags, with different checks like ui:fragment rendered="#{!empty someController.value}", anymore.
style="visibility: #{questionchoose.show==false ? 'hidden' : 'visible'}"

JSF 2.0 navigating on commandLink and commandButton doesn't work

I'm using JSF 2.0 and I have a problem with navigation after both commandLink and commandButton. I use following code:
<h:commandLink action="login?faces-redirect=true"
value="#{showElementBean.showElement()}"> Login </h:commandLink>
<h:commandButton action="login?faces-redirect=true" value="Move to login.xhtml" />
These tags are inside a form, login is just an example. Result of clicking on rendered controls is always POST with refresh of a current page. What do I wrong?
Edit:
According to comments of BalusC I' adding real code fragment:
<h:commandLink actionListener="#{showElementBean.showElement(element)}"
value="View" > </h:commandLink>
I have a page with a list of elements and I want to add links that leads to element view page. Thus I need to pass this element to a show page. I'm JSF primer, e.g. in Rails I'd use GET and URL params, but I don't know how to do it 'in JSF-way'.
There are a lot of possible causes for this behaviour. They are all cited in the following answer, along with solutions: commandButton/commandLink/ajax action/listener method not invoked or input value not updated.
However, in your particular case, you seem rather to be interested in plain GET requests instead of POST requests, as all you want is simple page-to-page navigation. In that case, you need a <h:link> or <h:button> instead:
<h:link outcome="login" value="Login" />
<h:button outcome="login" value="Move to login.xhtml" />
(I have no idea what you're trying to do with both #{showElementBean.showElement()} and Login as command link value, so I omitted the former)
See also:
When should I use h:outputLink instead of h:commandLink?
Refer this info: JSF HTML Tags
h:commandButton
The commandButton tag renders an HTML submit button that can be
associated with a backing bean or ActionListener class for event
handling purposes. The display value of the button can also be
obtained from a message bundle to support internationalization (I18N).
Example
<h:commandButton id="button1" value="#{bundle.checkoutLabel}" action="#{shoppingCartBean.checkout}" />
HTML Output
<input id="form:button1" name="form:button1" type="submit" value="Check Out" onclick="someEvent();" />
h:commandLink
The commandLink tag renders an HTML anchor tag that behaves like a
form submit button and that can be associated with a backing bean or
ActionListener class for event handling purposes. The display value of
the link can also be obtained from a message bundle to support
internationalization (I18N).
Example
<h:commandLink id="link1" value="#{bundle.checkoutLabel}" action="#{shoppingCartBean.checkout}" />
HTML Output
Check Out
Noticed that backing bean method is not called if the form is for file upload:
<h:form name="searchForm" enctype="multipart/form-data" method="post" action="/search">
I also faced with that issue and adding the
<h:form><h:commandLink></h:commandLink> </h:form>
solved my problem.

Resources