2

I want to do the following:

  1. Select an item from an h:selectOneMenu
  2. Update the backing bean with the new value, via ajax
  3. Run a Javascript function with the new value

In the following code though, alert(#{backingBean.derivedValue}) still contains the value from the last change (i.e. it's 0 when I select "Two", 4 when I select "One", and so on):

<h:form>
    <h:selectOneMenu value="#{backingBean.input1}">
        <f:selectItem itemLabel="One" itemValue="1"/>
        <f:selectItem itemLabel="Two" itemValue="2"/>
        <f:ajax render="@form" onevent="function(data) { if (data.status === 'success') { alert(#{backingBean.derivedValue}) }}"/>
    </h:selectOneMenu>

    Input value: #{backingBean.input1}
    Derived value: #{backingBean.derivedValue}
</h:form>

And the backing-bean:

@ManagedBean
@ViewScoped
public class BackingBean {

    private int input1;
    private int derivedValue;

    public int getDerivedValue() {
        return derivedValue;
    }

    public void setDerivedValue(int derivedValue) {
        this.derivedValue = derivedValue;
    }

    public int getInput1() {
        return input1;
    }

    public void setInput1(int input1) {
        this.input1 = input1;
        derivedValue = input1 * 2;
    }
}

Is there a way to do this? (BTW, I've read countless threads on this site which kind of/sort of deal with JSF/ajax/javascript working together, but not this specific issue)

8
  • far simpler to remove your inline javascript and use unobtrusive script event handler. Do everything you need inside a named function Commented Apr 9, 2015 at 19:38
  • I'm not married to doing it inline. Can you provide a sample of what you are talking about? I'm not familiar with what you mean by "script event handler". I've tried having onevent="refresh_on_success" which points to "function refresh_on_success(data)" but I have the same issue... Commented Apr 9, 2015 at 19:46
  • RE EDIT 2: I think you're right, @wsaxton. Have a look at the HTML source of your page, see what the Javascript says. Commented Apr 9, 2015 at 22:51
  • @DavidS, The HTML definitely shows the old value and the old value is appearing inside the javascript call so...it's certainly a timing thing. Perhaps EL expressions within the AJAX tags don't render like other tags? Commented Apr 9, 2015 at 22:56
  • I am seeing the same behaviour, @wsaxton. I can display the new durationDerivedValue on the page using h:outputText, but if I use a Javascript alert inside the function, the old value is shown. We're probably misunderstanding something fundamental about EL. Commented Apr 9, 2015 at 23:03

1 Answer 1

3

I had success implementing the solution proposed in this answer, Getting backing bean value with Javascript which uses PrimeFace's RequestContext to add a Javascript callback parameter server-side.

Here is my Facelets page:

<h:form>
    <p:selectOneMenu value="#{backingBean.input1}">
        <f:selectItem itemLabel="One" itemValue="1"/>
        <f:selectItem itemLabel="Two" itemValue="2"/>
        <p:ajax oncomplete="afterLoad(xhr, status, args)"/>
    </p:selectOneMenu>
    <h:outputScript>
        function afterLoad(xhr, status, args) {    
          alert("Input * 2 = " + args.derived);
        }
    </h:outputScript>
</h:form>

And here is my backing-bean:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.context.RequestContext;

@ManagedBean
@ViewScoped
public class BackingBean {

    private int input1;
    private int derivedValue;

    public int getDerivedValue() {
        return derivedValue;
    }

    public void setDerivedValue(int derivedValue) {
        this.derivedValue = derivedValue;
    }

    public int getInput1() {
        return input1;
    }

    public void setInput1(int input1) {
        this.input1 = input1;
        derivedValue = input1 * 2;
        RequestContext.getCurrentInstance().addCallbackParam("derived", derivedValue);
    }
}

(I don't know if this is a good solution for integrating JSF and D3.)

See also

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

2 Comments

This could work as a workaround, but its a bit of a mess. I really wish there was an EL way of doing it. Unfortunately, I ended up breaking JSF and D3 apart completely and just use URL's to pass information between them.
I understand wanting something simpler, but I don't agree that this is a workaround or a mess. It's just passing a JSON parameter to a Javascript callback, which is how a standard REST API works anyhow. It's exactly what PrimeFace's RequestContext was designed for, and it's what JSF ajax-enabled components are doing behind the scenes. Again though, I understand wanting a simpler solution -- I'm not satisfied with this myself.

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.