Re: Loop and iterator
You can use two loops. Example here: http://tapestry-stitch.uklance.cloudbees.net/gallerydemo On 29 Jan 2014 16:12, Dimitris Zenios dimitris.zen...@gmail.com wrote: Is it possible to make the loop component expose the iterator through a public method? There are situations where a mixin might want to use it. Best Regards Dimitris Zenios
Re: Loop and iterator
On Thu, 30 Jan 2014 00:31:35 -0200, Bob Harner bobhar...@gmail.com wrote: You mean as a mixin applied to the Loop component? I guess so, but I don't see how that would make it any better. I love mixins! :) And your component doesn't really generate content by itself (it just rewrites what some other does), and in this scenario I always go for a mixin. -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
I have a list of 8 elements.I want to loop over the elements and every 3 elements or at beginning of list to Start with a div and end with a /div. Resulting output should be div item item item? /div div item item item /div div item item /div So i though i will create a mixin that attaches to the loop and adds those divs.I managed to almost make it work except one last case.After the last element i want to close my previous div even if the index is not % 3.In order to know that loop is in the last element i need the iterator of the loop. On Wed, Jan 29, 2014 at 8:08 PM, Thiago H de Paula Figueiredo thiag...@gmail.com wrote: On Wed, 29 Jan 2014 14:10:53 -0200, Dimitris Zenios dimitris.zen...@gmail.com wrote: Is it possible to make the loop component expose the iterator through a public method? There are situations where a mixin might want to use it. Which ones? Never needed it. -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
On Wed, 29 Jan 2014 16:17:49 -0200, Dimitris Zenios dimitris.zen...@gmail.com wrote: I have a list of 8 elements.I want to loop over the elements and every 3 elements or at beginning of list to Start with a div and end with a /div. Resulting output should be div item item item? /div div item item item /div div item item /div So i though i will create a mixin that attaches to the loop and adds those divs.I managed to almost make it work except one last case.After the last element i want to close my previous div even if the index is not % 3.In order to know that loop is in the last element i need the iterator of the loop. I'd use pure DOM rewriting instead. tapestry-xpath is extremely helpful for these situations. Don't expect the Tapestry team to expose implementation details: they don't like it. -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
What about something similar to varStatus in jsf? On Jan 29, 2014, at 2:01 PM, Thiago H de Paula Figueiredo thiag...@gmail.com wrote: On Wed, 29 Jan 2014 16:17:49 -0200, Dimitris Zenios dimitris.zen...@gmail.com wrote: I have a list of 8 elements.I want to loop over the elements and every 3 elements or at beginning of list to Start with a div and end with a /div. Resulting output should be div item item item? /div div item item item /div div item item /div So i though i will create a mixin that attaches to the loop and adds those divs.I managed to almost make it work except one last case.After the last element i want to close my previous div even if the index is not % 3.In order to know that loop is in the last element i need the iterator of the loop. I'd use pure DOM rewriting instead. tapestry-xpath is extremely helpful for these situations. Don't expect the Tapestry team to expose implementation details: they don't like it. -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
1.Passing the collection to the mixin and the component is one solution but i doesn'`t feel nice.I never had to pass the same parameter twice 2.Regarding render variables i don't see where these will help in my situation 3.Dom rewriting ( Javascript ? ) On Wed, Jan 29, 2014 at 9:10 PM, Ville Virtanen ville.virta...@orientimport.fi wrote: Hi, you can pass mixins parameters, so you could pass the original collection you're iterating over with the loop to the mixin also, and compare if the collection.size() == index http://tapestry.apache.org/component-mixins.html Look for Mixin Parameters. Ville -Alkuperäinen viesti- Lähettäjä: Thiago H de Paula Figueiredo [mailto:thiag...@gmail.com] Lähetetty: 29. tammikuuta 2014 21:02 Vastaanottaja: Tapestry development Aihe: Re: Loop and iterator On Wed, 29 Jan 2014 16:17:49 -0200, Dimitris Zenios dimitris.zen...@gmail.com wrote: I have a list of 8 elements.I want to loop over the elements and every 3 elements or at beginning of list to Start with a div and end with a /div. Resulting output should be div item item item? /div div item item item /div div item item /div So i though i will create a mixin that attaches to the loop and adds those divs.I managed to almost make it work except one last case.After the last element i want to close my previous div even if the index is not % 3.In order to know that loop is in the last element i need the iterator of the loop. I'd use pure DOM rewriting instead. tapestry-xpath is extremely helpful for these situations. Don't expect the Tapestry team to expose implementation details: they don't like it. -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
Yes but i cannot access the Iterator since is a private variable.Also the source parameter is declared as Iterable.I am not sure whether i am able to cast iterable to to List in order to get size.I think no On Wed, Jan 29, 2014 at 9:32 PM, Ville Virtanen ville.virta...@orientimport.fi wrote: Take a look at @BindParameter http://tapestry.apache.org/component-mixins.html -- Look for Binding the parameter of the core component You can access all component parameters in the mixin Ville Virtanen -Alkuperäinen viesti- Lähettäjä: Dimitris Zenios [mailto:dimitris.zen...@gmail.com] Lähetetty: 29. tammikuuta 2014 21:22 Vastaanottaja: Tapestry development Aihe: Re: Loop and iterator 1.Passing the collection to the mixin and the component is one solution but i doesn'`t feel nice.I never had to pass the same parameter twice 2.Regarding render variables i don't see where these will help in my situation 3.Dom rewriting ( Javascript ? ) On Wed, Jan 29, 2014 at 9:10 PM, Ville Virtanen ville.virta...@orientimport.fi wrote: Hi, you can pass mixins parameters, so you could pass the original collection you're iterating over with the loop to the mixin also, and compare if the collection.size() == index http://tapestry.apache.org/component-mixins.html Look for Mixin Parameters. Ville -Alkuperäinen viesti- Lähettäjä: Thiago H de Paula Figueiredo [mailto:thiag...@gmail.com] Lähetetty: 29. tammikuuta 2014 21:02 Vastaanottaja: Tapestry development Aihe: Re: Loop and iterator On Wed, 29 Jan 2014 16:17:49 -0200, Dimitris Zenios dimitris.zen...@gmail.com wrote: I have a list of 8 elements.I want to loop over the elements and every 3 elements or at beginning of list to Start with a div and end with a /div. Resulting output should be div item item item? /div div item item item /div div item item /div So i though i will create a mixin that attaches to the loop and adds those divs.I managed to almost make it work except one last case.After the last element i want to close my previous div even if the index is not % 3.In order to know that loop is in the last element i need the iterator of the loop. I'd use pure DOM rewriting instead. tapestry-xpath is extremely helpful for these situations. Don't expect the Tapestry team to expose implementation details: they don't like it. -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
I am not sure whether i will be able to cast to collection.Maybe tapestry is doing some magic with BindParameter. On Wed, Jan 29, 2014 at 9:47 PM, Ville Virtanen ville.virta...@orientimport.fi wrote: OK, got it. I thought the source param was collection. You always could (pseudocode) if (values instanceof Collection?) { return ((Collection?) source).size(); } else { it = source.iterator(); while (it.hasNext()) { it.next(); sum++; } return sum; } Ville -Alkuperäinen viesti- Lähettäjä: Dimitris Zenios [mailto:dimitris.zen...@gmail.com] Lähetetty: 29. tammikuuta 2014 21:38 Vastaanottaja: Tapestry development Aihe: Re: Loop and iterator Yes but i cannot access the Iterator since is a private variable.Also the source parameter is declared as Iterable.I am not sure whether i am able to cast iterable to to List in order to get size.I think no On Wed, Jan 29, 2014 at 9:32 PM, Ville Virtanen ville.virta...@orientimport.fi wrote: Take a look at @BindParameter http://tapestry.apache.org/component-mixins.html -- Look for Binding the parameter of the core component You can access all component parameters in the mixin Ville Virtanen -Alkuperäinen viesti- Lähettäjä: Dimitris Zenios [mailto:dimitris.zen...@gmail.com] Lähetetty: 29. tammikuuta 2014 21:22 Vastaanottaja: Tapestry development Aihe: Re: Loop and iterator 1.Passing the collection to the mixin and the component is one solution but i doesn'`t feel nice.I never had to pass the same parameter twice 2.Regarding render variables i don't see where these will help in my situation 3.Dom rewriting ( Javascript ? ) On Wed, Jan 29, 2014 at 9:10 PM, Ville Virtanen ville.virta...@orientimport.fi wrote: Hi, you can pass mixins parameters, so you could pass the original collection you're iterating over with the loop to the mixin also, and compare if the collection.size() == index http://tapestry.apache.org/component-mixins.html Look for Mixin Parameters. Ville -Alkuperäinen viesti- Lähettäjä: Thiago H de Paula Figueiredo [mailto:thiag...@gmail.com] Lähetetty: 29. tammikuuta 2014 21:02 Vastaanottaja: Tapestry development Aihe: Re: Loop and iterator On Wed, 29 Jan 2014 16:17:49 -0200, Dimitris Zenios dimitris.zen...@gmail.com wrote: I have a list of 8 elements.I want to loop over the elements and every 3 elements or at beginning of list to Start with a div and end with a /div. Resulting output should be div item item item? /div div item item item /div div item item /div So i though i will create a mixin that attaches to the loop and adds those divs.I managed to almost make it work except one last case.After the last element i want to close my previous div even if the index is not % 3.In order to know that loop is in the last element i need the iterator of the loop. I'd use pure DOM rewriting instead. tapestry-xpath is extremely helpful for these situations. Don't expect the Tapestry team to expose implementation details: they don't like it. -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
On Wed, 29 Jan 2014 17:07:13 -0200, Lenny Primak lpri...@hope.nyc.ny.us wrote: What about something similar to varStatus in jsf? No need for that. You already have the index and value parameters. -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
On Wed, 29 Jan 2014 17:58:08 -0200, Dimitris Zenios dimitris.zen...@gmail.com 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: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
On Wed, 29 Jan 2014 17:21:31 -0200, Dimitris Zenios dimitris.zen...@gmail.com wrote: 3.Dom rewriting ( Javascript ? ) Nope. Using void afterRender(MarkupWriter writer) in your mixin. writer.getDocument() returns the Tapestry Document object. You can manipulate its Elements any way you want. -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
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 lt;ligt; element: * * pre * lt;t:columns number=2gt; * lt;t:loop source=myList value=oneItemgt; * lt;ligt;lt;bgt;Name:lt;/bgt;{$oneItem.name}lt;/ligt; * lt;/t:loopgt; * lt;/t:columnsgt; * /pre * * But the following fails to lay out property, because there are two HTML * elements -- a span and a br -- per item: * * pre * lt;t:columns number=2gt; * lt;t:loop source=myList value=oneItemgt; * lt;spangt;${oneItem.name}lt;/spangt;lt;br /gt; * lt;/t:loopgt; * lt;/t:columnsgt; * /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 ListNode 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 thiag...@gmail.com wrote: On Wed, 29 Jan 2014 17:58:08 -0200, Dimitris Zenios dimitris.zen...@gmail.com 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: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
If you use that Columns component you'll also need some CSS: DIV.t-column { float: left; padding: 1em; } Or, you can use a different CSS class name (other than t-column) by passing the class name as a component parameter: t:columns number=3 columnClass=foo t:loop source=items value=item div${item.name}/div /t:loop /t:columns On Wed, Jan 29, 2014 at 4:57 PM, Bob Harner bobhar...@gmail.com wrote: 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 lt;ligt; element: * * pre * lt;t:columns number=2gt; * lt;t:loop source=myList value=oneItemgt; * lt;ligt;lt;bgt;Name:lt;/bgt;{$oneItem.name}lt;/ligt; * lt;/t:loopgt; * lt;/t:columnsgt; * /pre * * But the following fails to lay out property, because there are two HTML * elements -- a span and a br -- per item: * * pre * lt;t:columns number=2gt; * lt;t:loop source=myList value=oneItemgt; * lt;spangt;${oneItem.name}lt;/spangt;lt;br /gt; * lt;/t:loopgt; * lt;/t:columnsgt; * /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 ListNode 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 thiag...@gmail.com wrote: On Wed, 29 Jan 2014 17:58:08 -0200, Dimitris Zenios dimitris.zen...@gmail.com 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: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
Nice one Bob.I think these solves my problem On Thu, Jan 30, 2014 at 12:08 AM, Bob Harner bobhar...@gmail.com wrote: If you use that Columns component you'll also need some CSS: DIV.t-column { float: left; padding: 1em; } Or, you can use a different CSS class name (other than t-column) by passing the class name as a component parameter: t:columns number=3 columnClass=foo t:loop source=items value=item div${item.name}/div /t:loop /t:columns On Wed, Jan 29, 2014 at 4:57 PM, Bob Harner bobhar...@gmail.com wrote: 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 lt;ligt; element: * * pre * lt;t:columns number=2gt; * lt;t:loop source=myList value=oneItemgt; * lt;ligt;lt;bgt;Name:lt;/bgt;{$oneItem.name}lt;/ligt; * lt;/t:loopgt; * lt;/t:columnsgt; * /pre * * But the following fails to lay out property, because there are two HTML * elements -- a span and a br -- per item: * * pre * lt;t:columns number=2gt; * lt;t:loop source=myList value=oneItemgt; * lt;spangt;${oneItem.name}lt;/spangt;lt;br /gt; * lt;/t:loopgt; * lt;/t:columnsgt; * /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 ListNode 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 thiag...@gmail.com wrote: On Wed, 29 Jan 2014 17:58:08 -0200, Dimitris Zenios dimitris.zen...@gmail.com 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: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
Nice implementation! :) But shouldn't this be better writen a mixin? On Wed, 29 Jan 2014 19:57:19 -0200, Bob Harner bobhar...@gmail.com wrote: 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 lt;ligt; element: * * pre * lt;t:columns number=2gt; * lt;t:loop source=myList value=oneItemgt; * lt;ligt;lt;bgt;Name:lt;/bgt;{$oneItem.name}lt;/ligt; * lt;/t:loopgt; * lt;/t:columnsgt; * /pre * * But the following fails to lay out property, because there are two HTML * elements -- a span and a br -- per item: * * pre * lt;t:columns number=2gt; * lt;t:loop source=myList value=oneItemgt; * lt;spangt;${oneItem.name}lt;/spangt;lt;br /gt; * lt;/t:loopgt; * lt;/t:columnsgt; * /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 ListNode 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 thiag...@gmail.com wrote: On Wed, 29 Jan 2014 17:58:08 -0200, Dimitris Zenios dimitris.zen...@gmail.com 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: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org
Re: Loop and iterator
You mean as a mixin applied to the Loop component? I guess so, but I don't see how that would make it any better. t:loop source=items value=item t:mixins=Columns number=5 columnClass=foo div${item.name}/div /t:loop Although that is a tiny bit more compact, I don't think it is as clean, nor as general. Or maybe I misunderstand you. On Wed, Jan 29, 2014 at 8:15 PM, Thiago H de Paula Figueiredo thiag...@gmail.com wrote: Nice implementation! :) But shouldn't this be better writen a mixin? On Wed, 29 Jan 2014 19:57:19 -0200, Bob Harner bobhar...@gmail.com wrote: 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 lt;ligt; element: * * pre * lt;t:columns number=2gt; * lt;t:loop source=myList value=oneItemgt; * lt;ligt;lt;bgt;Name:lt;/bgt;{$oneItem.name}lt;/ligt; * lt;/t:loopgt; * lt;/t:columnsgt; * /pre * * But the following fails to lay out property, because there are two HTML * elements -- a span and a br -- per item: * * pre * lt;t:columns number=2gt; * lt;t:loop source=myList value=oneItemgt; * lt;spangt;${oneItem.name}lt;/spangt;lt;br /gt; * lt;/t:loopgt; * lt;/t:columnsgt; * /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 ListNode 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 thiag...@gmail.com wrote: On Wed, 29 Jan 2014 17:58:08 -0200, Dimitris Zenios dimitris.zen...@gmail.com 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: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org -- Thiago H. de Paula Figueiredo Tapestry, Java and Hibernate consultant and developer http://machina.com.br - To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org