如何使用两个ArrayList的SelectManyCheckbox? - Primefaces

时间:2013-11-09 22:17:52

标签: jsf primefaces selectmanycheckbox

我正在尝试实施<p:selectManyCheckbox>,但我没有成功。

现在我有以下架构:

Course - have many Disciplines
Discipline - belongs to none, one or many Courses.

Course课程中,我有两个ArrayList<Discipline>

public class CourseMBean{

    (...)
    // Stores all disciplines
    private static ArrayList<Discipline> allDisciplines;

    // Stores only the disciplines that's already associated with this course.
    private static ArrayList<Discipline> courseDisciplines;

    (get and set for the arraylists)
    (...)
}

所有数据都来自MYSQL数据库,但这不是问题。现在我想创建一个新课程,所以我在courseDisciplines中没有任何内容。

我希望在复选框中显示allDisciplines,并希望在用户选择一个复选框时,在courseDisciplines中添加此复选框的对象Discipline - 并且取消选中一个复选框时,从courseDsiciplines中删除该规则。

我的JSF 2.0代码如下:

<p:selectManyCheckbox id="disciplines" value="#{courseMBean.allDisciplines}" layout="grid" columns="2">                                          
     <f:selectItems value="#{courseMBean.courseDisciplines}" />
</p:selectManyCheckbox>

这实际上显示了没有任何选中复选框的所有学科,这是正确的。但是当我选择一些复选框并提交表单时,我尝试在courseDisciplines中打印元素,这不会在控制台中显示任何内容。

我做错了什么?

1 个答案:

答案 0 :(得分:9)

  

当我选择一些复选框并提交表单时,我尝试在courseDisciplines中打印元素

由于courseDisciplines实际上代表可用的项而不是选定的项,因此您似乎误解了UISelectMany周围的一些基本概念, UISelectItem(s)个组件。

<f:selectItem(s)>(来自UISelectItem(s)系列)代表可用项。正是UI中显示的那些项目以及最终用户必须选择的项目。

value的{​​{1}}属性(来自<p:selectManyCheckbox>家庭,如UISelectMany<h:selectManyCheckbox>)代表(预选)物品。如果在首次显示表单时该值为null或为空,则不会预先选择任何内容。或者,如果这包含一些预选项目,则只会预选<h:selectManyMenu>个可用项目。

当最终用户更改了UI中的选择并提交表单时,所有选定的项目将最终位于equal()组件的value属性中。 UISelectMany保持不变。

这是一个基本的启动示例:

UISelectItem(s)
<p:selectManyCheckbox value="#{bean.selectedItems}">
    <f:selectItems value="#{bean.availableItems}" />
</p:selectManyCheckbox>
<p:commandButton value="Submit" action="#{bean.submit}" />
<p:messages autoUpdate="true" />

(所有其他private List<String> selectedItems; // +getter +setter private List<String> availableItems; // +getter (no setter necessary!) @PostConstruct public void init() { availableItems = new ArrayList<String>(); availableItems.add("one"); availableItems.add("two"); availableItems.add("three"); } public void submit() { System.out.println("Selected items: " + selectedItems); } <p:selectManyXxx>组件的工作方式完全相同)

当像<h:selectManyXxx>之类的复杂Javabean对象进入图片时,你需要确保有一个Discipline,以便JSF可以在它和Converter之间正确转换在生成的HTML输出中使用和作为HTTP请求参数(HTML和HTTP即不能传递或保存Java对象,但只能使用由String表示的Java字符序列。)

这可能是你的根本问题。你说在提交时没有打印到控制台。但实际上永远不会调用整个String方法的情况可能同样出色。你对此不够明确。如果确实从未调用整个action方法(即调试断点没有在那里,或者另一个submit()打印,则控制台中永远不会显示静态字符串),那么实际上很可能是转换错误。如果您以正确的方式使用System.out.println(),或者已经注意了有关排队但未显示的面部消息的服务器日志,那么您应该注意到它。

在这种情况下,您需要实现<h|p:message(s)>,该Converter可在DisciplineString之间进行转换。

@FacesConverter(forClass=Discipline.class)
public class DisciplineConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        // Write code here to convert from String to Discipline.
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
        // Write code here to convert from Discipline to String.
    }

}

DB ID通常用作String表示。有关相关问题,请参阅此答案的“复杂对象作为所选项目”部分:How to populate options of h:selectOneMenu from database?