3

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! ;-)

Christian Seifert
  • 2,562
  • 5
  • 23
  • 42

1 Answers1

2

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? ;)

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Thanks for the reply, I was afraid there was no "perfect" way. But regarding your comment "he edit view is after all not directly openable/bookmarkable by a simple GET, isn't it?" - what, if I need something like this? If I'd need some URL like "http://blaba/edit.jsf?userId=42" the only way would be to programatically access the parameter? – Christian Seifert Feb 18 '11 at 12:35
  • 1
    Then do so. You can use a request scoped bean with `@ManagedProperty` or a view scoped one which gathers it from externalcontext during construction or uses `f:viewParam`. – BalusC Feb 18 '11 at 12:45