简体   繁体   English

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

[英]How to use SelectManyCheckbox with two ArrayList? - Primefaces

I'm trying to implement a <p:selectManyCheckbox> but I'm having no success. 我正在尝试实现<p:selectManyCheckbox>但我没有成功。

Now I have the following architecture: 现在我有以下架构:

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

In Course class I have two ArrayList<Discipline> : 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)
    (...)
}

All data comes from a MYSQL DB, but that isn't the question. 所有数据都来自MYSQL数据库,但这不是问题。 Now I want create a new Course, so I don't have anything in courseDisciplines. 现在我想创建一个新课程,所以我在courseDisciplines中没有任何内容。

I want show allDisciplines in checkboxes, and want that when user select one checkbox, the object Discipline of this checkbox be added in courseDisciplines - and when unselect one checkbox, remove the discipline from the courseDsiciplines. 我希望在复选框中显示allDisciplines,并希望在用户选择一个复选框时,在courseDisciplines中添加此复选框的对象Discipline - 并且当取消选中一个复选框时,从courseDsiciplines中删除该规则。

My JSF 2.0 code is following: 我的JSF 2.0代码如下:

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

This actually shows all disciplines without any selected checkboxes, what's right. 这实际上显示所有学科没有任何选中的复选框,什么是正确的。 But when I select some checkboxes and submit the form I try to print the elements inside courseDisciplines, and this don't show anything in console. 但是当我选择一些复选框并提交表单时,我尝试在courseDisciplines中打印元素,这不会在控制台中显示任何内容。

What I'm doing wrong? 我做错了什么?

when I select some checkboxes and submit the form I try to print the elements inside courseDisciplines 当我选择一些复选框并提交表单时,我尝试在courseDisciplines中打印元素

As the courseDisciplines actually represents the available items not the selected items, it seems that you misunderstood some basic concepts around the UISelectMany and UISelectItem(s) components. 由于courseDisciplines实际上代表了可用项目而不是所选项目,因此您似乎误解了UISelectManyUISelectItem(s)组件周围的一些基本概念。

The <f:selectItem(s)> (from the UISelectItem(s) family) represent the available items. <f:selectItem(s)> (来自UISelectItem(s)系列)表示可用的项目。 It are exactly those items which are shown in the UI and which the enduser has to choose from. 正是UI中显示的那些项目以及最终用户必须选择的项目。

The value attribute of <p:selectManyCheckbox> (from the UISelectMany family, like <h:selectManyCheckbox> and <h:selectManyMenu> ) represent the (pre)selected items. <p:selectManyCheckbox>value属性(来自UISelectMany系列,如<h:selectManyCheckbox><h:selectManyMenu> )表示(预)选定的项目。 If this is null or empty during first display of the form, then nothing is preselected. 如果在首次显示表单时该值为null或为空,则不会预先选择任何内容。 Or if this contains some preselected items, then only those available items which are equal() will be preselected. 或者如果它包含一些预选项,则只预选那些equal()可用项。

When the enduser has changed the selection in the UI and submits the form, then all selected items will end up in the value attribute of UISelectMany component. 当最终用户更改了UI中的选择并提交表单时,所有选定的项目将最终出现在UISelectMany组件的value属性中。 The UISelectItem(s) remains unchanged. UISelectItem(s)保持不变。

Here's a basic kickoff example: 这是一个基本的启动示例:

<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);
}

(all other <p:selectManyXxx> and <h:selectManyXxx> components work exactly the same) (所有其他<p:selectManyXxx><h:selectManyXxx>组件完全相同)

When a complex Javabean object like Discipline comes into the picture, then you need to make sure that there's a Converter for that so that JSF can properly convert between it and String for usage in generated HTML output and as HTTP request parameter (HTML and HTTP namely can't pass around nor hold Java objects, but only character sequences which are in Java represented by String ). 当像Discipline这样复杂的Javabean对象进入图片时,你需要确保有一个Converter ,以便JSF可以在它和String之间正确转换,以便在生成的HTML输出中使用,并作为HTTP请求参数(HTML和HTTP即不能传递或保存Java对象,而只能传递由String表示的Java中的字符序列。

This is perhaps your root problem. 这可能是你的根本问题。 You said that nothing is printed to the console on submit. 你说在提交时没有打印到控制台。 But it could be as good the case that the whole submit() method is actually never being invoked. 但是实际上永远不会调用整个submit()方法的情况也是如此。 You're not explicit enough on this. 你对此不够明确。 If the whole action method is indeed never invoked (ie a debug breakpoint doesn't hit there, or another System.out.println() printing a static string is never shown in console), then you've actually most likely a conversion error. 如果确实从未调用过整个action方法(即调试断点没有在那里,或者另一个System.out.println()打印静态字符串从未在控制台中显示),那么你实际上很可能是转换错误。 If you have used <h|p:message(s)> the right way, or have paid attention to server log about queued but undisplayed faces messages, then you should have noticed it. 如果您使用<h|p:message(s)>正确的方式,或者已经注意了有关排队但未显示的面部消息的服务器日志,那么您应该注意到它。

In that case, you need to implement a Converter which converts between Discipline and String . 在这种情况下,您需要实现一个在DisciplineString之间进行Converter

@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.
    }

}

More than often the DB ID is being used as String representation. DB ID通常被用作String表示。 See also the section "Complex object as selected item" of this answer on a related question: How to populate options of h:selectOneMenu from database? 另请参阅此答案的“复杂对象作为所选项目”部分的相关问题: 如何从数据库填充h:selectOneMenu的选项?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM