Clicking p:commandButton causes the value of p:selectOneMenu being set twice

故事扮演 提交于 2019-12-11 04:36:35

问题


I ran into an issue with PrimeFaces - consider form with SelectOneMenu being put inside of Inplace. Next to the Inplace we have a CommandButton that is meant to reset the value of the SelectOneMenu.

The form looks like this:

<h:form id="myform">
    <p:inplace id="inplace" editor="true">
        <p:ajax event="save" update="@(form)" />

        <f:facet name="output">
            <h:outputText value="#{testBean.year}" />
        </f:facet>

        <f:facet name="input">
            <p:selectOneMenu id="selYears" value="#{testBean.year}">
                <f:selectItem itemValue="2015" itemLabel="2015" />
                <f:selectItem itemValue="2014" itemLabel="2014" />
                <f:selectItem itemValue="2013" itemLabel="2013" />
            </p:selectOneMenu>
        </f:facet>
    </p:inplace>

    <p:commandButton id="btnResetYear" value="Reset year" rendered="#{testBean.year lt 2015}"
        action="#{testBean.resetYear()}" update="@(form)" />

</h:form>

This is the TestBean:

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class TestBean {
    private int year;

    @PostConstruct
    private void init() {
        this.year = 2015;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        System.out.println("---> setYear: " + year);
        this.year = year;
        this.someMethod();
    }

    public void someMethod() {
        System.out.println("---> someMethod: " + this.year);
    }

    public void resetYear() {
        System.out.println("---> resetYear");
        this.setYear(2015);
    }
}

The following scenario works just fine:

  1. Click the year to show the actual SelectOneMenu
  2. Select different year (e.g. 2013)
  3. Confirm the selection by clicking the "check" button

However, if I try clicking the "Reset year" button, the method setYear is called with the original year as a parameter just before resetYear is called. This is what I can see in a console:

12:28:40,003 INFO  [stdout] (default task-15) ---> setYear: 2013
12:28:40,003 INFO  [stdout] (default task-15) ---> someMethod: 2013
12:28:40,004 INFO  [stdout] (default task-15) ---> resetYear
12:28:40,004 INFO  [stdout] (default task-15) ---> setYear: 2015
12:28:40,004 INFO  [stdout] (default task-15) ---> someMethod: 2015

Which is what I do not want as someMethod is intended to e.g. load data from DB and there is no reason to run it for the original value and then for the new value again.

If I use the standard CommandButton instead of the one provided by PrimeFaces, it seems to work properly:

<h:commandButton id="btnResetYear" value="Reset year" rendered="#{testBean.year lt 2015}">
    <f:ajax listener="#{testBean.resetYear}" render="myform" />
</h:commandButton>

Clicking the standard button would give the expected result:

12:42:11,506 INFO  [stdout] (default task-88) ---> resetYear
12:42:11,506 INFO  [stdout] (default task-88) ---> setYear: 2015
12:42:11,506 INFO  [stdout] (default task-88) ---> someMethod: 2015

QUESTION:

Is this a bug in PrimeFaces or did I do anything wrong? Is there a way to setup the PF's CommandButton to behave like described above, i.e. not to trigger the setYear method with old parameter passed in or do I have to stick with the "standard" CommandButton?

I was experimenting with setting immediate="true" to the CommandButton and it indeed skipped setting the original value first, but the SelectOneMenu didn't take the new value into account, no matter what I put into the button's update attribute - it was still showing the original value.

The example was run using the following:

  • Java 1.8 (jdk1.8.0_51 - 64bit)
  • PrimeFaces 5.2
  • WildFly 8.2.0 (also tested with JBoss 7.1)

Any idea is more than welcome.


回答1:


After few more hours I figured out what the problem was - the default behavior of PF's CommandButton is to process everything on the page, which is basically the same as if I set process="@all"

I found out this by checking details of the request/response sent/received by the CommandButton - there was the following parameter in the request header:

javax.faces.partial.execute = @all

So setting process="@this" to the CommandButton did the trick and I can observe the correct behavior now:

18:45:51,874 INFO  [stdout] (default task-41) ---> resetYear
18:45:51,874 INFO  [stdout] (default task-41) ---> setYear: 2015
18:45:51,874 INFO  [stdout] (default task-41) ---> someMethod: 2015

This is the final version of my CommandButton:

<p:commandButton id="btnResetYear" value="Reset year" rendered="#{testBean.year lt 2015}"
    action="#{testBean.resetYear()}" update="@(form)" process="@this" />

I hope to save someone else's time by posting this solution here :-)



来源:https://stackoverflow.com/questions/32295806/clicking-pcommandbutton-causes-the-value-of-pselectonemenu-being-set-twice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!