in a Grid
Posted by Howard Lewis Ship <hl...@gmail.com>.
Remember that the Grid can sometimes only take you so far; if you look
at its implementation, you'll see that much of it is driven by
reusable sub-components.
I expect, in 5.2, to create an AbstractGrid that will be easier to
subclass and extend.
On Thu, Dec 3, 2009 at 3:44 AM, Thiago H. de Paula Figueiredo
<th...@gmail.com> wrote:
> Em Thu, 03 Dec 2009 07:41:57 -0200, Christian Riedel
> <ch...@gmx.net> escreveu:
>
>> Rewriting the generated DOM sounds so easy but... How can I accomplish
>> that?
>
> I'll copy here a slighlty modified mixin I've made that adds a select tag in
> each header column. It would be simplified if I used XPath, I guess.
> I hope it'll help you.
>
> @MixinAfter // this is very important.
> @IncludeJavaScriptLibrary("classpath:/deselectColumnOptions.js")
> public class ColumnSelect {
>
> @AfterRender
> void rewriteDOM(MarkupWriter writer) {
>
> Element element = writer.getElement();
>
> final Element table = firstChild("table", element);
> final Element thead = firstChild("thead", table);
> final Element th = thead.find("tr");
> final List<Element> headerCells = childElements(th);
>
> for (Element headerCell : headerCells) {
> addColumnField(headerCell);
> }
> ...
>
> }
>
>
> private List<Element> childElements(Element element) {
>
> List<Element> elements = new ArrayList<Element>();
>
> for (Node node : element.getChildren()) {
>
> if (node instanceof Element) {
> elements.add((Element) node);
> }
>
> }
>
> return elements;
>
> }
>
> private Element firstChild(String tag, Element element) {
>
> Element firstChild = null;
>
> List<Element> children = childElements(element);
>
> for (Element child : children) {
>
> if (child.getName().equals(tag)) {
> firstChild = child;
> }
> else {
> firstChild = firstChild(tag, child);
> }
>
> if (firstChild != null) {
> break;
> }
>
> }
>
> return firstChild;
>
> }
>
> private Element firstChild(String tag, String className, Element
> element) {
>
> Element firstChild = null;
>
> List<Element> children = childElements(element);
>
> for (Element child : children) {
>
> if (child.getName().equals(tag) &&
> child.getAttribute("class").contains(className)) {
> firstChild = child;
> }
> else {
> firstChild = firstChild(tag, child);
> }
>
> if (firstChild != null) {
> break;
> }
>
> }
>
> return firstChild;
>
> }
>
> }
>
>> <t:grid ... t:mixins="GridFooter" >
>> <p:foot>
>> <tr><td>my footer</td></tr>
>> </p:foot>
>> </t:grid>
>> First problem was to get a <tfoot> tag rendered around the block "foot"
>> that I specified as a parameter for the mixin. I tried several things, but I
>> think I need a little help here.
>
> I don't know if you can get block parameters in mixins. If not, you cannot
> use <p:foot> in your template. You'd need to add the footer programatically.
>
> Your mixin and your methods should be @AfterRender.
>
>> Instead of the desired markup this will render <tfoot></tfoot> followed by
>> the contents of the "foot"-block although the render methods are called in
>> the right order. I cannot end <tfoot> in the afterRender method because it
>> would wrap around the whole t5-grid, and moving it in the dom would be even
>> more difficult. So how can I wrap some markup around a block?
>
> Use the Element methods do to that.
>
>> Second, I didn't make it to get the table element of the grid. I hope
>> afterRender is the right place for that.
>
> I think that the best way to understand a DOM-rewriting mixin is that it
> always works after the component is rendered completely.
>
>> I don't know if that xpath command would work if I'd find the gridElement
>> in the first place, but apart from that it should work like that, right? How
>> can I get the gridElement?
>
> If your mixin works after the grid is rendered, the current element
> (markupWriter.getElement()) is the parent element of the grid.
>
>> The autocompleter mixin and some others I've seen are injecting their
>> containers (@InjectContainer ... someField) and calling
>> someField.getClientId, which would maybe a solution if grid contained a
>> getClientId method...
>
> You would only need that if you needed to hook some JavaScript to the grid.
>
> --
> Thiago H. de Paula Figueiredo
> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and
> instructor
> Owner, software architect and developer, Ars Machina Tecnologia da
> Informação Ltda.
> http://www.arsmachina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>
--
Howard M. Lewis Ship
Creator of Apache Tapestry
The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!
(971) 678-5210
http://howardlewisship.com
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: How to insert in a Grid
Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Em Thu, 03 Dec 2009 07:41:57 -0200, Christian Riedel
<ch...@gmx.net> escreveu:
> Rewriting the generated DOM sounds so easy but... How can I accomplish
> that?
I'll copy here a slighlty modified mixin I've made that adds a select tag
in each header column. It would be simplified if I used XPath, I guess.
I hope it'll help you.
@MixinAfter // this is very important.
@IncludeJavaScriptLibrary("classpath:/deselectColumnOptions.js")
public class ColumnSelect {
@AfterRender
void rewriteDOM(MarkupWriter writer) {
Element element = writer.getElement();
final Element table = firstChild("table", element);
final Element thead = firstChild("thead", table);
final Element th = thead.find("tr");
final List<Element> headerCells = childElements(th);
for (Element headerCell : headerCells) {
addColumnField(headerCell);
}
...
}
private List<Element> childElements(Element element) {
List<Element> elements = new ArrayList<Element>();
for (Node node : element.getChildren()) {
if (node instanceof Element) {
elements.add((Element) node);
}
}
return elements;
}
private Element firstChild(String tag, Element element) {
Element firstChild = null;
List<Element> children = childElements(element);
for (Element child : children) {
if (child.getName().equals(tag)) {
firstChild = child;
}
else {
firstChild = firstChild(tag, child);
}
if (firstChild != null) {
break;
}
}
return firstChild;
}
private Element firstChild(String tag, String className, Element element)
{
Element firstChild = null;
List<Element> children = childElements(element);
for (Element child : children) {
if (child.getName().equals(tag) &&
child.getAttribute("class").contains(className)) {
firstChild = child;
}
else {
firstChild = firstChild(tag, child);
}
if (firstChild != null) {
break;
}
}
return firstChild;
}
}
> <t:grid ... t:mixins="GridFooter" >
> <p:foot>
> <tr><td>my footer</td></tr>
> </p:foot>
> </t:grid>
> First problem was to get a <tfoot> tag rendered around the block "foot"
> that I specified as a parameter for the mixin. I tried several things,
> but I think I need a little help here.
I don't know if you can get block parameters in mixins. If not, you cannot
use <p:foot> in your template. You'd need to add the footer
programatically.
Your mixin and your methods should be @AfterRender.
> Instead of the desired markup this will render <tfoot></tfoot> followed
> by the contents of the "foot"-block although the render methods are
> called in the right order. I cannot end <tfoot> in the afterRender
> method because it would wrap around the whole t5-grid, and moving it in
> the dom would be even more difficult. So how can I wrap some markup
> around a block?
Use the Element methods do to that.
> Second, I didn't make it to get the table element of the grid. I hope
> afterRender is the right place for that.
I think that the best way to understand a DOM-rewriting mixin is that it
always works after the component is rendered completely.
> I don't know if that xpath command would work if I'd find the
> gridElement in the first place, but apart from that it should work like
> that, right? How can I get the gridElement?
If your mixin works after the grid is rendered, the current element
(markupWriter.getElement()) is the parent element of the grid.
> The autocompleter mixin and some others I've seen are injecting their
> containers (@InjectContainer ... someField) and calling
> someField.getClientId, which would maybe a solution if grid contained a
> getClientId method...
You would only need that if you needed to hook some JavaScript to the grid.
--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,
and instructor
Owner, software architect and developer, Ars Machina Tecnologia da
Informação Ltda.
http://www.arsmachina.com.br
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: How to insert in a Grid
Posted by Christian Riedel <ch...@gmx.net>.
Rewriting the generated DOM sounds so easy but... How can I accomplish that?
I'm facing some problems with that approach...
I tried to make that dummy-code working:
.tml
<t:grid ... t:mixins="GridFooter" >
<p:foot>
<tr><td>my footer</td></tr>
</p:foot>
</t:grid>
First problem was to get a <tfoot> tag rendered around the block "foot"
that I specified as a parameter for the mixin. I tried several things,
but I think I need a little help here.
This is not working, but shows how I'd like to do it:
@Parameter(name = "foot", defaultPrefix = BindingConstants.LITERAL)
private Block foot;
private Element tfoot, table;
@BeginRender
void renderBegin(MarkupWriter writer) {
tfoot = writer.element("tfoot");
}
@BeginRender
Object renderFoot(MarkupWriter writer) {
return foot;
}
@BeginRender
void renderTagEnd(MarkupWriter writer) {
writer.end(); // end tfoot
}
Instead of the desired markup this will render <tfoot></tfoot> followed
by the contents of the "foot"-block although the render methods are
called in the right order. I cannot end <tfoot> in the afterRender
method because it would wrap around the whole t5-grid, and moving it in
the dom would be even more difficult. So how can I wrap some markup
around a block?
Second, I didn't make it to get the table element of the grid. I hope
afterRender is the right place for that.
void afterRender(MarkupWriter writer) {
Element gridElement = ... // that should point to grid's
sorrounding div
table = gridElement.find("./div/table");
tfoot.moveToBottom(table);
}
I don't know if that xpath command would work if I'd find the
gridElement in the first place, but apart from that it should work like
that, right? How can I get the gridElement?
The autocompleter mixin and some others I've seen are injecting their
containers (@InjectContainer ... someField) and calling
someField.getClientId, which would maybe a solution if grid contained a
getClientId method...
I'm open for any ideas :)
Thanks so far,
Christian
Thiago H. de Paula Figueiredo schrieb:
> Em Wed, 02 Dec 2009 15:41:12 -0200, Christian Riedel
> <ch...@gmx.net> escreveu:
>
>> Hi,
>
> Hi!
>
>> I'd like to put a <tfoot> tag inside my table, but it seems the
>> Tapestry Grid component is not able to do that... or can somebody
>> point out a solution?
>
> You can write a mixin that rewrites the generated DOM and adds the tag
> you want. Take a look at the Autocomplete mixin source to have an idea.
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: How to insert in a Grid
Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Em Wed, 02 Dec 2009 15:41:12 -0200, Christian Riedel
<ch...@gmx.net> escreveu:
> Hi,
Hi!
> I'd like to put a <tfoot> tag inside my table, but it seems the Tapestry
> Grid component is not able to do that... or can somebody point out a
> solution?
You can write a mixin that rewrites the generated DOM and adds the tag you
want. Take a look at the Autocomplete mixin source to have an idea.
--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,
and instructor
Owner, software architect and developer, Ars Machina Tecnologia da
Informação Ltda.
http://www.arsmachina.com.br
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org