Hi,

I did a Gallery for T4... it ran beautiful

currently porting it to T5... fun fun fun

I wouldn't say its a trivial task... but a nice learning experience if you want 
to come out with some handy tapestry skill.

I should be done with my T5 version in the coming weeks after I soup it up.

- cheers

Ken

----------------- cut here -----------------

Here is the Home.html template demonstrating its usage
<span jwcid="border@Border">

    <h1>
        <div id="page.title">
            <span jwcid="@Insert" value="Listings"/>
        </div>
    </h1>

    <form jwcid="galleryForm@Form" listener="listener:galleryFormSubmit">
        <div jwcid="galleryWidget@custom:Gallery"
            collectionType="ognl:@org.trails.demo.Listing@class"
            itemsPerPage="ognl:itemsPerPage"
            tableColumns="ognl:tableColumns"
            cursor="ognl:cursor"
            >

            <span jwcid="@RenderBody">content goes here</span>
        </div>
    </form>


<span jwcid="@Script" script="/org/trails/demo/components/Gallery.script"
    component = "ognl:components.galleryWidget"
    itemsPerPage = "ognl:components.galleryWidget.itemsPerPage"
    tableColumns = "ognl:components.galleryWidget.tableColumns"
    itemCount="ognl:components.galleryWidget.collection.size"
    cursor="ognl:cursor"
    />
    


</span>


Here is the template 
Gallery.HTML
 <!-- 
     * CAUTION: This component is sanctioned by heaven. 
     *   The following agreement is binding upon use
     *   
     * AGREEMENT: Usage of this component is limited to academic and clean 
business.
     *   Under no circumstances is this component to be used for gender 
business or 
     *   to render criminal & lude material. Should you decide to violate the 
terms 
     *   of this agreement and abuse the use of this component, you will be 
held 
     *   accountable, at your feet, right where you stand. 
     
// -- 
// -- http://developer.mozilla.org/En/DOM/Element.offsetTop
// -- http://developer.mozilla.org/En/DOM/Element.offsetLeft
// -- http://developer.mozilla.org/En/DOM/Element.offsetWidth
// -- http://developer.mozilla.org/En/DOM/Element.offsetHeight
// --
// -- Lessons Learned
// --     dom.offsetWidth  - the components far right X coordinate after render
// --     dom.offsetHeight - the components far right Y coordinate after render
// --     dom.offsetTop    - the components Y coordinate after render
// --     dom.offsetLeft   - the components X coordinate after render
// --   dom.offsetparent - reference to nearest in the containment hierarchy
// --  
// -- Sample Methods
// -- function findPosX(obj) {    
// --     var curLeft = 0;    
// --     
// --     do {        
// --         curLeft += obj.offsetLeft;    
// --     } while ( obj = obj.offsetParent );
// --     return curLeft;
// -- }
// -- 
// -- function findPosY(obj) {    
// --     var curTop = 0;    
// --     do {        
// --         curTop += obj.offsetTop;    
// --     } while ( obj = obj.offsetParent );
// --     return curTop;
// -- }
// -- 
// -- function findPos(obj) {
// --     return { x : findPosX(obj), y : findPosY(obj) };
// -- }     
     
 -->

<span jwcid="$content$">
    <span jwcid="autoPagingContent@Block">
        <table width="100%" border=0>
            <tr>
                <td width="25%" align="left" NOWRAP>
                    <span jwcid="@Insert" value="Items Per Page"/>
                    <select jwcid="itemsPerPageSelect@PropertySelection"
                        model="ognl:itemsPerPageModel"
                        value="ognl:itemsPerPage"
                        defaultValue="ognl:9"
                        onchange="tapestry.form.refresh(this.form)"
                        />
                    <span jwcid="@Insert" value="Table Columns"/>
                    <select jwcid="tableColumnsSelect@PropertySelection"
                        model="ognl:tableColumnsModel"
                        value="ognl:tableColumns"
                        defaultValue="ognl:3"
                        onchange="tapestry.form.refresh(this.form)"
                        />
                </td>            
                <td colspan=2>
                    <div style="font-weight:bold; text-align: center;">
                        <span jwcid="@Insert" value=""/>        
                        
                        <!-- 
                        <span jwcid="@If" condition="ognl:(cursor == 0)">    
                            <span jwcid="@Insert" value="ognl:1"/>
                        </span>
                        <span jwcid="@Else">
                            <span jwcid="@Insert" value="ognl:(cursor + 1)"/>
                        </span>                        
                        -->
                        <span jwcid="@Insert" value="ognl:(cursor + 1)"/>
                        
                        <span jwcid="@Insert" value=" to "/>
                        
                        <span jwcid="@If" condition="ognl:(cursor == 0)">    
                            <span jwcid="@Insert" value="ognl:(cursor + 
@java.lang.Math@min(collection.size,itemsPerPage) )"/>
                        </span>        
                        <span jwcid="@Else">
                            <span jwcid="@Insert" value="ognl:(cursor + 
@java.lang.Math@min(collection.size,itemsPerPage) )"/>
                        </span>                            
                        
                        <span jwcid="@Insert" value=" of "/>
                        <span jwcid="@Insert" value="ognl:collection.size"/>
                        <span jwcid="@Insert" value=""/>
                    </div>
                </td>
            </tr>
            <tr>
                <td align="left" NOWRAP colspan=2>
                    <div style="font-size:10pt; text-align: center;">
                        <a jwcid="onFirstPage@DirectLink" 
listener="listener:onFirstPage"> <span jwcid="@Insert" value="  <<  "/> </a>
                        <a jwcid="onPrevPage@DirectLink" 
listener="listener:onPrevPage">     <span jwcid="@Insert" value="  <    "/> </a>
                        
                        <span jwcid="foreachpage@For" source="ognl:pages" 
value="ognl:currentPage" index="ognl:pageIndex">
                                <a jwcid="@DirectLink" 
                                    listener="listener:onPage" 
                                    parameters="ognl:(pageIndex + 1)"> 
                                        <span jwcid="@Insert" 
value="ognl:(pageIndex + 2)"/> </a>
                        </span>
                        
                        <a jwcid="onNextPage@DirectLink" 
listener="listener:onNextPage">     <span jwcid="@Insert" value="    >  "/>  
</a>
                        <a jwcid="onLastPage@DirectLink" 
listener="listener:onLastPage">     <span jwcid="@Insert" value="  >>  "/> </a>
                    </div>
                </td>            
            </tr>
        </table>
    </span>

    <span jwcid="collectionContent@Block" style="background: 
url(images/bkgd.jpg); margin:10; padding:10;"    >
        <table width="100%">
            <tr>
                <span jwcid="foreachitem@For" source="ognl:collection" 
value="ognl:currentObject" index="ognl:index">
                    <span jwcid="@If" condition="ognl:okToRenderItem">
                        
                        <span jwcid="@If" condition="ognl:( 
@java.lang.Math@min(tableColumns, itemsPerPage) )">
                            <span jwcid="@If" condition="ognl:((index - cursor) 
% @java.lang.Math@min(tableColumns, itemsPerPage) ) == 0">
                                <span jwcid="@Insert" value="</tr><tr>" 
raw="true"/>
                            </span>
                        </span>
    
                        <td>
                            <!--
                            <a jwcid="editLinkElse@LinkSubmit" 
listener="listener:view" parameters="ognl:currentObject">
                                <div jwcid="image@Any">
                                    <img 
jwcid="imageWidget@TransparentTextImage"
                                         model="ognl:currentObject"
                                         image="ognl:photoAsset"
                                         alt="ognl:currentObject.photo.fileName"
                                         
title="ognl:currentObject.photo.fileName" 
                                         width="160" height="120"               
          
                                     />
                                </div>                             
                            </a>
                            -->

                            <a jwcid="@trails:EditLink" href="#" 
                                            model="ognl:currentObject">
<!--
                                
                            <a jwcid="editLinkElse@LinkSubmit" 
listener="listener:view" parameters="ognl:currentObject"
                                    >
-->                                        
                                <span jwcid="@Any" 
                                                 
                                                id="ognl:imageComponentId" >
                                    <img 
jwcid="imageWidget@TransparentTextImage" 
id="ognl:transparentTextImageComponentId"
                                             model="ognl:currentObject"
                                             image="ognl:photoAsset"
                                             
alt="ognl:currentObject.photo.fileName"
                                             
title="ognl:currentObject.photo.fileName" 
                                             width="200" height="160"           
              
                                             
                                             
topLeftText="ognl:currentObject.transparentText"
                                             topRightText="topRightText"
                                             bottomLeftText="bottomleft"
                                             bottomRightText="bottomright"
                                             centerText="center"
                                         />

                                </span>
                            </a>
                            
                        </td>        

        
                        <span jwcid="@Script" 
script="/org/trails/demo/components/TransparentTextImage.script"
                            topLeftText = "ognl:currentObject.transparentText"
                            index = "ognl:index">
                        </span>    
                        
                    </span>
                </span>    <!-- for loop -->
            </tr>
        </table>        
    </span>    

    <div jwcid="headerSelect@Any">
        <div jwcid="@RenderBlock" block="ognl:components.autoPagingContent" />
    </div>
    <div jwcid="galleryContent@Any">
        <div jwcid="@RenderBlock" block="ognl:components.collectionContent" />
    </div>
</span>


Gallery.JAVA
package org.trails.demo.components;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tapestry.IAsset;
import org.apache.tapestry.IPage;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.annotations.ComponentClass;
import org.apache.tapestry.annotations.EventListener;
import org.apache.tapestry.annotations.InjectObject;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.form.IPropertySelectionModel;
import org.apache.tapestry.web.WebRequest;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.dao.DataAccessException;
import org.trails.component.TrailsComponent;
import org.trails.component.blob.BlobDownloadService;
import org.trails.component.blob.TrailsBlobAsset;
import org.trails.demo.Listing;
import org.trails.descriptor.DescriptorService;
import org.trails.descriptor.IClassDescriptor;
import org.trails.descriptor.IPropertyDescriptor;
import org.trails.page.PageResolver;
import org.trails.persistence.HibernatePersistenceService;
import org.trails.persistence.PersistenceService;
import org.trails.util.IntegerPropertySelectionModel;

/**
 * This guy (tapestry/dojo/json/script oriented widget) renders a gallery.
 * 
 * 
 * CAUTION: This component is sanctioned by heaven. The following agreement is
 * binding upon use
 * 
 * AGREEMENT: Usage of this component is limited to academic and clean business.
 * Under no circumstances is this component to be used for gender business or to
 * render criminal/obscene & lude material. Should you decide to violate the
 * terms of this agreement and abuse the use of this component, you will be held
 * accountable, at your feet, right where you stand. You were warned.
 * 
 * Script is facilitated to operate/persist auto-paging variables.
 * 
 * @author kenneth.colassi nhhockeypla...@hotmail.com
 * 
 */
@ComponentClass(allowBody = true, allowInformalParameters = true)
public abstract class Gallery extends TrailsComponent {
    private static final Log LOG = LogFactory.getLog(Gallery.class);

    private static final Integer[] itemsPerPageIntegerOptions = new Integer[] {
            new Integer("5"), new Integer("10"), new Integer("15"),
            new Integer("25"), new Integer("50"), new Integer("100"),
            new Integer("500"), new Integer("1000"), new Integer("2500"),
            new Integer("5000"), new Integer("10000"), new Integer("25000"),
            new Integer("50000") };

    private static final Integer[] tableColumnsIntegerOptions = new Integer[] {
            new Integer("1"), new Integer("2"), new Integer("3"),
            new Integer("4"), new Integer("5"), new Integer("6"),
            new Integer("7"), new Integer("8"), new Integer("9"),
            new Integer("10"), new Integer("11"), new Integer("12"),
            new Integer("13"), new Integer("14"), new Integer("15"),
            new Integer("25"), new Integer("50"), new Integer("100")};

    private IPropertySelectionModel itemsPerPageModel = null;

    private IPropertySelectionModel tableColumnsModel = null;

    private Collection collection = null;

    /**
     * E-Frastructure and Services
     */
    @InjectObject("service:tapestry.globals.ServletContext")
    public abstract ServletContext getServletContext();

    @InjectObject("service:tapestry.globals.WebRequest")
    public abstract WebRequest getWebRequest();

    @InjectObject("service:trails.core.PageResolver")
    public abstract PageResolver getPageResolver();

    @InjectObject("service:trails.core.DescriptorService")
    public abstract DescriptorService getDescriptorService();

    @InjectObject("service:trails.core.PersistenceService")
    public abstract PersistenceService getPersistenceService();

    @InjectObject("service:trails.hibernate.PersistenceService")
    public abstract HibernatePersistenceService 
getHibernatePersistenceService();

    @InjectObject("service:trails.core.BlobService")
    public abstract BlobDownloadService getDownloadService();

    @Parameter(required = true)
    public abstract Class getCollectionType();

    public abstract void setCollectionType(Class collectionType);

    /**
     * PropertySelection Support
     */
    @Parameter(required = false, cache = false, defaultValue = "ognl:50")
    public abstract Integer getItemsPerPage();

    public abstract void setItemsPerPage(Integer itemsPerPage);

    @Parameter(required = false, cache = false, defaultValue = "ognl:3")
    public abstract Integer getTableColumns();

    public abstract void setTableColumns(Integer tableColumns);

    @Parameter(required = false, cache = true, defaultValue = "ognl:0")
    public abstract int getCursor();

    public abstract void setCursor(int cursor);

    protected void finishLoad() {
        super.finishLoad();
    }

    /**
     * FOR component Collection Iterator support
     */
    @Parameter(required = false)
    public abstract int getStartRow();

    public abstract void setStartRow(int startRow);

    public abstract Object getCurrentObject();

    public abstract void setCurrentObject(Object CurrentObject);

    public abstract int getIndex();

    public abstract void setIndex(int index);

    public abstract int getPageIndex();

    public abstract void setPageIndex(int pageIndex);

    public abstract Object getCurrentPage();

    public abstract void setCurrentPage(Object CurrentPage);

    /**
     * Typically injected via jwc - readonly, yes that means no setter
     */
    // @InjectScript("Gallery.script")
    // public abstract IScript getScript();

    public Collection getCollection() {
        return collection;
    }

    public void setCollection(Collection collection) {
        this.collection = collection;
    }

    public Collection loadCollection(Class collectionClass)
            throws DataAccessException {
        DetachedCriteria criteria = DetachedCriteria.forClass(collectionClass);
        // criteria.add(Restrictions.eq("id", 1));
        return getHibernatePersistenceService().getInstances(collectionClass,
                criteria);
    }

    public IPropertySelectionModel getItemsPerPageModel() {
        if (itemsPerPageModel == null) {
            itemsPerPageModel = new IntegerPropertySelectionModel(
                    itemsPerPageIntegerOptions);
        }

        return itemsPerPageModel;
    }

    public IPropertySelectionModel getTableColumnsModel() {
        if (tableColumnsModel == null) {
            tableColumnsModel = new IntegerPropertySelectionModel(
                    tableColumnsIntegerOptions);
        }

        return tableColumnsModel;
    }

    @Override
    protected void prepareForRender(IRequestCycle cycle) {
        super.prepareForRender(cycle);

        setCollection(loadCollection(getCollectionType()));
    }

    public IPropertyDescriptor findPropertyDescriptor(Class clazz,
            String propertyName) {
        IClassDescriptor acd = getDescriptorService().getClassDescriptor(clazz);

        for (IPropertyDescriptor pd : acd.getPropertyDescriptors()) {
            if (pd.getName().equalsIgnoreCase(propertyName))
                return pd;
        }
        return null;
    }

    public IAsset getPhotoAsset() {
        IPropertyDescriptor propertyDescriptor = findPropertyDescriptor(
                Listing.class, "photo");

        Serializable pk = getPersistenceService().getIdentifier(
                getCurrentObject(),
                getDescriptorService().getClassDescriptor(
                        propertyDescriptor.getBeanType()));

        Listing listing = (Listing) getCurrentObject();
        String contentType = listing.getPhoto().getContentType();
        String fileName = listing.getPhoto().getFileName();
        String filePath = listing.getPhoto().getFilePath();
        return new TrailsBlobAsset(getDownloadService(), propertyDescriptor, pk
                .toString(), contentType, fileName, filePath);
    }

    @EventListener(events = { "onchange" }, targets = { "itemsPerPageSelect" }, 
submitForm = "galleryForm", async = true)
    public void itemsPerPageChangeListener(IRequestCycle cycle) {
        // (events="onchange") Just keep all of your event names in lowercase
        // and you'll be ok. - jesse kunhert
        LOG.info("In itemsPerPageChangeListener : ");

        if (getItemsPerPage() < getTableColumns()) {
            setTableColumns(getItemsPerPage());
            // cycle.getResponseBuilder().updateComponent("tableColumnsSelect");
            cycle.getResponseBuilder().updateComponent(
                    getComponent("tableColumnsSelect").getClientId());
            // cycle.commitPageChanges();
            // try {
            // cycle.getResponseBuilder().flush();
            // } catch (IOException exc) {
            // }
        } else {
            /**
             * Use case, items is larger than columns, need to back cursor off
             * if in endzone
             */
            int i = getCursor() + getItemsPerPage();
            while (i > (collection.size() - Math.min(collection.size(),
                    getItemsPerPage() + getTableColumns()))) {
                i--;
            }
            setCursor(i);
        }
    }

    @EventListener(events = { "onchange" }, targets = { "tableColumnsSelect" }, 
submitForm = "galleryForm", async = true)
    public void tableColumnsChangeListener(IRequestCycle cycle) {
        // (events="onchange") Just keep all of your event names in lowercase
        // and you'll be ok. - jesse kunhert
        LOG.info("In tableColumnsChangeListener : ");
        itemsPerPageChangeListener(cycle);
    }

    public IPage galleryFormSubmit(IRequestCycle cycle) {
        IPage galleryPage = cycle.getPage();

        LOG.info("In galleryFormSubmit : ");

        return galleryPage;
    }

    public IPage onFirstPage(IRequestCycle cycle) {
        IPage galleryPage = cycle.getPage();

        LOG.info("In onFirstPage : ");

        setCursor(0);

        return galleryPage;
    }

    public IPage onPrevPage(IRequestCycle cycle) {
        IPage galleryPage = cycle.getPage();

        LOG.info("In onPrevPage : ");

        /**
         * Use Cases:
         * 
         * Check for setting to - and set to 0
         * 
         * else , set back a page
         */
        setCursor(getCursor() - Math.min(getItemsPerPage(), collection.size()) 
< 0 ? 0
                : getCursor() - Math.min(getItemsPerPage(), collection.size()));

        return galleryPage;
    }

    /**
     * This guy is not getting called. ?
     * 
     * @param number
     * @param cycle
     * @return
     */
    public IPage onPage(Integer number, IRequestCycle cycle) {
        IPage galleryPage = cycle.getPage();

        LOG.info("In onPage : ");

        setCursor(number.intValue() * getItemsPerPage());

        return galleryPage;
    }

    public IPage onNextPage(IRequestCycle cycle) {
        IPage galleryPage = cycle.getPage();

        LOG.info("In onNextPage : ");

        /**
         * If we're already in the endzone, set it to last batch,
         * 
         * If our next action places us into the endzone, set it to last batch
         * 
         * else just increment by a new page
         */
        setCursor(getCursor() > (getCollection().size() - Math.min(
                getItemsPerPage(), collection.size())) ? (collection.size() - 
Math
                .min(getItemsPerPage(), collection.size()))
                : ((getCursor() + Math
                        .min(getItemsPerPage(), collection.size())) > 
(getCollection()
                        .size() - Math
                        .min(getItemsPerPage(), collection.size())) ? collection
                        .size()
                        - Math.min(getItemsPerPage(), collection.size())
                        : getCursor()
                                + Math
                                        .min(getItemsPerPage(), collection
                                                .size())));

        return galleryPage;
    }

    public IPage onLastPage(IRequestCycle cycle) {
        IPage galleryPage = cycle.getPage();

        LOG.info("In onLastPage : ");

        setCursor(collection.size()
                - Math.min(getItemsPerPage(), collection.size()));

        return galleryPage;
    }

    public boolean okToRenderItem() {
        boolean result = false;

        if (getIndex() >= getCursor()
                && getIndex() < (getCursor() + Math.min(collection.size(),
                        getItemsPerPage())))
            result = true;
        return result;
    }

    public void view(IRequestCycle cycle) {
        /*
         * EditPage ownerEditPage = (EditPage)
         * getPageResolver().resolvePage(cycle, getCurrentObject().getClass(),
         * PageType.Edit);
         * 
         * EditCallback callback = new EditCallback(ownerEditPage.getPageName(),
         * getCurrentObject()); getCallbackStack().push(callback);
         * 
         * try { EditCallback nextPage = new
         * EditCallback(ownerEditPage.getPageName(), getCurrentObject ());
         * //String currentEditPageName =
         * getPage().getRequestCycle().getPage().getPageName();
         * 
         * //EditPage ePage = (EditPage) cycle.getPage(currentEditPageName);
         * //ePage.setNextPage(nextPage); nextPage.performCallback(cycle); }
         * catch (Exception ex) { throw new TrailsRuntimeException(ex,
         * getCurrentObject().getClass()); }
         */
    }

    public Collection getPages() {
        Collection numPages = new ArrayList();
        for (int i = 1; i < (collection.size() / getItemsPerPage() - 1); i++)
            numPages.add(new Integer(i));

        return numPages;
    }

    /*
     * public IPage edit(IRequestCycle cycle) {
     * getCallbackStack().push(buildCallback());
     * 
     * String currentEditPageName =
     * getPage().getRequestCycle().getPage().getPageName(); EditPage
     * ownerEditPage = (EditPage) getPageResolver().resolvePage(cycle,
     * getDescriptor().getClass(), PageType.Edit);
     * 
     * try { Object newModel = buildNewMemberInstance(); EditCallback nextPage =
     * new EditCallback(ownerEditPage.getPageName(), newModel);
     * 
     * ((EditPage) cycle.getPage(currentEditPageName)).setNextPage(nextPage);
     * nextPage.performCallback(cycle); } catch (Exception ex) { throw new
     * TrailsRuntimeException(ex, getDescriptor().getClass().getClass()); } }
     * 
     * EditCallback buildCallback() { EditCallback callback = new
     * EditCallback(getPage().getRequestCycle().getPage().getPageName(),
     * getModel(), getDescriptor()); return callback; }
     * 
     * protected Object buildNewMemberInstance() throws InstantiationException,
     * IllegalAccessException { Object associationModel; if
     * (getCreateExpression() == null) { associationModel =
     * getDescriptor().getPropertyType().newInstance(); } else { try {
     * associationModel = Ognl.getValue(getCreateExpression(), getOwner()); }
     * catch (OgnlException oe) { oe.printStackTrace(); return null; } }
     * 
     * if (getOwningObjectReferenceDescriptor() != null &&
     * getOwningObjectReferenceDescriptor().getInverseProperty() != null) { try
     * {
     * Ognl.setValue(getOwningObjectReferenceDescriptor().getInverseProperty(),
     * associationModel, getOwner()); } catch (OgnlException e) {
     * LOG.error(e.getMessage()); } }
     * 
     * return associationModel; }
     */
    /*
     * @Component(id = "imageWidget", type = "TransparentTextImage", bindings =
     * { "model=ognl:currentObject", "image=ognl:photoAsset",
     * "alt=ognl:currentObject.photo.fileName",
     * "title=ognl:currentObject.photo.fileName", "width=160", "height=110",
     * "transparentText=literal:hello world" }) public abstract
     * TransparentTextImage getImageWidget();
     */

    public String getImageComponentId() {
        return "Image_" + new Integer(getIndex()).toString();
    }

    public String getTransparentTextImageComponentId() {
        return "ImageWidget_" + new Integer(getIndex()).toString();
    }
}

                                          

Reply via email to