JSF 2.0 navigating on commandLink and commandButton doesn't work - jsf

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.

Related

How to open an arbitrary URL in new window using a PrimeFaces button

I have the below output link which does its job:
<h:outputLink value="#{verDocumentoController.url()}" target="_blank">
show document
</h:outputLink>
It opens an URL obtained as a bean property in a new window.
However, I'd like to turn the link into a button in PrimeFaces look'n'feel. I tried as below:
<p:commandButton value="show document" action="#{verDocumentoController.url()}"
onclick="form.target='_blank'" ajax="false" />
But it only reopens the current page in a new window and not the URL specified as bean property. How can I achieve this anyway?
The <p:commandButton> basically submits a POST request to the URL as specified by its parent <h:form>, which defaults indeed to the current request URL (you know, "postback"). The action attribute basically invokes a bean method and uses the returned value as navigation case outcome. An URL does not necessarily represent a sensible navigation case outcome.
Just use window.open() instead on a simple <p:button>.
<p:button value="show document"
onclick="window.open('#{verDocumentoController.url()}');return false;" />
You can also do this on a <p:commandButton>, but that's unnecessarily overcomplicated.

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?

commandButton inactive after ajax rendering

I have a problem with these two commandButton : Join and Leave.
I want to hide Join if I click on leave and vice-versa.
When I put ajax on false, there is no problem (but all the page is refresh and I don't find this optimal).
But when ajax attribut is on true with specific updating (cf comment in the code), the rendering is good but the new button whitch appear become inactive. If I click on it, nothing happens (well it's seems the actionListener trigger but the view is not refreshed, I have to manual refresh to see the difference)
Thanks for reading.
<h:form id="formWaitingList" rendered="#{connexion.connected}" >
<p:commandButton id="Join"
actionListener = "#{connexion.joinWaitingList()}"
rendered="#{!connexion.waiting}"
ajax="false"
<!-- ajax="true"
update="Join,Leave"-->
value="Join"/>
<p:commandButton id="Leave"
value="Leave"
ajax="false"
<!-- ajax="true"
udpate="Join,Leave"-->
rendered="#{connexion.waiting}"
actionListener ="#{connexion.leaveWaitingList()}" />
</h:form>
It seems that you're not entirely familiar with HTML/JavaScript. You know, JSF is basically a HTML/JavaScript(/CSS) code generator. Ajax updating works basically like this in JavaScript:
After sending the ajax request to JSF via XMLHttpRequest, retrieve a XML response which contains all elements which needs to be updated along with their client IDs.
For every to-be-updated element, use document.getElementById(clientId) to find it in the current HTML DOM tree.
Replace that element by new element as specified in ajax XML response.
However, if a JSF component has not generated its HTML representation because of rendered="false", then there's nothing in the HTML DOM tree which can be found and replaced. That totally explains the symptoms you're "seeing".
You basically need to wrap conditionally rendered JSF components in a component whose HTML representation is always rendered and then reference it instead in the ajax update.
For example,
<h:form>
...
<h:panelGroup id="buttons">
<p:commandButton ... update="buttons" rendered="#{condition}" />
<p:commandButton ... update="buttons" rendered="#{not condition}" />
</h:panelGroup>
</h:form>
See also:
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?

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'}"

Resources