How to create h:commandButton in JSF to open a new page - jsf

I want to create command button in JSF page. When I press it I want to open a new page and send a value using using the http. I tested this h:commnadButton but it's not working.
<h:commandButton id="lnkHidden" value=" Edit User " action="EditAccountProfile.jsf">
<f:param name="id" value="#{item.userid}" />
</h:commandButton>

h:commandButton is for submitting forms, usually executing actions in the server.
Use h:button for simple navigation:
<h:button id="lnkHidden" value=" Edit User " outcome="EditAccountProfile.jsf">
<f:param name="id" value="#{item.userid}" />
</h:button>
This will generate a normal HTML <input type="button" onclick="window.location.href=/correct/path/to/EditAccountProfile.jsf" />, no HTTP POST needed.
See also:
When should I use h:outputLink instead of h:commandLink?

Related

JSF link to external site without showing username and password in the URL

I was able to do a SSO(Single sign on) on click of external link from the code below. SSO works but username/password is seen on url.
https://example.org/index.php?userLogin=user1&userPassword=pass123
<h:outputLink styleClass="ui-menuitem-link ui-corner-all"
value="https://example.org/index.php">
<h:outputText value="Ext Tool" />
<h:outputText styleClass="ui-icon ui-icon-suitcase"
style="float:left" rendered="#{userBean.in}" />
<f:param name="userLogin" value="#{userBean.user.eUser}" />
<f:param name="userPassword" value="#{userBean.user.ePass}" />
</h:outputLink>
I also used tried as below...
<h:commandLink action="#{userBean.eSubmit()}">
<h:outputText value="Ext Tool" />
<f:param name="userLogin" value="#{userBean.user.eUser}" />
<f:param name="userPassword" value="#{userBean.user.ePass}" />
</h:commandLink>
In the bean.. My coding is like this
public void eSubmit() throws IOException{
FacesContext fc = FacesContext.getCurrentInstance();
fc.getExternalContext().redirect("https://example.org/index.php?userLogin=" + user.getUser() + "&userPassword=" + user.getPass());
}
Even for the above code with commandLink - UserName and password are visible in the URL. Please guide me to hide password in the URL.
Am new to JSF so please help me understand...
A redirect instructs the client to create a new GET request on the specified URL. That's why you see it being reflected in browser's address bar.
As to performing a POST to an external site, you don't necessarily need JSF here. You're not interested in updating JSF model nor invoking a JSF action. Just use a plain HTML POST form.
<form method="post" action="https://example.org/index.php">
<input type="hidden" name="userLogin" value="#{userBean.user.eUser}" />
<input type="hidden" name="userPassword" value="#{userBean.user.ePass}" />
<input type="submit" value="Ext Tool" />
</form>
If necessary, throw in some CSS to make the submit button look like a link, or some JS to let a link submit that form.

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?

Button as link, <h:button outcome /> not working (no navigation cases used)

I am trying to achieve the following, though with a button.
<h:outputLink value="/admin/category/read">
Cancel
<f:param name="cat" value="" />
<f:param name="subcat" value="" />
</h:outputLink>
I have tried using h:button, though the outcome property does not work since /admin/category/read is not a specified navigation-case.
How to use a button as link, without having to use a navigation-case or server side method?
No, there's no solution using JSF attributes, at least not if you really don't have a navigation case for the h:button.
If possible, I'd advise to use CSS styling as already mentioned in the comments.
But h:button just creates a plain HTML link with onclick="window.location.href=URL". So if you really want, you can build the URL yourself and just use a plain HTML input button like this:
<input type="button" value="Cancel"
onclick="window.location.href='/admin/category/read?cat=&subcat='; return false;" />
Related:
Difference between h:button and h:commandButton
When should I use h:outputLink instead of h:commandLink?

How to create a simple redirect with JSF?

How do I create a simple redirect with jsf?
I tried:
<h:form>
<h:commandButton action="www.google.de" value="go to google" />
</h:form>
But when I click the button, I just stay on the index page. Nothing happens!
What is wrong here?
Is JSF absolutely necessary here? You don't seem to need to submit anything to your side at all. Just use plain HTML.
<form action="http://www.google.de">
<input type="submit" value="Go to Google" />
</form>
Please note that the URL to the external site must include the scheme (the http:// part), otherwise it would just be submitted relative to the current request URI, such as http://example.com/context/www.google.de.
If you really need to submit to your side, e.g. to preprocess and/or log something, then you could use ExternalContext#redirect() in the action method.
<h:form>
<h:commandButton value="Go to Google" action="#{bean.submit}" />
</h:form>
with
public void submit() throws IOException {
// ...
FacesContext.getCurrentInstance().getExternalContext().redirect("http://www.google.de");
}
You can use:
<h:commandButton value="Go to Google" type="button" onclick="window.location.href = 'http://www.google.de';" />
No need for a form.

JSF Authentication: cannot intercept error messages

I have developed a simple login form to be used in my JSF + PrimeFaces page:
<form action="j_security_check" method="post">
<p:dialog modal="true" header="Login" widgetVar="loginDlg">
<h:panelGrid columns="3" cellpadding="5">
<h:outputLabel for="j_username">Username:</h:outputLabel>
<h:inputText id="j_username" required="true" />
<h:message for="j_username" />
<h:outputLabel for="j_password">Password:</h:outputLabel>
<h:inputSecret id="j_password" required="true" />
<h:message for="j_password" />
<br />
<h:commandButton value="Login" />
</h:panelGrid>
</p:dialog>
</form>
Tried with an empty password, but the missing password (that is required) is not caught by h:message component. I have also switched to a p:commandButton thinking that the problem could have been in the Ajax behaviour of the button, but the page is not rendered because PrimeFaces complains about the CommandButton not being inside a form element. The exception thrown by the container is:
com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Access denied on empty password for user pippo
To summarize, I have 2 questions:
Why the missing password doesn't produce a message before the form is submitted?
How can I catch a LoginException and display the error message inside the dialog?
The j_security_check request is handled by the web container, not by JSF. That explains that the required="true" won't work. It works only when you use JSF <h:form> and programmatic login by HttpServletRequest#login() in the action method associated with the command button.
Best what you can do is to confiure a <form-error-page> in web.xml pointing to the very same URL as the <form-login-page>. You could then check if the request has been forwarded by j_security_check itself, which would mean that a login error has occurred.
<h:panelGroup rendered="#{requestScope['javax.servlet.forward.servlet_path'] == '/j_security_check'}">
<h:outputText value="Unknown login, please try again" styleClass="error" />
</h:panelGroup>
Use this instead of the <h:message>.
As to why <p:commandButton> complains that there's no form is simply because you didn't use <h:form>.
Unrelated to the concrete problem, that <form> (or <h:form> whenever you would decide to switch to programmatic login) can better be placed in the body of <p:dialog>, not outside. The <p:dialog> can by JS be relocated to end of body which would cause it not to be in a form anymore.

Resources