8

I'm currently trying out sending the id of a record from one page to another page.

So in the page 1, i have something like this :

<p:column>
    <h:link value="#{rpb.map['transNum']}" outcome="TInput.xhtml">
        <f:param name="id" value="#{rpb.map['id']}" />
    </h:link>
</p:column>

and in the target page (TInput.xhtml), i have something like this to capture the id :

....
    xmlns:fn="http://java.sun.com/jsp/jstl/functions">

<f:metadata>
    <f:viewParam name="id" value="#{tInputBean.id}"></f:viewParam>
</f:metadata>

<h:head>
....

Now, clicking on the link, goes to page 2, and page 2 is handled by one view-scoped jsf bean. And from my debugging, this is the order of happenning :

  1. the @PostConstruct method is executed
  2. the model is updated with the id captured from the viewParam (after appy request + validation)

What i would like to achieve is that : after the model is updated, i would like to execute a query for that record id, get it's bean and it's list of details from Business Service.

I wonder where should i could put my query code :

  1. inside @PostConstruct method is not possible, since the id captured from the viewParam is set to the model after the @PostConstruct method finishes
  2. use a phase listener on after the model update ?
  3. use a system event ? although i cant seem to find the appropriate one for this case

Please enlighten me :)

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
Albert Gan
  • 16,262
  • 44
  • 125
  • 177

2 Answers2

8

Add a <f:event type="preRenderView"> to the <f:metadata>.

<f:metadata>
    <f:viewParam name="id" value="#{tInputBean.id}" />
    <f:event type="preRenderView" listener="#{tInputBean.init}" />
</f:metadata>

with a

public void init(ComponentSystemEvent event) throws AbortProcessingException {
    // ...
}

(by the way, in contrary to the documentation, the argument and the exception are optional, at least in all Mojarra 2.x versions I've had used)

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • @BalusC: Thank you so much! I just know today that we can put the event tag inside the f:metadata. So, basically, regardless of whether im using GET or POST, i can always make use of the f:event inside f:metadata to call methods according to the event type, am i correct ? – Albert Gan Apr 13 '11 at 15:26
  • You're welcome. Yes, it's regardless of the method. However, such a page with `f:metadata` should preferably be used for GET requests only. – BalusC Apr 13 '11 at 15:28
  • @BalusC: Hello again ! I wonder, if f:metadata is preferably be used for GET method only, what is the recommended approach to be able to execute a method on a pre-render event with a POST method ? – Albert Gan Apr 14 '11 at 00:46
  • The command link/button action method. Without `f:metadata`. Thus, "the usual way" :) – BalusC Apr 14 '11 at 01:34
  • @BalusC: aha! the englightening moment ! Thank you BalusC .. :-) – Albert Gan Apr 14 '11 at 01:49
  • @BalusC: Ah .. found a little trouble with this. Every ajax call like when i'm using auto completion, doing partial submit and then refreshing using ajax, the listener will also run. Is there a trick to avoid the listener running while doing ajax stuffs ? Thank you ! – Albert Gan Apr 14 '11 at 10:50
  • 1
    Check if `FacesContext#isPostback()` returns true, then it's an (ajax) postback request. – BalusC Apr 14 '11 at 12:41
  • @BalusC: Ah, the documentation imcompleteness! Many times I have been confused due to the documentation not being correct. It does make it hard for new Java starters. – ChuongPham Apr 16 '11 at 13:26
4

I used the BalusC solution. Thanks;)

I just want to add if you use facelet, you need to put :

 <f:metadata>

in each page using the template:

mytemplate.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">

<ui:insert name="meta"/>

mypage.xhtml using mytemplate.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">

<ui:composition template="mytemplate">

 <ui:define name="meta">
    <f:metadata>
       <f:viewParam name="id" value="#{tInputBean.id}" />
       <f:event type="preRenderView" listener="#{tInputBean.init}" />
     </f:metadata>
  </ui:define>
...

Solution found at : https://forums.oracle.com/forums/thread.jspa?threadID=2145709

YoelBen
  • 103
  • 8