Sometimes you need a way to enter tabular data such as list of quantity for products in a shopping cart, marks from a list of examination candiates, etc. If you just have one input value per line item, you can use a HashMap to store the value. This can be expanded to support multiple input values by having multiple HashMap. This describes a number of alternatives using some of more advanced features of WebWork. Assume you want to capture the quantity and a gift note for a list of products in a shopping cart (i.e Amazon).
1.
...
When the number of line items is known
If you are using JSP:
the cart.jsp file in altSyntax
Code Block |
---|
<s:iterator value="cart.items" status="rowstatus">
<s:hidden name="cart.items[%{#rowstatus.index}].productId" value="%{productId}">
<s:textfield name="cart.items[%{#rowstatus.index}].qty" value="%{qty}" />
<s:textfield name="cart.items[%{#rowstatus.index}].note" value="%{note}" />
</s:iterator>
|
the cart.jsp file (non altSyntax)
Code Block |
---|
<s:iterator value="cart.items" status="rowstatus"> <s:hidden name="'cart.items[' + #rowstatus.index + '].productId'" value="productId"> <s:textfield name="'cart.items[' + #rowstatus.index + '].qty'" value="qty" /> <s:textfield name="'cart.items[' + #rowstatus.index + '].note'" value="note" /> </s:iterator> |
Alternatively, if you use Velocity as your view technology of choice:
the cart.vm file
Code Block |
---|
#foreach ( $item in $cart.items ) #set($index = $velocityCount - 1) <input type="hidden" name="cart.items[$index].productId" value="$item.productId"> <input type="text" name="cart.items[$index].qty" value="$item.qty"> <input type="text" name="cart.items[$index].note" value="$item.note"> #end |
...
Code Block |
---|
public class UpdateCartAction extends ActionSupport { public Cart getCart() { return // Lazy initialization Cart result = ActionContext.getContext().getSession.get("cart.key"); if ( result == null ) { result = new Cart(); ActionContext.getContext().getSession.put("cart.key", result); } return result; } public String execute() throws Exception { // Just ensuring our cart is initialized... Cart cart = getCart(); // loop through a } } |
...
Code Block |
---|
public class CartItem implements Serializable { private int qty; private int productId; private String note; // getters/setters... } |
Explanation
The resulting vm file html code is rendered as
Code Block |
---|
<input type="hidden" name="cart.items[0].qty.productId" value="1"> <input type="text" name="cart.items[0].qty" value="2"> <input type="text" name="cart.items[0].note" value="This is a fun book!"> <input type="hidden" name="cart.items[1].qty.productId" value="2"> <input type="text" name="cart.items[1].qty" value="2"> <input type="text" name="cart.items[1].note" value="You love this one"> <input type="hidden" name="cart.items[2].qty.productId" value="3"> <input type="text" name="cart.items[2].qty" value="$item.qty"> <input type="text" name="cart.items[2].note" value=""> |
Webwork will populate all the entries in Cart with the correct values.
...
In depth, the ParametersInterceptor would apply the form results to our model, leading to the call similar like
Code Block |
---|
((CartItem) updateCartAction.getCart().getItems().get(0)).setProductId(1);
|
for the first shown line in the rendered result.
2. When the number of line items is unknown
For example, you want to allow the user to enter any number of ISBN, quanty and a note. You can replace ArrayList with XWorkList, which will automatically create new items if the index is greater than the size of the list.
3. Use
...
Type Conversion
If you want more advanced way to do this, check out Null Property Access for type conversion Type Conversion documentation.