我正在尝试实现<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 DB,但这不是问题。现在,我要创建一个新课程,因此CourseDisciplines中没有任何内容。
我想在复选框中显示allDisciplines,并希望当用户选中一个复选框时,将此复选框的对象Discipline添加到courseDisciplines中;而当取消选中一个复选框时,则从courseDsiciplines中删除该学科。
我的JSF 2.0代码如下:
<p:selectManyCheckbox id="disciplines" value="#{courseMBean.allDisciplines}" layout="grid" columns="2">
<f:selectItems value="#{courseMBean.courseDisciplines}" />
</p:selectManyCheckbox>
实际上,这显示了所有学科而未选中任何复选框,这是正确的。但是,当我选择一些复选框并提交表单时,我尝试在courseDisciplines中打印元素,而这在控制台中什么也没有显示。
我做错了什么?
最佳答案
当我选择一些复选框并提交表单时,我尝试在CourseDisciplines中打印元素
由于courseDisciplines
实际上代表可用项目而不是选定项目,因此您似乎误解了UISelectMany
和UISelectItem(s)
组件的一些基本概念。<f:selectItem(s)>
(来自UISelectItem(s)
系列)表示可用的项目。正是那些在UI中显示的项目,最终用户必须从中选择。value
的<p:selectManyCheckbox>
属性(来自UISelectMany
系列,例如<h:selectManyCheckbox>
和<h:selectManyMenu>
)表示(预)选择的项目。如果在第一次显示表单时此字段为null或为空,则不会预先选择任何内容。或者,如果其中包含一些预选项目,则将仅选择那些equal()
可用项目。
最终用户更改了UI中的选择并提交了表单后,所有选中的项目将最终出现在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
)时,您需要确保有一个Converter
,以便JSF可以正确地在它和String
之间进行转换,以用于生成的HTML输出和HTTP请求中。参数(HTML和HTTP既不能传递也不能保存Java对象,而只能传递String
表示的Java中的字符序列)。这也许是您的根本问题。您说提交时没有任何内容打印到控制台。但是,实际上从未调用整个
submit()
方法的情况可能会很好。您对此还不够明确。如果确实从未调用过整个操作方法(即,未在其中调用调试断点,或者在控制台中从未显示另一个打印静态字符串的System.out.println()
),则实际上您很可能发生了转换错误。如果您以正确的方式使用了<h|p:message(s)>
,或者已关注有关排队但未显示的面孔消息的服务器日志,那么您应该已经注意到它。在这种情况下,您需要实现在
Converter
和Discipline
之间转换的String
。@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?