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 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


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to