I am using JSF 2 with Glassfish 4. I would like to create an object that has a collection of objects as one of its fields. When searching, I can only find ways to display a collection field in a JSF form. Here I want the opposite: allow the user to populate this collection while creating the parent object. Simplified example below:
Parent Object: Account
public class Account {
private String accountName;
private List<Order> orderList = new ArrayList<Order>();
public String save() {
System.out.println(accountName);
System.out.println(orderList);
return "";
}
// Constructors, getters and setters below.
}
Child Object: Order
public class Order {
private String orderName;
private Integer orderCost;
// Constructors, getters and setters below.
}
JSF Page Body
The idea for the form was taken from BalusC's answer here.
<h:body>
<h1>Create Account</h1>
<h:form>
<h:panelGrid>
Account Name:
<h:inputText value="#{account.accountName}" />
<ui:repeat value="#{account.orderList}" varStatus="loop">
Order Name:
<h:inputText value="#{account.orderList[loop.index]}" />
Order Cost:
<h:inputText value="#{account.orderList[loop.index]}" />
</ui:repeat>
</h:panelGrid>
<h:commandButton action="#{account.save}" value="Create" />
</h:form>
</h:body>
I run into a few problems:
- It's impossible for me to have a set number of Orders displayed. (ex: max 5 per new account). An input field is only displayed if the List already has some objects. This makes sense, but I would like to present the user with X blank lines they can fill in.
- I am unable to expose both the orderName and orderCost fields at once to the user.
- Later on I would like to add a commandButton that adds another row of inputText fields in the UI so the user can add however many orders to an account as they want.
Any help greatly appreciated. Happy to answer questions for anything I missed. Thank you!
After BalusC's help I made the following changes and I now have the behaviour that I want:
// Prop up the array so the desired number of fields appears in the UI
@PostConstruct
public void prepare() {
orderList.add(new Order());
orderList.add(new Order());
orderList.add(new Order());
}
Iterate through the list of empty Order objects. No data is disabled since all field values in the Order objects are null. Also, since I created the objects in @PostConstruct, the user's changes are easily saved on Submit.
<ui:repeat value="#{account.orderList}" var="order">
Order Name:
<h:inputText value="#{order.orderName}" />
Order Cost:
<h:inputText value="#{order.orderCost}" /><br/>
</ui:repeat>