0

I want a countdown in my JSF-Page, and i solved it with <p:poll> from Primefaces.

I have following source:

JSF-Page:

<h:form>
    <h:outputText id="timeLeft" value="#{bean.secondsToGo}" />
    <p:poll interval="1" listener="#{bean.countdown}" stop="#{bean.secondsToGo<0}" update="timeLeft" />
</h:form>

BEAN (view-scoped):

private int secondsToGo;
public void setValues(){ //prerenderview-event )
    if(FacesContext.getCurrentInstance().isPostback()){
        System.out.println("POSTBACK RECOGNIZED");
        return; //ignore ajax-calls!
    }
    ...
    secondsToGo=74; //(the value depends from a GET-parameter
    System.out.println("INIT: " + secondsToGo);
}

public void countdown(){
    System.out.println("BEFORE: " + secondsToGo);
    secondsToGo--;
    System.out.println("AFTER: " + secondsToGo);
}

The funny or weird thing is that when the ajax-call is performed (p:poll), the secondsToGo is resetted to 0:

INIT: 74 //correct value

BEFORE: 0

AFTER: -1

Why?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Niko
  • 1,054
  • 5
  • 25
  • 52

1 Answers1

1

You should use @PostConstruct annotation for someMethodToSetTimeout_PrerenderView instead of prerenderview as "The preRenderView event is invoked on every HTTP request (yes, this also includes ajax requests!)." as BalusC states in when-to-use-prerenderview-versus-postconstruct.

I would also change stop condition for poll to stop="#{bean.secondsToGo == 0}", it makes counting a little bit clearer.

EDIT:

From my point of view, all you have to do is:

    <h:form>
        <h:outputText id="timeLeft" value="#{bean.secondsToGo}" />
        <p:poll interval="1" listener="#{bean.countdown}" stop="#{bean.secondsToGo == 0}" update="timeLeft" />
    </h:form>

and

private int secondsToGo;

@PostConstruct
public void init(){
    secondsToGo = 10;
}

public void countdown(){
    secondsToGo--;
}

But please correct me, if you expect something more.

Community
  • 1
  • 1
Dodek
  • 51
  • 4
  • Thanks for your answer, i forgot to mention that i use GET-Parameter and I filter out ajax-requests when prerender is invoked: if(FacesContext.getCurrentInstance().isPostback()){ System.out.println("POSTBACK RECOGNIZED"); return; //ignoreajax! } so i need to set the variables on prerenderview. I figured out that if i put all the used variables in it would solve the problem, but this cannot be the correct way. Maybe there is another way to count a server-side-variable down (beside of polling)? All i want is to change only ONE variable, not all of the bean... – Niko Oct 08 '13 at 08:58
  • do you need to start the counter more than once in one page view? why do you think that more than one variable has to be changed? – Dodek Oct 08 '13 at 12:56
  • Hi, The thing which is missing is that in PostConstruct i don't have access to my viewparam (GET-Parameters) values. so i need to set the init value on the first prerenderview (its only executed once) – Niko Oct 08 '13 at 21:08
  • could you provide the rest of your code from jsf page related to this problem? – Dodek Oct 09 '13 at 05:43
  • thats all. pls paste it and you will see that each ajax-request resets the value of the in the first prerender set variables – Niko Oct 10 '13 at 10:45