Re: Grid: multiple tr within grid row

2009-02-24 Thread Jonathan O'Connor

Jason,
I wanted to add onclick, onmouseover and onmouseout to the rows in my 
grid, and due to some timing issues with JavaScript enhancement (it 
could take 3-4 seconds before the JS was loaded after the browser 
displayed the HTML), I went with DOM rewriting. Here's a sample of my 
code. You can probably do the same, by adding tr elements to the DOM tree.


First, I wrote a little utility class that should be enhanced to 
something similar to the $$() Prototype method. My version just finds 
the first matching node.


package org.jonathan.t5web;

import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.dom.Node;
import org.apache.tapestry5.ioc.internal.util.Defense;

public class ElementFinder
{
private static interface Finder {
Node search(Node root);
}

private static class IdFinder implements Finder {
private String id;

public IdFinder(String id) {
this.id = id;
}

public Element search(Node root) {
return ((Element)root).getElementById( id );
}
}

private static class IndexFinder implements Finder {
private int index;

public IndexFinder(int index) {
this.index = index;
}

public Node search(Node root) {
return root.getChildren().get( index );
}
}

private static class TagFinder implements Finder {
private String tag;

public TagFinder(String tag) {
this.tag = tag;
}

public Element search(Node root) {
return ((Element)root).find( tag );
}
}

public Node find(String selector, Node rootElement) {
Defense.notBlank(selector, selector);
Defense.notNull( rootElement, rootElement );

String[] selectors = selector.split(   );
Node search = rootElement;
for (String s : selectors) {
Finder finder = parseSelector( s );
search = finder.search( search );
if (search == null) {
return null;
}
}
return search;
}

/**
 * Returns true if the selector is an id, e.g. #customerSearch
 * @param selector
 */
private boolean isIdSelector( String selector ) {
return selector.startsWith( # );
}

IdFinder buildIdFinder( String idSelector ) {
return new IdFinder(idSelector.substring( 1 ));
}

/**
 * Returns true if the selector is an id, e.g. #customerSearch
 * @param selector
 */
private boolean isIndexSelector( String selector ) {
return selector.startsWith( [ )  selector.endsWith( ] );
}

IndexFinder buildIndexFinder(String indexSelector) {
return new IndexFinder(Integer.parseInt( 
indexSelector.substring( 1, indexSelector.length() - 1 ) ));

}

Finder parseSelector(String selector) {
if (isIdSelector( selector )) {
return buildIdFinder( selector );
}

if (isIndexSelector( selector )) {
return buildIndexFinder( selector );
}

if (isTagSelector( selector )) {
return buildTagFinder( selector );
}

throw new IllegalArgumentException(selector +  is not an id, 
tag or index);

}

Finder buildTagFinder( String selector )
{
return new TagFinder( selector );
}

private boolean isTagSelector( String selector )
{
return !selector.startsWith( # )  !selector.startsWith( [ 
)  !selector.endsWith( ] );

}
}

Now, you need to provide an afterRender method to do the DOM rewriting:

void afterRender(MarkupWriter writer) {
Document doc = writer.getDocument();
if (doc == null) {
_logger.info( writer.getDocument( ) is null );
return;
}

ElementFinder finder = new ElementFinder();
Node tbody = finder.find( #customerTable tbody, 
doc.getRootElement() );

if (tbody == null) {
_logger.info( writer.getDocument( 
).getElementById(customerTable).find(tbody) is null );

return;
}
String prefixUrl = generateCustomerRowLinkEventUrlPrefix();
_rowIndex = 0;
for (Node node : tbody.getChildren()) {
Element tr = (Element)node;
Node custId = finder.find( [1] [0], tr );
tr.attribute( onclick, doCustomerTableRowClick(' + 
prefixUrl + custId.toString() + '); );
tr.attribute( onmouseover, this.className = 
'DataTableEntryMouseOver'; );
tr.attribute( onmouseout, this.className = ' + 
getRowClass() + ';);

_rowIndex++;
}
}

Hope this helps,
Jonathan
On 24/02/2009 01:40, Jason Tan wrote:

Hi,

I'd like to render multipletr  elements within the same grid row.
Searching this mailing list seems to come up with a combination of
subclassing Grid and GridRows (i.e.

Grid: multiple tr within grid row

2009-02-23 Thread Jason Tan
Hi,

I'd like to render multiple tr elements within the same grid row.
Searching this mailing list seems to come up with a combination of
subclassing Grid and GridRows (i.e.
http://tapestry.markmail.org/search/?q=override+gridrows#query:override%20gridrows+page:1+mid:ztjjoksxggnbkstv+state:results_)
-- was wondering if there was a more elegant way to do this?

Thanks,
Jason