Maybe this handy little component will help:
/**
* A Tapestry component that rearranges the HTML items in its body into multiple
* columns. It accomplishes this by DOM manipulation after the body is rendered
* to the DOM.
* <p>
* Note: For this to work properly, the items that you wrap this component
* around must each consist of a single HTML element (possibly with nested
* elements). For example, the following works, because each item is contained
* within a single <li> element:
*
* <pre>
* <t:columns number="2">
* <t:loop source="myList" value="oneItem">
* <li><b>Name:</b>{$oneItem.name}</li>
* </t:loop>
* </t:columns>
* </pre>
*
* But the following fails to lay out property, because there are two HTML
* elements -- a span and a br -- per item:
*
* <pre>
* <t:columns number="2">
* <t:loop source="myList" value="oneItem">
* <span>${oneItem.name}</span><br />
* </t:loop>
* </t:columns>
* </pre>
*/
@SupportsInformalParameters
public class Columns {
/**
* The number of columns to divide the items into
*/
@Property
@Parameter(value="5", defaultPrefix="literal")
private int number;
@Property
@Parameter(value="literal:t-column")
private String columnClass;
@Inject
private ComponentResources componentResources;
/**
* Manipulate the Tapestry-rendered DOM to insert as many DIV elements as
* needed to break up the list of items in our "body" into the requested
* number of columns. This method is only called after the "body" is
* rendered into the DOM.
*
* @param writer
*/
@AfterRenderBody
void manipulateTheDom(MarkupWriter writer)
{
Element container = writer.getElement();
// figure out how many items should go into each column
List<Node> children = container.getChildren();
int numChildren = children.size();
int itemsPerColumn = numChildren / number;
int remainder = numChildren % number;
int itemNum = 0;
// render informal parameters into the container element
componentResources.renderInformalParameters(writer);
for (int columnNumber = 0; columnNumber < number; columnNumber++)
{
int extras = (remainder > 0) ? 1 : 0;
remainder--;
int numItemsthisColumn = itemsPerColumn + extras;
// Make a per-column wrapper element and move it to the bottom
Element columnElement = container.element("div", "class",
columnClass);
columnElement.moveToBottom(container);
// move some children into the new column wrapper element
for (int i = 0; i < numItemsthisColumn; i++)
{
children.get(itemNum).moveToBottom(columnElement);
itemNum++;
}
}
}
}
On Wed, Jan 29, 2014 at 3:28 PM, Thiago H de Paula Figueiredo
<[email protected]> wrote:
> On Wed, 29 Jan 2014 17:58:08 -0200, Dimitris Zenios
> <[email protected]> wrote:
>
>> I am not sure whether i will be able to cast to collection.Maybe tapestry
>> is doing some magic with BindParameter.
>
>
> You don't need to cast it to a Collection, because Iterable is exactly the
> Java interface implemented by any class which provides an Iterator. Just use
> Iterable and its iterator() method directly.
>
>
> --
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]