Showing HTTP addresses as links - jsf

I have a List of http addresses and I'd like to show them as links, so that people could click and go to the website.
I'm trying to do it like this, but it shows the http address, but not as a link:
Links Relacionados
<br />
<a4j:repeat value="#{pesquisaBean.selectedDocument.seeAlso}" var="uri" >
<h:link value="#{uri}" outcome="#{uri}" />
<br />
</a4j:repeat>
What's the problem?

The <h:link outcome> takes either a JSF navigation case outcome,
<h:link ... outcome="nextpage" />
or a JSF view ID,
<h:link ... outcome="/nextpage.xhtml" />
but definitely not an external URL, it would render as a <span> instead of an <a>.
<h:link ... outcome="http://stackoverflow.com" /> <!-- Fail. -->
This failure should also have been logged in server log. At least, Mojarra does that with a JSF1090 warning. Look once again at your server log:
WARNING: JSF1090: Navigation case not resolved for component j_idt7.
Use plain HTML <a> instead. You can specify the URL in its href attribute.
#{uri}

Related

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?

Bookmarkability via View Parameters feature

Is bookmarkability achievable though using the includeViewParams=true query parameter with JSF implicit navigation ? If yes, then how ?
First we need to understand what exactly "bookmarkability" is and what exactly includeViewParams does. This way the effect of the combination of both can be better understood.
Bookmarkability concerns the HTTP request URL in its exact form as you see in the browser's address bar. It's exactly the URL as the enduser would store in its bookmarks and/or would copypaste as a link elsewhere, such as a forum, a chatbox, some social medium, or just a new browser window/tab, etc. When a link is followed or an URL is copypasted into browser's address bar, then by default a HTTP GET request will be fired. If the result is exactly the same everytime (leaving authorization/authentication and the time-sensitive nature of the page —search results, last news, etc— outside consideration), then we can talk about a bookmarkable URL. The technical term is "an idempotent HTTP request".
If the enduser has however submitted a POST form on that URL beforehand, which hasn't performed a redirect, then the URL is not necessarily bookmarkable. The submitted form data is not reflected in the URL. Copypasting the URL into a new browser window/tab may not necessarily yield exactly the same result as after the form submit. Such an URL is then not bookmarkable. POST is not idempotent. That's why page-to-page navigation by commandlinks is bad.
Bookmarkability is usually achieved by a specific construct of the URL path and/or query parameters. If you look at Google, the search results are bookmarkable thanks to the q query string parameter.
http://google.com/search?q=bookmarkability
In JSF terms, those request parameters can be set (and converted and validated) via <f:viewParam>:
<f:metadata>
<f:viewParam name="q" value="#{bean.query}" />
<f:viewAction action="#{bean.search}" />
</f:metadata>
If you need to perform for example pagination, and you'd like to keep the URL bookmarkable, then you could add another request parameter:
http://google.com/search?q=bookmarkability&start=10
with
<f:metadata>
<f:viewParam name="q" value="#{bean.query}" />
<f:viewParam name="start" value="#{bean.start}" />
<f:viewAction action="#{bean.search}" />
</f:metadata>
The includeViewParams="true" basically includes all of those view parameters in the generated GET link. With help of this, the pagination links can then look like this without the need to repeat the q parameter:
<h:link value="1" outcome="search" includeViewParams="true">
<f:param name="start" value="#{null}" />
</h:link>
<h:link value="2" outcome="search" includeViewParams="true">
<f:param name="start" value="10" />
</h:link>
<h:link value="3" outcome="search" includeViewParams="true">
<f:param name="start" value="20" />
</h:link>
...
(of course generated by some <ui:repeat> or so)
When entering the page with q=bookmarkability, this will produce the following links
/search.xhtml?q=bookmarkability
/search.xhtml?start=10&q=bookmarkability
/search.xhtml?start=20&q=bookmarkability
Those are bookmarkable URLs and the includeViewParams made creating them more convenient.

Cancel button doesn't work in case of validation error

i have a form with some inputs that have validation (required=true)
and when i click on the cancel button in case of validation error, the cancel button doesn't navigate to previous page, instead it removes the validation error (i think it goes back one step that was before the validation error ?)
here's my code:
<h:form>
<h:inputText value="#{myBean.nickName}" id="nickname" required="true"
requiredMessage="nickname should be specified" />
<h:commandLink immediate="true" id="cancel_link" onclick="history.back(); return false" style="float: left;margin: 118px 189px 0 0;">
<h:graphicImage width="90" height="28" value="#{resource['images:blu_btnCancel.png']}" />
</h:commandLink>
</h:form>
please advise how to fix that.
The JavaScript history.back() function takes you to the previous synchronous request, not to the previous view as you seemed to expect.
Even though the history.back() is terrible this way (unreliable, hackable, etc), a quick fix would be to send an ajax request on form submit instead of a synchronous request.
<h:form>
...
<h:commandButton value="submit">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
</h:form>
Ajax requests doesn't account as browser history.
A more robust way is to just pass the identifier of the previous view along during navigation and then use <h:link> to link back to it. E.g.
<h:link value="Go to next view" outcome="nextview">
<f:param name="from" value="#{view.viewId}" />
<h:link>
And then in the nextview.xhtml
<f:metadata>
<f:viewParam name="from" />
</f:metadata>
...
<h:link ... outcome="#{from}" rendered="#{not empty from}">
<h:graphicImage ... />
</h:link>
If you're navigating by POST, you might consider using the flash scope to remember the initial view.
Unrelated to the concrete problem, the proper way to use <h:graphicImage> with JSF2 resources is to just use its name attribute instead of its value attribute with a #{resource} which is plain clumsy.
Replace
<h:graphicImage width="90" height="28" value="#{resource['images:blu_btnCancel.png']}" />
by
<h:graphicImage name="images/blu_btnCancel.png" width="90" height="28" />
Note that the library name images is here just replaced by the path name. The usage of the name "images" as library name is highly questionable. See also What is the JSF resource library for and how should it be used?

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

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?

JSF and links: the target property doesn't work?

I need to render a simple link in a page that open a pdf file in a new browser window.
I wrote the following tag:
<h:commandLink target="_blank"
action="showPDF"
title="Show attached PDF"
actionListener="#{bean.doShowPDF}"
value="Show PDF">
<f:attribute name="path" value="#{bean.pdfPath}" />
</h:commandLink>
The target attribute seems to be ignored. The destination page appear over the current.
I tried with h:outputLink:
<h:outputLink target="_blank"
title="Show attached PDF"
value="/visAttached.jspx">
<f:param name="path" value="#{bean.pdfPath}" />
Show PDF
</h:outputLink>
but with the same result. The generated html , in both cases, has not the target attribute.
Where's my fault?
There is a better strategy in JSF to show a file in a new browser window?
Try the ice: versions of them: ice:outputLink, or ice:commandLink. The component showcase shows a working example (layout panels/collapsible panels has a lot of links, check the source):
<ice:outputLink target="_blank" styleClass="navPnlClpsblLnks"
value="http://icefaces.org/main/home/index.jsp">
<ice:outputText id="icefacesOrgLink" value="ICEfaces.org"/>
</ice:outputLink>

Resources