2013-11-09 28 views
3

我試圖實現一個<p:selectManyCheckbox>但我沒有成功。如何使用SelectManyCheckbox和兩個ArrayList? - Primefaces

現在我有以下結構:

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數據庫,但是這不是問題。現在我想創建一門新課程,所以我沒有任何課程學科。

我想在複選框中顯示所有的紀律,並希望當用戶選擇一個複選框時,該複選框的對象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中的元素,而這不會在控制檯中顯示任何內容。

我做錯了什麼?

+0

是selectManyCheckbox在一個窗體中? CourseMBean的範圍是什麼? – 757071

+0

是的,他在一個表單內,範圍是@ SessionScoped.Is是錯誤的,這應該按我的意願工作? – Paladini

+0

我很難理解你的問題。你爲什麼試圖打印可用的項目而不是選定的項目,爲什麼可用的項目顯然是空的,但你顯然可以在UI中選擇它們? – BalusC

回答

8

當我選擇一些複選框,並提交表單我嘗試打印裏面courseDisciplines元素

由於courseDisciplines實際上代表可用項目不是選擇項目,它似乎你誤解了UISelectManyUISelectItem(s)組件的一些基本概念。

<f:selectItem(s)>(來自UISelectItem(s)系列)代表可用項目。正是這些項目顯示在用戶界面中,最終用戶可以從中選擇。

value屬性的<p:selectManyCheckbox>(從UISelectMany家族,像<h:selectManyCheckbox><h:selectManyMenu>)表示(預)選擇項目。如果在第一次顯示錶單時這是空或空,則不會預選任何內容。或者如果這包含一些預先選擇的項目,則只有那些可用項目是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>和​​部件的工作原理完全相同)

當一個像Discipline一個複雜的JavaBean對象到圖片,那麼你需要確保有一個Converter,以便JSF可以在它和String之間正確轉換e在生成的HTML輸出中作爲HTTP請求參數(HTML和HTTP即不能傳遞也不保存Java對象,但僅包含由String表示的Java中的字符序列)。

這也許是你的根本問題。您表示在提交時沒有任何內容顯示在控制檯上。但是,整個submit()方法實際上永遠不會被調用。你對此不夠明確。如果整個動作方法確實從未被調用過(即調試斷點沒有打到那裏,或者另一個打印一個靜態字符串的控件從不在控制檯中顯示),那麼你實際上很可能是一個轉換錯誤。如果您正確使用<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?

+0

再次感謝Balusc!只是一個小問題:在轉換器中,我可以獲得Discipline「id」值而不是Discipline「name」?我這樣說是因爲句柄字符串不像int(id)那樣太安全和快速,它更安全從數據庫中獲取一個帶有ID而不是「name」的值,對吧? – Paladini

+0

我從http://stackoverflow.com/questions/6848970/how-to-prepopulate-a-hselectonemenu-from-a-db/6850681#6850681中使用了Omnifaces,從你的另一個答案再次感謝! – Paladini

相關問題