14

JSF 2.0, Mojarra 2.0.1, PrimeFaces 3.4.1

There are similar questions but I need sth. else; javascript function has to wait for the backing bean method, which is filling the variable that wanted to be pulled from js function. What I want to say is:

<p:commandLink action="#{statusBean.getStatuses}" oncomplete="afterLoad()"/>

Assuming js function just getting the value and printing it to the screen.

function afterLoad() {    
    alert("#{statusBean.size}");
}

And here is the birthday kid:

@ManagedBean
@ViewScoped
public class StatusBean {
    public int size=0;
    List<Status> panelList = new ArrayList<Status>();
    public void getStatuses() {
        this.panelList = fillList();
        this.size = panelList.size(); //Assuming 3
    }
    //getter and setters
}

So function alerts the size as 0 which is the initial value of it, while we're expecting to see 3.

How it's working: If I add the @PostConstruct annotation to bean's head surely it gets the correct size, because bean is already constructed before the page load. But this means redundant processes, value just needed after the commandlink action. So how to postpone the js function? Any ideas?

3
  • 1
    Mojarra 2.0.1 is ancient. It's over 3 years old already. Consider upgrading. There are many, many bugfixes and improvements in the current 2.1.19 version. Commented Feb 19, 2013 at 20:12
  • @BalusC Ok I am going to review the version differences, also both answers are correct and working thank you and partlov but I couldn't decide to which one should be selected as the answer. Should I choose due to first come first served basis? But server says you answered 1 min ago but when I last looked it was saying partlov answered first. Is it same-time? Commented Feb 19, 2013 at 20:27
  • Just choose the one which is most helpful to you. The answers posted so far do not provide exactly the same information. As to the exact answer timestap, just check the tooltip of the "answered" timestamp. But you should not consider this in choosing the answer. This only simulates the FGITW. Commented Feb 19, 2013 at 20:28

2 Answers 2

26

JSF/EL and HTML/JS doesn't run in sync. Instead, JSF/EL run in webserver and produces HTML/JS which in turn runs in webbrowser. Open page in browser, rightclick and View Source. You see, there's no single line of JSF/EL. It's one and all HTML/JS. In place of your JS function, you'll see:

function afterLoad() {    
    alert("0");
}

Exactly this JS function get invoked on complete of your command button action. So the result is fully expected.

Basically, you want to let JSF re-render that piece of JS.

<p:commandLink action="#{statusBean.getStatuses}" update="afterLoad" oncomplete="afterLoad()"/>
<h:panelGroup id="afterLoad">
    <h:outputScript>
        function afterLoad() {    
            alert("#{statusBean.size}");
        }
    </h:outputScript>
</h:panelGroup>

Depending on the concrete functional requirement, which you didn't tell anything about, there may be more elegant ways. For example, RequestContext#execute(), <o:onloadScript>, etc.

Sign up to request clarification or add additional context in comments.

2 Comments

BalusC, you're rock :)
This is an old thread.. But I have a question.. How to accomplish this if I am using an external javascript file? Please help me out.
11

EL in your JavaScript is calculated when page is rendered and you can update its container (if it is in some JSF component), but I would suggest another approach.

As you are making AJAX request, you can add callback parameter in getStatuses() method. You can use Primefaces's RequestContext utility method addCallBackParam() for this:

public void getStatuses() {
    this.panelList = fillList();
    this.size = panelList.size();
    RequestContext.getCurrentInstance().addCallBackParam("size", this.size);
}

and you can use this parameter in xhtml:

<p:commandLink action="#{statusBean.getStatuses}" oncomplete="afterLoad(xhr, status, args)"/>

<script type="text/javascript">
  function afterLoad(xhr, status, args) {    
    alert(args.size);
  }
</script>

1 Comment

Hello again, I've an issue about addCallBackParam. It works perfect when using the afterLoad(xhr,status,args) at first invocation. But If I want to call it for second time using same getStatuses(), in the afterLoad method size becomes undefined. It seems it can not adds call back param correctly on second invocation. What I mean with second invocation is: for example user adds a status and afterLoad works after that successfully, but If user deletes a status, I've defined a remotecommand it calls statusBean.getStatuses and it has oncomplete="afterLoad(xhr,status,args).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.