6

here is my situation in short.

I have page with datatable and few buttons backed by bean. Bean should be initialized with some default properties. That properties can be changed depending on action. I started with RequestScoped bean and @PostConstruct annotated method. but it seems that datatable works well only with View(Session)scoped. Now my setup look like this:

@ManagedBean
@ViewScoped
public class ProductsTableBean implements Serializable {

    private LazyDataModel<Products> productsData;
    @Inject
    private ProductsFacade model;


    public void onPageLoad() {
       // here some defaults are set
       // ...
       System.err.println("onPageLoad called");
    }

    public void addRow() {
       // andhere some defaults redefined
       // ...
       System.err.println("addRow called");
    }

    ...

and snippet from jsf page:

    <p:commandButton action="#{productsTableBean.addRow()}"
                     title="save"
                     update="@form" process="@form" >
    </p:commandButton>
    ...
    <f:metadata>
        <f:event type="preRenderView" listener="#{productsTableBean.onPageLoad}"/>
    </f:metadata>

And here is the main problem arise in calling order, i have following output:

onPageLoad called
addRow called
onPageLoad called <-- :(

But i want addRow to be the last action to be called, like this:

onPageLoad called
addRow called

Any simple solution here ?

Dfr
  • 3,915
  • 9
  • 38
  • 54
  • are you using `f:ajax` ? show your add row commandButton/Link code from JSF – Daniel Aug 06 '12 at 10:51
  • Hello, i'm using primefaces, but it seems just uses f:ajax internally, i updated code in my question. – Dfr Aug 06 '12 at 10:55
  • try placing the `` tag – Daniel Aug 06 '12 at 11:13
  • How exactly is a `@PostConstruct` insufficient? – BalusC Aug 06 '12 at 11:45
  • `@PostConstruct` is called only when the bean constructed, so in `ViewScoped` it called only when page is reloaded, but i need it called also on every button click. – Dfr Aug 06 '12 at 12:19
  • Yes, I know that, but I was more asking *why* exactly you need to invoke it on every postback? Your comment just states "set some defaults" and the view scoped bean already remembers them as long as you're interacting with the same view. – BalusC Aug 06 '12 at 12:20
  • Let's say user clicked "add row" commandButton, then some defaults got overridden with some new defaults in `addRow` action specific to this action. Then user clicked "removeRow" and now i want original defaults to be there again, but user will see those modified by `addRow` – Dfr Aug 06 '12 at 15:13

1 Answers1

8

Check this link : http://www.mkyong.com/jsf2/jsf-2-prerenderviewevent-example/

You know that the event is call on every requests : ajax, validation fail .... You can check if it's new request like this:

public boolean isNewRequest() {
        final FacesContext fc = FacesContext.getCurrentInstance();
        final boolean getMethod = ((HttpServletRequest) fc.getExternalContext().getRequest()).getMethod().equals("GET");
        final boolean ajaxRequest = fc.getPartialViewContext().isAjaxRequest();
        final boolean validationFailed = fc.isValidationFailed();
        return getMethod && !ajaxRequest && !validationFailed;
    }

public void onPageLoad() {
       // here some defaults are set
       // ...
if (isNewRequest()) {...}
       System.err.println("onPageLoad called");
    }
La Chamelle
  • 2,797
  • 3
  • 33
  • 54
  • 4
    The clumsy `getMethod && !ajaxRequest` can be replaced by `!fc.isPostback()`. But after all, this is in no way better than just a `@PostConstruct` if all what the OP actually did was replacing `@RequestScoped` by `@ViewScoped` (unless he *also* replaced `@ManagedProperty` by ``, but this is nowhere explicitly mentioned, hence also my comment on the question). – BalusC Aug 06 '12 at 12:16