How to call managed bean in h:outputLink when opening new page - java

I have a h:outputLink which opens new JSF page and sends h:param.
<h:outputLink id="lnkHidden" action="#{HistoryLinkController.linkValue("test")}" value="HistoryLink.xhtml" style="display:none">
<f:param name="id" value="#{item.aSessionID}" />
</h:outputLink>
I want when I click it to send a value to a second managed bean. I tried to implement it with action="#{HistoryLinkController.linkValue("test")}" but I get error. Is there any attribute that I can use for this purpose?

Try using a <h:commandLink> in the following way and it should work fine
<h:commandLink id="hLink" value="History" action="#{HistoryLinkController.linkValue}" >
<f:param name="sessID" value="#{item.aSessionID}" />
</h:commandLink>
and the bean "HistoryLinkController" should have a method like
public String linkValue(){
// get "sessID" from FacesContext
...
return "/HistoryLink.xhtml";
}

Replace h:outputLink into h:commandLink.

I have also tried to navigate to some view along with passing a value to another bean already but I didn't get it. But what I got is---
U can remain in the same bean class if possible, and use navigation rules in faces-config.xml for navigating to another page.
And In ajax, action will be called earlier than its actionListener.
Hope it helps you finding a way...

Related

Call of action method from iterated h:commandButton fails

I am trying to implement a function that adds a book to a shopping cart.
The Cart bean has the fields to hold the request parameters. It is session scoped.
<h:form id="addBookToCartForm">
<ui:repeat var="book" value="#{search.bookList}">
<h:commandButton value="#{messages.addToCart}"
action="#{cart.addBookToCart}">
<f:param name="bookId" value="#{book.bookId}" />
</h:commandButton>
</ui:repeat>
</h:form>
The request from the view index.jsf, the action method calls the view cart.jsf.
The problem is: The action method isn't called, not even the bean itself is constructed.
I had a look at solutions for similar problems but couldn't find a solution that pointed in the right direction. At first I thought #{search.bookList} could be a problem but I don't need the bookList for the next view.
Activating debugging via <ui:debug> reveals this:
java.lang.UnsupportedOperationException: Not supported.
at javax.faces.component.UIViewAction.getActionListener(UIViewAction.java:249)
This message refers to the metadata at the top of index.jsf:
<f:metadata>
<f:viewParam name="genreTypeId" value="#{search.genreTypeId}" />
<f:viewAction action="#{search.searchByGenreTypeId}" />
</f:metadata>
The search bean is where the bookList comes from.
Update message using ajax update. It will show some validation message.
As it turns out the problem wasn't the iteration at all but the return value of the action methods my application is using.
In order to keep the view instance the methods have to return either null or void.

how to change css of the image link when clicked?

i have a commandLink that has a graphicImage inside and i want to change some property
of the link to show that it is clicked.I could find no built-in property for that purpose.
Maybe some javascript or css code is required.Since i am not so good at those,i'd be glad if someone could guide me a way.Thanks
Here is the code of the link.
<p:commandLink title="Forward" update="growl"
actionListener="#{roombaBean.forward}">
<p:graphicImage value="images/but_forward.png" />
</p:commandLink>
Use onclick event of the commandLink to execute javascript.
Something like
<p:commandLink onclick="changeCSSInJavascript()" ...>
....
</p:commandLink>
You could add a style attribute to primefaces graphicImage and give it a string value from a bean. After the link it's clicked you could update that string value with: opacity:0.4:
<p:commandLink title="Forward" update="growl"
actionListener="#{roombaBean.forward}">
<p:graphicImage value="images/but_forward.png" style="#{myBean.myStringStyleValue}" />
</p:commandLink>
For IE8 and earlier use filter:alpha(opacity=40);
Anyway I don't really understand why do you want something like this? Don't you navigate away from the page? Why is it really matter that the image was clicked? Please, if you could give some more info, we could see if there is a better solution...

JSF property transfer from backing bean A to backing bean B

I'm getting deeper into JSF 2.0 at the moment and lacking a bit of understanding about the "transport" of managed bean properties from one view to the other. I searched a bit but haven't found a really good example, so if anyone could point me to a tutorial or explain the things a little bit I'd really grateful.
So here is my scenario:
I'm developing a small playground calendar application. The first view select.xhtml contains the calendar selector, where the user can pick a specific date:
<html>
...
<h:form>
<!-- Calendar selector from primefaces -->
<p:calendar value="#{calendarSelect.date}" mode="inline" navigator="true" />
<p:commandButton value="Show entries for date" action="day" />
...
My corresponding backing bean looks like this:
#ManagedBean(name="calendarSelect")
#RequestScoped
public class CalendarSelectComponent {
private Date date = null;
... // Getters and setters
Now when I submit the form from select.xhtml I'm forwarded to day.xhtml
<html>
...
<h:form>
The current day ist:
<h:outputText value="#{calendarEdit.date}">
<f:convertDateTime pattern="dd.MM.yyyy" />
</h:outputText>
The backing bean now looks like this:
#ManagedBean(name="calendarEdit")
#ViewScoped
public class CalendarEditComponent implements Serializable {
private Date date = null;
private CalendarEntryBean currentEntry = null;
private List<CalendarEntryBean> allEntries = null;
....
I am now trying to solve the problem: How do I transfer the date parameter from the selector to the editor?
I've tried a number of options, one was this:
<p:commandButton value="Show entries for date" action="day" />
<f:setPropertyActionListener target="#{calendarEdit.date}" value="#{calendarSelect.date}" />
</p:commandButton>
A debugger shows, that indeed, the date property of the calendarEdit is populated with the value from calendarSelect, but since day.xhtml is a new view, a new CalendarEditComponent backing bean is being created and not the one I've populated with the date from the selector in the select view.
I've read that one solution would be to create a SessionScoped backing bean that does retain all it's values. But this is not the way I think it's supposed to work, because I don't really need the information in the session, I simply want it to "travel" from A to B. Another downside with the session based approach is that I can only use one selector and one editor per session - which I think isn't acceptible if you think of multi window browsing and so on.
I really don't think I'm the first one encountering such a scenario and I'm sure that JSF provides an elegant solution for this but I haven't been able to find that solution.
So once again, if anyone knows how to approach this - I'm listening! ;-)
The <f:setPropertyActionListener> is executed during invoke action phase of the form submit. So it expects that the value is still there at that point. But since your select bean is request scoped, it isn't there during form submit anymore. You want instead to pass a request parameter which get inlined in the output during render response. You can do this with <f:param>.
<p:commandButton value="Show entries for date" action="day" />
<f:param name="date" value="#{calendarSelect.dateAsString}" />
</p:commandButton>
It'll be available as request parameter (note that it only understands Strings, due to the nature of HTTP). You could let JSF set request parameters as managed properties, but since your edit bean is view scoped, this isn't possible with #ManagedProperty. You've got to gather it yourself by ExternalContext.
String dateAsString = externalContext.getRequestParameterMap().get("date");
True, that's clumsy. I would just have used the same bean and view for this and toggle visibility of select/edit forms by rendered attribute. The edit view is after all not directly openable/bookmarkable by a simple GET, isn't it? ;)

JSF - 2 a4j:actionParam in one commandlink bug

I have such structure in my jsp:
<h:commandLink action=#{docbean.save}>
<a4j:actionParam name="somename" value="bill_all" assignTo="#{billdoc.billType}"/>
<a4j:actionParam name="somename" value="bill_document" assignTo="#{docbean.doctype}"/>
</h:commandLink>
While debugging i saw, that billdoc.billtype and docbean.doctype have the same values: "bill_document".
Is it bug? If not, then how can i put value to my managed-bean?
UPDATED:
Found the answer:
I had two actionParams with one name. ActionParam is f:actionListener + f:param. So, if you have several actionparams with one name, you will have the problem i had. RichFaces and JSF doesn't warn you about it.
First, you need a space here <a4j:actionParamvalue - before value
Second, You may try this instead of <a4j:actionParam>:
<f:setPropertyActionListener value="bill_all" target="#{billdoc.billType}" />
You may need to put immediate="true" on your commandLink if there are validation errors in your form. You can view these errors by adding <rich:messages /> ontop of the page.
Try using an a4j:commandLink. Or - if you stick to h:commandLink - try embedding your a4j:actionParams in an a4j:support tag.

Passing data from request ManagedBeans in JSF

I'm somewhat confused about the lifecycle of ManagedBeans of type "request".
In this example i'm using one request bean "userBean" to fill this page and one request bean "userEditBean" to fill the following edit page.
<h:form>
<h:panelGrid border="1" columns="2">
<h:outputText value="Name" />
<h:outputText value="#{userBean.user.name}" />
...
</h:panelGrid>
<h:commandButton value="Edit" action="edit" actionListener="#{userEditBean.init}">
<f:attribute name="user" value="#{userBean.user}"/>
</h:commandButton>
</h:form>
When i press the Edit button a userEditBean is created but the attribute map resolves "user" to null.
Does this mean that the attribute EL is resolved after the userBean has already been destroyed? How can i pass values from incoming beans to outgoing beans?
You're setting the attribute value with an expression, not a static value. Whenever you request the value, the expression will be re-evaluated again. The userBean.user apparently isn't present in the subsequent request. You need to ensure that it is there (in other words, the constructor of the userBean should ensure that the user is been created and set.
There are however alternatives. One of the best is to use Tomahawk's <t:saveState> for that. Add it somewhere in the page:
<t:saveState value="#{userBean.user}" />
That said, I agree with Bozho that the whole approach is a bit strange, but that's another story. You may however get lot of useful ideas out either of the following articles: Communication in JSF and/or Using Datatables. Good luck.
request scope means the bean lives during one request. And you fill your edit page (1st request), and send the edited user (2nd request).
In addition to that, <f:attribute> sets tha attributes in the parent component, not in the request. So in your code the attributes will be found in the button.getAttributes() (if you have bound your button).
Furthermore, it is strange to have an actionListener method named init. Since you don't need the event, you can set the action to be the method which will do the editing operation, and make that method return the navigation-rule you want.

Categories

Resources