p:selectManyMenu(with checkbox):同时添加项目和select复选框

p:selectManyMenu(with checkbox): Add item and select checkbox at the same time

xhtml 代码

<p:selectManyMenu id="menuid"
                value="#{bean.selectedActivities}"
                showCheckbox="true" scrollable="true" scrollHeight="150">
                <f:selectItems value="#{bean.activities}" var="activity" itemValue="#{activity}"
                               itemLabel="#{activity}" />               
</p:selectManyMenu>
<p:commandButton value="ADD ACTIVITY" id="addId">
    <p:ajax event="click" process="@this" update="menuid" listener="#{bean.addActivity()}"/>
</p:commandButton>

豆子:

private List<String> selectedActivities = new ArrayList<>();
private List<String> activities = new ArrayList<>();
int index = 1;
public void addActivity(){
  String activity = "Activity "+ (index ++);
  activities.add(activity);
  selectedActivities.add(activity);
}

此代码正在向 manyMenu 添加新项目,但未选中复选框。

除了一些遗漏的注释外,我看不出有什么错误。无论如何,这是一个基于您的代码的经过测试的解决方案,应该可以使用。首先让我们定义视图。这与您的示例基本相同:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>SelectMany Example</title>
    </h:head>
    <h:body>
        <h:form>
            <p:selectManyMenu id="menuid"
                      value="#{selectManyBackingBean.selectedActivities}"
                      showCheckbox="true" scrollable="true" scrollHeight="150">
                <f:selectItems value="#{selectManyBackingBean.activities}" var="activity" itemValue="#{activity}"
                           itemLabel="#{activity}" />               
            </p:selectManyMenu>
            <p:commandButton value="ADD ACTIVITY" id="addId">
                <p:ajax event="click" process="@form" update="menuid"
                    listener="#{selectManyBackingBean.onAddActivity}"/>
            </p:commandButton>
        </h:form>
    </h:body>
</html>

然后,我们定义backing bean:

@Data
@Named
@ViewScoped
public class SelectManyBackingBean implements Serializable {
    private List<String> selectedActivities;
    private List<String> activities;
    private int index;

    @PostConstruct
    private void init() {
        activities =  new ArrayList<>();
        selectedActivities = new ArrayList<>();
        index = 0;
    }

    public void onAddActivity(){
        String activity = "Activity " + (index++);
        activities.add(activity);
        selectedActivities.add(activity);
    }
}

这应该会给您带来预期的行为。单击 ADD ACTIVITY 按钮三次现在会产生以下结果:

请注意命令按钮从 process="@this"process="@form" 的细微变化。这将确保您在组件中所做的任何更改也包含在表单提交中。如果您将其保持在原始值,则在菜单中的复选框上的任何单击都不会保留,并且会在您按下命令按钮时将条目重置为以前的值(这是因为在生命周期内不包括相关组件循环执行)。