How to call Java method from h:outputlink and pass value - jsf

I have this output `h:outputLink' to open a new page and pass a value:
<h:outputLink id="link" value="newpage.jsf" style="text-decoration:none; color:white;">
<f:param name="id" value="#{item.value}" />
</h:outputLink>
I need to add Java method which is called after I click the link. I saw that h:outputLink don't have action listener which I can use for calling Java method. I tested to use `h:commandButton' but the table logic is changed and it's not working properly. How I can solve this problem?

Try using 'h:commandLink' instead of `h:outputLink':
<h:commandLink id="lnkHidden" style="text-decoration:none; color:white;" actionListener="#{bean.pageRedirect}">
<f:setPropertyActionListener target="#{bean.sessionValue}" value="#{item.value}" />
</h:commandLink>

Related

Implementing a return navigation in JSF

I am looking for a JSF coding practice that will allow one page to link to another that, when it completes, will return to the original page. So I have a page viewDoc.xhtml that has this:
<f:metadata>
<f:viewParam name="id" value="#{viewDoc.id}" />
</f:metadata>
( bunch of stuff to show the document indicated by "id" )
<p:button value="Edit Name/Title"
outcome="editnametitle">
<f:param name="id" value="#{param.id}" />
</p:button>
Then I have a page editnametitle.xhtml that has this:
<h:form>
(input fields and stuff)
<p:commandButton value="Save Changes"
action="#{editNameTitle.doSave()}"
/>
<p:commandButton value="Cancel"
action="#{editNameTitle.doCancel()}"
immediate="true"
/>
</h:form>
So how do I implement the backing bean methods doSave() and doCancel() such that when they finish they navigate back to viewDoc.xhtml with the id parameter of the document included?
I haven't found any guidance for a solution and I haven't been happy with any approach I have thought of so far. I have thought of something like adding to the p:button the return path like:
<p:button value="Edit Name/Title"
outcome="editnametitle">
<f:param name="id" value="#{param.id}" />
<f:param name="returnoutcome" value="viewDoc" />
</p:button>
Is this the right approach? Or is there some JSF facility that does this that I missed?
Yes, that's basically it if those requests are idempotent.
One possible improvement is that you can dynamically obtain the current view ID as below:
<f:param name="returnoutcome" value="#{view.viewId}" />
This allows abstracting away it in a reusable custom tag.
Personally I'd use parameter name "from" too as that's more short.

f:param not working in p:fileDownload

I'm using the following code to cause custom validators to skip validation on certain button presses :
<p:commandButton ... value="Don't Validate">
<f:param name="triggerValidation" value="false"/>
</p:commandButton>
Which is working quite nicely. However I can't seem to get this to work when using the <p:fileDownload> component :
<p:commandButton ... value="Don't Validate">
<p:fileDownload value="#{someWebBean.download()}">
<f:param name="triggerValidation" value="false"/>
</p:fileDownload>
</p:commandButton>
The triggerValidation parameter is null by the time it gets to the validator (regardless of whether the <f:param> element is a child of the <p:commandButton> or <p:fileDownload> component).
The code inside the base class of the custom validators get this parameter:
Object o = ((HttpServletRequest) context.getExternalContext().getRequest()).getParameter("triggerValidation");
Any insight into why this is happening would be greatly appreciated!
Even if the p:commandButton contains the p:fileDownload, the parameter still has to be on the p:commandButton, not the p:fileDownload
<p:commandButton ... value="Don't Validate">
<f:param name="triggerValidation" value="false"/>
<p:fileDownload value="#{someWebBean.download()}" />
</p:commandButton>
See also How to pass a parameter along with h:commandButton.

How to implement the image redirect with parameters?

This is the way how a commandButton realizes the redirect with parameters.
<h:commandButton value="Check" action="#{GetInfoBean.getInfo}">
<f:param name="ID" value="4"></f:param>
</h:commandButton>
When this commandButton get clicked, it will pass the parameter named ID with value 4. The managed bean GetInfoBean's method getInfo() will return the new url.
But now, my question is how can I implement this redirect process using image or graphicImage since it doesn't have the action attribute?
Wrap the image using a <h:commandLink>:
<h:commandLink value="Check" action="#{GetInfoBean.getInfo}">
<f:param name="ID" value="4"></f:param>
<h:graphicImage value="/your/image.png" />
</h:commandLink>

<h:commandButton> is not refreshing page after actioned

hi we are using along with a4j tag.
here we are retrieving data from database after a click of button. even though the data is available in server, it will not display over view. After manual refresh of web page will lead to data diplay.
here is code snippet
.... some code here
<rich:tab id="menu5" label="Recall">
<ui:include src="/pages/mctrans/reCallMcifTrans.xhtml" />
</rich:tab>
reCallMcifTrans.xhtml contains below code
<h:commandButton type="button" id="reCallbutton1" value=" Search "
styleClass="commandExButton">
<a4j:support event="onclick" id="ajsf12"
oncomplete="javascript:alert('Search Completed');javascript:document.body.style.cursor='default';"
action="#{mcifRecallTransBean.reCallSearch}" reRender="reCallgrid1" />
</h:commandButton>
It looks like you're working with RichFaces 3.3. So, you don't need a <h:commandButton with <a4j:support> because you can use <a4j:commandButton> that already does this. You can refactor your code to this:
<a4j:commandButton type="button" id="reCallbutton1" value="Search"
styleClass="commandExButton"
action="#{mcifRecallTransBean.reCallSearch}"
reRender="reCallgrid1"
oncomplete="javascript:alert('Search Completed');javascript:document.body.style.cursor='default';" />
Make sure your reCallgrid1 component is available in the same <h:form> of the <a4j:commandButton>.
Since you also want to add a Wait while searching the data behavior when the button is clicked, you can use <a4j:status> along with the <a4j:commandButton> as shown in the <a4j:status> demo. Here's a basic example:
<a4j:commandButton type="button" id="reCallbutton1" value="Search"
styleClass="commandExButton"
action="#{mcifRecallTransBean.reCallSearch}"
reRender="reCallgrid1" />
<!-- Note that there's no oncomplete in this case -->
<a4j:status for="reCallbutton1">
<f:facet name="start">
<h:graphicImage value="/res/images/wait.gif"/>
</f:facet>
</a4j:status>
At last but not least, you should switch your managed bean to request scope and use RichFaces powerful <a4j:keepAlive> in order to simulate JSF 2 #ViewScoped. You can even use it in form of annotation on your managed bean (no additional configuration):
#KeepAlive
public class McifRecallTransBean {
//managed bean code here...
}
When you are using request parameters inside the bean, you need to pass them again with your action :
<h:commandButton type="button" id="reCallbutton1" value="Search" styleClass="commandExButton">
<a4j:support event="onclick" id="ajsf12" oncomplete="javascript:alert('Search Completed');javascript:document.body.style.cursor='default';" action="#{mcifRecallTransBean.reCallSearch}" reRender="reCallgrid1" />
<f:param name="param1" value="#{param['param1']}" />
<f:param name="param2" value="#{param['param2']}" />
</h:commandButton>

why composite compoment does not invoke in the <h:datatable/>

I have a compoment which has a method-signature attribute. It can be activated, but if I put it in a <h:datatable> <h:column/> and trigger this component, it does not work.
When I just refresh this page again or when I put it in another place it can invoked successfully. I would be grateful if somebody can tell me why!
this is my code
<h:column>
<f:facet name="header">op:</f:facet>
<h:commandLink value="alter" action="#{userSession.alterAction}"
rendered="#{userSession.user.power.powerID == 1}">
<f:param name="beanId" value="#{book.bookID}" />
<f:param name="class" value="#{BookBean}" />
</h:commandLink>
<h:commandLink action="#{userSession.detailAction}" value="detail"
rendered="#{userSession.user != null}">
<f:param name="beanId" value="#{book.bookID}" />
<f:param name="class" value="#{BookBean}" />
</h:commandLink>
<h:commandLink action="#{bookAction.bookDelAction}"
onclick="return confirm('are you sure?')" value="delete"
rendered="#{userSession.user.power.powerID == 1}">
<f:param name="beanId" value="#{book.bookID}" />
</h:commandLink>
</h:column>
this manageredBean #{bookAction} is requestScope when i click one of this operation,just like delete ,it doesnot work at all. but if i put the 'delete' commandlink out of <h:datatabel/> .it can invoke backing method successfully. it is so upset!
who can tell me whether <h:datatable/> can Shielding the .i found if i put these code in a <h:form/> .it can invoke too! cound you can tell me the reason!
You need to preserve exactly the same data model (i.e. the one which you have referenced by the value attribute of the <h:dataTable>) in during the request of the form submit as it was during the request of displaying the initial form. The symptoms indicate that you're using a request scoped bean and that the loading of the data model is based on some request parameter which is missing during the form submit and/or the loading is not being done during bean's (post)construction.
Putting the bean in the view scope and/or rearranging the data loading logic should fix it.

Resources