这是T3版本下Table组件的使用例程。代码是国外大师级人物所写,现在把源代码整理出来:

如下图所示建立工程:

所需jar包一览如下:

bsf-2.3.0.jar
commons-beanutils-1.6.1.jar
commons-codec-1.2.jar
commons-collections-2.1.jar
commons-digester-1.5.jar
commons-fileupload-1.0.jar
commons-lang-1.0.jar
commons-logging-1.0.2.jar
jakarta-oro-2.0.6.jar
javassist-2.5.1.jar
ognl-2.6.3.jar
tapestry-3.0.1.jar
tapestry-contrib-3.0.1.jar

 

代码如下:

BirthDateComparator.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package datasource;
  9. import java.util.Comparator;
  10. /**
  11.  * This is a very hokey and error prone comparator cobbled together
  12.  * to demonstrate a point.  Don't use this in production.
  13.  */
  14. public class BirthDateComparator implements Comparator 
  15. {
  16.     // This comparator is designed to compare two
  17.     // MM/DD/YYYY formatted Strings
  18.     public int compare(Object o1, Object o2)
  19.     {
  20.         // return -1 if o1 < o2
  21.         // return 0 if o1 == o2
  22.         // return 1 if o1 > o2
  23.         String month1 = "01";
  24.         String day1 = "01";
  25.         String year1 = "1900";
  26.         if (o1 instanceof String) {
  27.             String birthDate1 = (String) o1 ;
  28.             //extract the month, date and year
  29.             month1 = birthDate1.substring(0,2);
  30.             day1 = birthDate1.substring(3,5);
  31.             year1 = birthDate1.substring(6,10);
  32.         }
  33.         String month2 = "01";
  34.         String day2 = "01";
  35.         String year2 = "1900";
  36.         if (o2 instanceof String) {
  37.             String birthDate2 = (String) o2 ;
  38.             //extract the month, date and year
  39.             month2 = birthDate2.substring(0,2);
  40.             day2 = birthDate2.substring(3,5);
  41.             year2 = birthDate2.substring(6,10);
  42.         }
  43.         //System.out.println("month1 = " + month1 + " day1 = " + day1 + " year1 = " + year1);
  44.         //System.out.println("month2 = " + month2 + " day2 = " + day2 + " year2 = " + year2);
  45.         
  46.         int yearCompare = year1.compareTo(year2);
  47.         if(yearCompare !=0) {
  48.             return yearCompare;
  49.         }
  50.         else {
  51.             int monthCompare = month1.compareTo(month2);
  52.             if(monthCompare !=0) {
  53.                 return monthCompare;
  54.             }
  55.             else
  56.             {
  57.                 return day1.compareTo(day2);
  58.                 
  59.             }
  60.         }
  61.         
  62.     }
  63. }

DataItem.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package datasource;
  9. import java.io.Serializable;
  10. /**
  11.  */
  12. public class DataItem implements Serializable 
  13. {
  14.     String SSN;
  15.     String FirstName;
  16.     String LastName;
  17.     String BirthDate;
  18.     String Height;
  19.     String Weight;
  20.     
  21.     boolean Selected;
  22.     
  23.     /**
  24.      * @param ssn
  25.      * @param firstName
  26.      * @param lastName
  27.      * @param birthDate
  28.      * @param height
  29.      * @param weight
  30.      */
  31.     public DataItem(String ssn, String firstName, String lastName,
  32.             String birthDate, String height, String weight) {
  33.         super();
  34.         SSN = ssn;
  35.         FirstName = firstName;
  36.         LastName = lastName;
  37.         BirthDate = birthDate;
  38.         Height = height;
  39.         Weight = weight;
  40.         Selected = false;
  41.     }
  42.     
  43.     public DataItem()
  44.     {
  45.         SSN = "ssn";
  46.         FirstName = "firstName";
  47.         LastName = "lastName";
  48.         BirthDate = "birthDate";
  49.         Height = "height";
  50.         Weight = "100";
  51.     }
  52.     
  53.     
  54.     /**
  55.      * @return Returns the birthDate.
  56.      */
  57.     public String getBirthDate() {
  58.         return BirthDate;
  59.     }
  60.     /**
  61.      * @param birthDate The birthDate to set.
  62.      */
  63.     public void setBirthDate(String birthDate) {
  64.         BirthDate = birthDate;
  65.     }
  66.     /**
  67.      * @return Returns the firstName.
  68.      */
  69.     public String getFirstName() {
  70.         return FirstName;
  71.     }
  72.     /**
  73.      * @param firstName The firstName to set.
  74.      */
  75.     public void setFirstName(String firstName) {
  76.         FirstName = firstName;
  77.     }
  78.     /**
  79.      * @return Returns the height.
  80.      */
  81.     public String getHeight() {
  82.         return Height;
  83.     }
  84.     /**
  85.      * @param height The height to set.
  86.      */
  87.     public void setHeight(String height) {
  88.         Height = height;
  89.     }
  90.     /**
  91.      * @return Returns the lastName.
  92.      */
  93.     public String getLastName() {
  94.         return LastName;
  95.     }
  96.     /**
  97.      * @param lastName The lastName to set.
  98.      */
  99.     public void setLastName(String lastName) {
  100.         LastName = lastName;
  101.     }
  102.     /**
  103.      * @return Returns the sSN.
  104.      */
  105.     public String getSSN() {
  106.         return SSN;
  107.     }
  108.     /**
  109.      * @param ssn The sSN to set.
  110.      */
  111.     public void setSSN(String ssn) {
  112.         SSN = ssn;
  113.     }
  114.     /**
  115.      * @return Returns the weight.
  116.      */
  117.     public String getWeight() {
  118.         return Weight;
  119.     }
  120.     /**
  121.      * @param weight The weight to set.
  122.      */
  123.     public void setWeight(String weight) {
  124.         Weight = weight;
  125.     }
  126.     /**
  127.      * @return Returns the birthDate.
  128.      */
  129.     public boolean getSelected() {
  130.         return Selected;
  131.     }
  132.     /**
  133.      * @param birthDate The birthDate to set.
  134.      */
  135.     public void setSelected(boolean selected) {
  136.         Selected = selected;
  137.     }
  138. }

DataSource.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package datasource;
  9. import java.io.Serializable;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12. /**
  13.  */
  14. public class DataSource implements Serializable {
  15.     List dataItems;
  16.     
  17.     private static String[] firstNames = { 
  18.             "Carol""John""Frank""Barbara""Julie""Ted""Ted""Bob""Mary""Alice""Fran"
  19.             ,"Carrie""John""Frank""Barbara""Julie""Bob""Mary""Alice""Fran"
  20.             ,"Carol""John""Frank""Barbara""Julie""Ted""Bob""Mary""Alice""Fran"
  21.             ,"Carol""John""John""Frank""Barbara""Barbara""Julie""Ted""Bob""Mary""Alice""Fran"
  22.             ,"Carol""John""Frank""Barbara""Julie""Ted""Bob""Mary""Alice""Fran"
  23.             ,"Carrol""John""Kenneth""Barbara""Julie""Ted""Bob""Mary""Alice""Fran"
  24.             ,"Carol""John""Frank""Barbara""Julie""Ted""Bob""Mary""Alice""Fran"
  25.             ,"Carol""John""Frank""Mary""Julie""Ted""Bob""Mary""Alice""Fran"
  26.             ,"Carl""John""Elizabeth""Barbara""Julie""Ted""Bob""Mary""Alice""Fran"
  27.             ,"Carol""John""Frank""Barbara""Julie""Ted""Bob""Mary""Alice""Fran"
  28.     };
  29.     
  30.     private static String[] lastNames = { 
  31.             "Smith""Jones""Johnson""Reynolds""Robinson""Clark""Lewis""Washington""Franklin""Pierce"
  32.             ,"Wilson","Smith""Jones""Johnson""Reynolds""Robinson""Clark""Lewis""Washington""Franklin""Pierce"
  33.             ,"Nixon","Smith""Jones""Johnson""Reynolds""Robinson""Clark""Lewis""Washington""Franklin""Pierce"
  34.             ,"Patterson","Smith""Jones""Johnson""Reynolds""Robinson""Clark""Lewis""Washington""Franklin""Pierce"
  35.             ,"Franklin","Smith""Jones""Johnson""Reynolds""Robinson""Clark""Lewis""Washington""Franklin""Pierce"
  36.             ,"Jetson","Smith""Jones""Johnson""Reynolds""Robinson""Clark""Lewis""Washington""Franklin""Pierce"
  37.             ,"Adams","Smith""Jones""Johnson""Reynolds""Robinson""Clark""Lewis""Washington""Franklin""Pierce"
  38.             ,"Carleson","Smith""Jones""Johnson""Reynolds""Robinson""Clark""Lewis""Washington""Franklin""Pierce"
  39.             ,"Smith""Jones""Johnson""Reynolds""Robinson""Clark""Lewis""Washington""Franklin""Pierce"
  40.             ,"Smith""Jones""Johnson""Reynolds""Robinson""Clark""Lewis""Washington""Franklin""Pierce"
  41.     };
  42.     
  43.     private static String[] birthDates = { 
  44.             "01/09/1960""08/15/1972""09/11/1973""02/03/1982""07/11/1978""03/15/1990""04/10/1955""09/10/1955""07/12/1956""02/06/1968"
  45.             ,"01/09/1961","01/09/1962""08/15/1973""09/11/1974""02/03/1985""07/11/1976""03/15/1997""04/12/1955""09/10/1955""07/12/1956""02/06/1968"
  46.             , "08/15/1972","01/09/1960""08/15/1972""09/11/1973""02/03/1982""07/11/1978""03/15/1990""04/13/1955""09/10/1955""07/12/1956""02/06/1968"
  47.             ,"01/09/1960""08/15/1971""09/11/1972""02/03/1983""07/11/1974""03/15/1995""04/12/1956""09/10/1957""07/12/1958""02/06/1968"
  48.             , "09/11/1973","01/09/1960""08/15/1972""09/11/1973""02/03/1982""07/11/1978""03/15/1990""04/14/1955""09/10/1955""07/12/1956""02/06/1968"
  49.             ,"01/09/1960""08/15/1972""09/11/1973""02/03/1982""07/11/1978""03/15/1990""04/12/1957""09/10/1955""07/12/1956""02/06/1968"
  50.             , "02/03/1982","01/09/1960""08/15/1972""09/11/1973""02/03/1982""07/11/1978""03/15/1990""04/15/1955""09/10/1955""07/12/1956""02/06/1968"
  51.             ,"01/09/1960""08/15/1972""09/11/1973""02/03/1982""07/11/1978""03/15/1990""04/12/1958""09/10/1955""07/12/1956""02/06/1968"
  52.             , "07/11/1978","01/09/1960""08/15/1972""09/11/1973""02/03/1982""07/11/1978""03/15/1990""04/16/1955""09/10/1955""07/12/1956""02/06/1968"
  53.             ,"01/09/1960""08/15/1972""09/11/1973""02/03/1982""07/11/1978""03/15/1990""04/12/1959""09/10/1955""07/12/1956""02/06/1968"
  54.     };
  55.     private static String[] heights = { 
  56.             "6' 4/"""5' 11/"""4' 11/"""5' 2/"""6'""5' 5/"""5' 8/"""4' 9/"""5'""5' 9/""
  57.             ,"5' 2/"","6' 4/"""5' 11/"""4' 11/"""5' 2/"""6'""5' 5/"""5' 8/"""4' 9/"""5'""5' 9/""
  58.             ,"6' 4/"""5' 11/"""4' 11/"""5' 2/"""6'""5' 5/"""5' 8/"""4' 9/"""5'""5' 9/""
  59.             ,"5' 2/"","6' 4/"""5' 11/"""4' 11/"""5' 2/"""6'""5' 5/"""5' 8/"""4' 9/"""5'""5' 9/""
  60.             ,"6' 4/"""5' 11/"""4' 11/"""5' 2/"""6'""5' 5/"""5' 8/"""4' 9/"""5'""5' 9/""
  61.             ,"5' 2/"","6' 4/"""5' 11/"""4' 11/"""5' 2/"""6'""5' 5/"""5' 8/"""4' 9/"""5'""5' 9/""
  62.             ,"6' 4/"""5' 11/"""4' 11/"""4' 11/"""5' 2/"""6'""5' 5/"""5' 8/"""4' 9/"""5'""5' 9/""
  63.             ,"5' 2/"","6' 4/"""5' 11/"""4' 11/"""5' 2/"""6'""5' 5/"""5' 8/"""4' 9/"""5'""5' 9/""
  64.             ,"6' 4/"""5' 11/"""5' 2/"""6'""5' 5/"""5' 8/"""4' 9/"""5'""5' 9/""
  65.             ,"6' 4/"""5' 11/"""4' 11/"""5' 2/"""6'""5' 5/"""5' 8/"""4' 9/"""5'""5' 9/""
  66.     };
  67.     
  68.     private static int[] weights = { 
  69.             210185140152200210160108100155
  70.             ,210185140152200210160108100155
  71.             , 140,210185140152200210160108100155
  72.             ,210185140152200210160108100155
  73.             ,210185140152200210160108100155
  74.             , 140,210185140152200210160108100155
  75.             ,210185140152200210160108100155
  76.             , 140,210185140152200210160108100155
  77.             ,210185140152200210160108100155
  78.             ,210185140152200210160108100155
  79.     };
  80.     
  81.     public DataSource() {
  82.         if (dataItems == null) {
  83.             dataItems = new ArrayList();
  84.             int SSN = 1000;
  85.             for (int i = 0; i < 100; i++) {
  86.                 dataItems.add(new DataItem("123-45-" + (SSN + i), firstNames[i],
  87.                         lastNames[i], birthDates[i], heights[i], new String(""+ weights[i])));
  88.             }
  89.         }
  90.     }
  91.     public List getDataItems() {
  92.         return dataItems;
  93.     }
  94. }

ColumnChooserPage.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import java.util.List;
  10. import org.apache.tapestry.IRequestCycle;
  11. import org.apache.tapestry.contrib.palette.SortMode;
  12. import org.apache.tapestry.form.IPropertySelectionModel;
  13. import org.apache.tapestry.form.StringPropertySelectionModel;
  14. import org.apache.tapestry.html.BasePage;
  15. /**
  16.  *
  17.  */
  18. public class ColumnChooserPage extends BasePage
  19. {
  20.     private List _selectedColumns;
  21.     private SortMode _sort = SortMode.USER;
  22.     private IPropertySelectionModel _sortModel;
  23.     public ColumnChooserPage()
  24.     {
  25.         super();
  26.     }
  27.     
  28.     public void initialize()
  29.     {
  30.         super.initialize();
  31.         _sort = SortMode.USER;
  32.         _selectedColumns = null;
  33.     }
  34.     public void formSubmit(IRequestCycle cycle)
  35.     {
  36.         ColumnChooserPage2 resultsPage = (ColumnChooserPage2) cycle.getPage("ColumnChooser2");
  37.         if( _selectedColumns != null && _selectedColumns.size()>0)
  38.         {
  39.             // Convert the List to a String of 
  40.             // comma-seperated ColumnIDs
  41.             StringBuffer selectedColumns = new StringBuffer();
  42.             for (int i=0; i < _selectedColumns.size(); i++)
  43.             {
  44.                 // Crude mapping of Labels to ColumnIDs
  45.                 String columnString = (String)_selectedColumns.get(i);
  46.                 if (columnString.equals("First Name")){
  47.                     selectedColumns.append("FirstName");
  48.                 } else if (columnString.equals("Last Name"))
  49.                 {
  50.                     selectedColumns.append("LastName");
  51.                 } else if (columnString.equals("Birth Date"))
  52.                 {
  53.                     selectedColumns.append("=birthDateColumn");
  54.                 } else {
  55.                     selectedColumns.append(columnString);
  56.                 }
  57.                 if( i < (_selectedColumns.size()-1))
  58.                 {
  59.                     selectedColumns.append(",");
  60.                 }
  61.             }
  62.             resultsPage.setSelectedColumns(selectedColumns.toString());
  63.             cycle.activate(resultsPage);
  64.         } else {
  65.             _errorMsg = "Select at least one column";
  66.         }
  67.     }
  68.     private IPropertySelectionModel columnModel;
  69.     private String[] columns = { "SSN""First Name""Last Name""Birth Date""Height""Weight" };
  70.     public IPropertySelectionModel getColumnModel()
  71.     {
  72.         if (columnModel == null)
  73.             columnModel = new StringPropertySelectionModel(columns);
  74.         return columnModel;
  75.     }
  76.     public void setSort(SortMode value)
  77.     {
  78.         _sort = value;
  79.     }
  80.     public SortMode getSort()
  81.     {
  82.         return _sort;
  83.     }
  84.     public IPropertySelectionModel getSortModel()
  85.     {
  86.         return _sortModel;
  87.     }
  88.     public List getSelectedColumns()
  89.     {
  90.         return _selectedColumns;
  91.     }
  92.     public void setSelectedColumns(List selectedColumns)
  93.     {
  94.         _selectedColumns = selectedColumns;
  95.     }
  96.     String _errorMsg;
  97.     
  98.     public String getErrorMsg()
  99.     {
  100.         return _errorMsg;
  101.     }
  102. }

ColumnChooserPage2.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import java.util.List;
  10. import org.apache.tapestry.IRequestCycle;
  11. import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
  12. import org.apache.tapestry.contrib.table.model.ITableColumn;
  13. import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
  14. import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
  15. import org.apache.tapestry.event.PageEvent;
  16. import org.apache.tapestry.event.PageRenderListener;
  17. import org.apache.tapestry.html.BasePage;
  18. import datasource.BirthDateComparator;
  19. import datasource.DataItem;
  20. /**
  21.  *
  22.  */
  23. public abstract class ColumnChooserPage2 extends BasePage implements PageRenderListener
  24. {
  25.     public abstract List getDataItems();
  26.     public abstract void setDataItems(List dataItems);
  27.     public abstract String getColumnsString();
  28.     public abstract void setColumnsString(String cols);
  29.     private IPrimaryKeyConvertor m_dataItemConvertor;
  30.     public ColumnChooserPage2()
  31.     {
  32.         super();
  33.         // define a IPrimaryKeyConvertor that gets DataItems from the original list 
  34.         m_dataItemConvertor = new IPrimaryKeyConvertor()
  35.         {
  36.             public Object getPrimaryKey(Object objValue)
  37.             {
  38.                 DataItem dataItem = (DataItem) objValue;
  39.                 return dataItem.getSSN();
  40.             }
  41.             public Object getValue(Object objPrimaryKey)
  42.             {
  43.                 String SSN = (String)objPrimaryKey;
  44.                 List list = getDataItems();
  45.                 // find the item
  46.                 int count = list.size();
  47.                 for (int i = 0; i < count; i++)
  48.                 {
  49.                     DataItem item = (DataItem) list.get(i);
  50.                     if (item.getSSN().equals(SSN)){
  51.                         return item;
  52.                     }
  53.                 }
  54.                 return new DataItem(); //Handle data item not found 
  55.             }
  56.         };
  57.         
  58.     }
  59.     public IPrimaryKeyConvertor getDataItemConvertor()
  60.     {
  61.         return m_dataItemConvertor;
  62.     }
  63.     public void pageBeginRender(PageEvent event)
  64.     {
  65.         List list = getDataItems();
  66.         if (list == null)
  67.         {
  68.             setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
  69.         }
  70.         setColumnsString(_selectedColumns);
  71.         System.out.println("setColumnsString(" + _selectedColumns + ")");
  72.     }
  73.     public ITableColumn getBirthDateColumn()
  74.     {
  75.         // The column value is extracted in a custom evaluator class
  76.         SimpleTableColumn birthDateColumn =  new SimpleTableColumn("BirthDate""Birth Date"new BirthDateColumnEvaluator(), true);
  77.         birthDateColumn.setColumnComparator(new BirthDateComparator());
  78.         return birthDateColumn;
  79.     }
  80.     /**
  81.      * A class defining the logic for getting the BirthDate from a DataItem
  82.      */
  83.     private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
  84.     {
  85.         /**
  86.          * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
  87.          */
  88.         public Object getColumnValue(ITableColumn objColumn, Object objRow)
  89.         {
  90.             DataItem dataItem = (DataItem) objRow;
  91.             if( dataItem == null )
  92.             {
  93.                 return "No Birthdate";
  94.             }
  95.             return dataItem.getBirthDate();
  96.         }
  97.     }
  98.     public void formSubmit(IRequestCycle cycle)
  99.     {
  100.         System.out.println("The form was submitted");
  101.     }
  102.     String _selectedColumns = "No Columns Selected";
  103.     public void setSelectedColumns( String selectedColumns)
  104.     {
  105.         _selectedColumns = selectedColumns;
  106.     }
  107. }

CustomSortColumnPage.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import tapestrytables.TapestryTablesVisit;
  10. import org.apache.tapestry.contrib.table.model.ITableColumn;
  11. import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
  12. import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
  13. import datasource.DataItem;
  14. import datasource.BirthDateComparator;
  15. import java.util.List;
  16. import org.apache.tapestry.event.PageEvent;
  17. import org.apache.tapestry.event.PageRenderListener;
  18. import org.apache.tapestry.html.BasePage;
  19. /**
  20.  *
  21.  */
  22. public abstract class CustomSortColumnPage extends BasePage implements PageRenderListener
  23. {
  24.     public abstract List getDataItems();
  25.     public abstract void setDataItems(List dataItems);
  26.     public void pageBeginRender(PageEvent event)
  27.     {
  28.         List list = getDataItems();
  29.         if (list == null)
  30.         {
  31.             setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
  32.         }
  33.     }
  34.     public ITableColumn getBirthDateColumn()
  35.     {
  36.         // The column value is extracted in a custom evaluator class
  37.         SimpleTableColumn birthDateColumn =  new SimpleTableColumn("BirthDate""Birth Date"new BirthDateColumnEvaluator(), true);
  38.         birthDateColumn.setColumnComparator(new BirthDateComparator());
  39.         return birthDateColumn;
  40.     }
  41.     /**
  42.      * A class defining the logic for getting the BirthDate from a DataItem
  43.      */
  44.     private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
  45.     {
  46.         /**
  47.          * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
  48.          */
  49.         public Object getColumnValue(ITableColumn objColumn, Object objRow)
  50.         {
  51.             DataItem dataItem = (DataItem) objRow;
  52.             return dataItem.getBirthDate();
  53.         }
  54.     }
  55. }

DirectLinkColumnPage.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import tapestrytables.TapestryTablesVisit;
  10. import org.apache.tapestry.IRequestCycle;
  11. import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
  12. import org.apache.tapestry.contrib.table.model.ITableColumn;
  13. import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
  14. import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
  15. import datasource.DataItem;
  16. import datasource.BirthDateComparator;
  17. import java.util.List;
  18. import org.apache.tapestry.event.PageEvent;
  19. import org.apache.tapestry.event.PageRenderListener;
  20. import org.apache.tapestry.html.BasePage;
  21. /**
  22.  *
  23.  */
  24. public abstract class DirectLinkColumnPage extends BasePage implements PageRenderListener
  25. {
  26.     public abstract List getDataItems();
  27.     public abstract void setDataItems(List dataItems);
  28.     public abstract String getSelectedSSN();
  29.     public abstract void setSelectedSSN(String selectedSSN);
  30.     
  31.     private IPrimaryKeyConvertor m_dataItemConvertor;
  32.     public DirectLinkColumnPage()
  33.     {
  34.         super();
  35.         // define a IPrimaryKeyConvertor that gets DataItems from the original list 
  36.         m_dataItemConvertor = new IPrimaryKeyConvertor()
  37.         {
  38.             public Object getPrimaryKey(Object objValue)
  39.             {
  40.                 DataItem dataItem = (DataItem) objValue;
  41.                 return dataItem.getSSN();
  42.             }
  43.             public Object getValue(Object objPrimaryKey)
  44.             {
  45.                 String SSN = (String)objPrimaryKey;
  46.                 List list = getDataItems();
  47.                 // find the item
  48.                 int count = list.size();
  49.                 for (int i = 0; i < count; i++)
  50.                 {
  51.                     DataItem item = (DataItem) list.get(i);
  52.                     if (item.getSSN().equals(SSN)){
  53.                         return item;
  54.                     }
  55.                 }
  56.                 return new DataItem(); //Handle data item not found 
  57.             }
  58.         };
  59.         
  60.     }
  61.     // authored by Rick Austin
  62.     public void SelectListener(IRequestCycle cycle) {
  63.         Object[] parameters = cycle.getServiceParameters();
  64.         String SSN = (String)parameters[0];
  65.         // Output the parameter value to the console to see if
  66.         // this works.
  67.         System.out.println("Selected SSN: " + SSN);
  68.         setSelectedSSN(SSN);
  69.     }
  70.     public IPrimaryKeyConvertor getDataItemConvertor()
  71.     {
  72.         return m_dataItemConvertor;
  73.     }
  74.     public void pageBeginRender(PageEvent event)
  75.     {
  76.         List list = getDataItems();
  77.         if (list == null)
  78.         {
  79.             setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
  80.         }
  81.     }
  82.     public ITableColumn getBirthDateColumn()
  83.     {
  84.         // The column value is extracted in a custom evaluator class
  85.         SimpleTableColumn birthDateColumn =  new SimpleTableColumn("BirthDate""Birth Date"new BirthDateColumnEvaluator(), true);
  86.         birthDateColumn.setColumnComparator(new BirthDateComparator());
  87.         return birthDateColumn;
  88.     }
  89.     /**
  90.      * A class defining the logic for getting the BirthDate from a DataItem
  91.      */
  92.     private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
  93.     {
  94.         /**
  95.          * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
  96.          */
  97.         public Object getColumnValue(ITableColumn objColumn, Object objRow)
  98.         {
  99.             DataItem dataItem = (DataItem) objRow;
  100.             if( dataItem == null )
  101.             {
  102.                 return "No Birthdate";
  103.             }
  104.             return dataItem.getBirthDate();
  105.         }
  106.     }
  107.     public void formSubmit(IRequestCycle cycle)
  108.     {
  109.         System.out.println("The form was submitted");
  110.  /*     
  111.         RequestContext context = cycle.getRequestContext();
  112.         System.out.println(context.getParameter("hiddenCurrentPage"));
  113.         
  114.         //int iterRows = Integer.parseInt(context.getParameter("iterRows"));            
  115.         String ew = "editableWeight";
  116.         for (int i=0; i < 6; i++)
  117.         {
  118.             String suffix;
  119.             if (i==0) {
  120.                 suffix = "";
  121.             } else {
  122.                 suffix = "$" + (i-1);
  123.             }
  124.             String editableWeightString = context.getParameter(ew + suffix);
  125.             if(editableWeightString != null)
  126.             {
  127.                 System.out.println("The " + ew + suffix + " parameter is: " + editableWeightString );
  128.             }
  129.         }
  130.         
  131.         // Process the submitted form
  132.         List list = getDataItems();
  133.         // Do something to process the list changes
  134.         int count = list.size();
  135.         for (int i = 0; i < 1; i++)
  136.         {
  137.             DataItem item = (DataItem) list.get(i);
  138.             System.out.println(item.getWeight());
  139.         }
  140.         // Always important to set peristent properties; otherwise changes
  141.         // made in this request cycle will be lost.  The framework
  142.         // makes a copy of the list.
  143.         setDataItems(list);
  144. */
  145.         }
  146. }

DirectLinkTableColumnPage.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import tapestrytables.TapestryTablesVisit;
  10. import org.apache.tapestry.IRequestCycle;
  11. import org.apache.tapestry.components.Block;
  12. import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
  13. import org.apache.tapestry.contrib.table.model.ITableColumn;
  14. import org.apache.tapestry.contrib.table.model.ITableColumnModel;
  15. import org.apache.tapestry.contrib.table.model.common.BlockTableRendererSource;
  16. import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
  17. import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
  18. import datasource.DataItem;
  19. import datasource.BirthDateComparator;
  20. import java.util.HashMap;
  21. import java.util.Iterator;
  22. import java.util.List;
  23. import org.apache.tapestry.event.PageEvent;
  24. import org.apache.tapestry.event.PageRenderListener;
  25. import org.apache.tapestry.html.BasePage;
  26. import org.apache.tapestry.util.ComponentAddress;
  27. /**
  28.  *  
  29.  */
  30. public abstract class DirectLinkTableColumnPage extends BasePage implements
  31.         PageRenderListener {
  32.     public abstract List getDataItems();
  33.     public abstract void setDataItems(List dataItems);
  34.     public abstract String getSelectedSSN();
  35.     public abstract void setSelectedSSN(String selectedSSN);
  36.     private IPrimaryKeyConvertor m_dataItemConvertor;
  37.     public DirectLinkTableColumnPage() {
  38.         super();
  39.         // define a IPrimaryKeyConvertor that gets DataItems from the original
  40.         // list
  41.         m_dataItemConvertor = new IPrimaryKeyConvertor() {
  42.             public Object getPrimaryKey(Object objValue) {
  43.                 DataItem dataItem = (DataItem) objValue;
  44.                 return dataItem.getSSN();
  45.             }
  46.             public Object getValue(Object objPrimaryKey) {
  47.                 String SSN = (String) objPrimaryKey;
  48.                 List list = getDataItems();
  49.                 // find the item
  50.                 int count = list.size();
  51.                 for (int i = 0; i < count; i++) {
  52.                     DataItem item = (DataItem) list.get(i);
  53.                     if (item.getSSN().equals(SSN)) {
  54.                         return item;
  55.                     }
  56.                 }
  57.                 return new DataItem(); //Handle data item not found
  58.             }
  59.         };
  60.     }
  61.     // authored by Rick Austin
  62.     public void SelectListener(IRequestCycle cycle) {
  63.         Object[] parameters = cycle.getServiceParameters();
  64.         String SSN = (String) parameters[0];
  65.         // Output the parameter value to the console to see if
  66.         // this works.
  67.         System.out.println("Selected SSN: " + SSN);
  68.         setSelectedSSN(SSN);
  69.     }
  70.     public IPrimaryKeyConvertor getDataItemConvertor() {
  71.         return m_dataItemConvertor;
  72.     }
  73.     public void pageBeginRender(PageEvent event) {
  74.         List list = getDataItems();
  75.         if (list == null) {
  76.             setDataItems(((TapestryTablesVisit) getVisit()).getDataItems());
  77.         }
  78.     }
  79.     public ITableColumn getBirthDateColumn() {
  80.         // The column value is extracted in a custom evaluator class
  81.         SimpleTableColumn birthDateColumn = new SimpleTableColumn("BirthDate",
  82.                 "Birth Date"new BirthDateColumnEvaluator(), true);
  83.         birthDateColumn.setColumnComparator(new BirthDateComparator());
  84.         return birthDateColumn;
  85.     }
  86.     /**
  87.      * A class defining the logic for getting the BirthDate from a DataItem
  88.      */
  89.     private static class BirthDateColumnEvaluator implements
  90.             ITableColumnEvaluator {
  91.         /**
  92.          * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn,
  93.          *      Object)
  94.          */
  95.         public Object getColumnValue(ITableColumn objColumn, Object objRow) {
  96.             DataItem dataItem = (DataItem) objRow;
  97.             if (dataItem == null) {
  98.                 return "No Birthdate";
  99.             }
  100.             return dataItem.getBirthDate();
  101.         }
  102.     }
  103.     public void formSubmit(IRequestCycle cycle) {
  104.         System.out.println("The form was submitted");
  105.         /*
  106.          * RequestContext context = cycle.getRequestContext();
  107.          * 
  108.          * System.out.println(context.getParameter("hiddenCurrentPage"));
  109.          * 
  110.          * //int iterRows = Integer.parseInt(context.getParameter("iterRows"));
  111.          * String ew = "editableWeight"; for (int i=0; i < 6; i++) { String
  112.          * suffix; if (i==0) { suffix = ""; } else { suffix = "$" + (i-1); }
  113.          * String editableWeightString = context.getParameter(ew + suffix);
  114.          * if(editableWeightString != null) { System.out.println("The " + ew +
  115.          * suffix + " parameter is: " + editableWeightString ); } }
  116.          *  // Process the submitted form List list = getDataItems();
  117.          *  // Do something to process the list changes int count = list.size();
  118.          * for (int i = 0; i < 1; i++) { DataItem item = (DataItem) list.get(i);
  119.          * System.out.println(item.getWeight()); }
  120.          *  // Always important to set peristent properties; otherwise changes //
  121.          * made in this request cycle will be lost. The framework // makes a
  122.          * copy of the list. setDataItems(list);
  123.          */
  124.     }
  125.     
  126.     public ITableColumnModel getColumnModel()
  127.     {
  128.         return new ColumnModel();
  129.     }
  130.     class ColumnModel implements ITableColumnModel {
  131.         private HashMap columns;
  132.         public ColumnModel() {
  133.             this.columns = new HashMap();
  134.             SimpleTableColumn column1 = new SimpleTableColumn("SSN""SSN",
  135.                     new ITableColumnEvaluator() 
  136.                     {
  137.                         public Object getColumnValue(ITableColumn objColumn,
  138.                                 Object objRow) 
  139.                         {
  140.                             return ((DataItem) objRow).getSSN();
  141.                         }
  142.                     }, true);
  143.             // The following overrides the default SimpleTableColumn.getColumnValue to
  144.             // render the Block component we defined on the HTML template
  145.             column1.setValueRendererSource(new BlockTableRendererSource(new ComponentAddress(getComponent("SSNColumnValue"))));
  146.             
  147.             ITableColumn column2 = new SimpleTableColumn("LastName""LastName",
  148.                     new ITableColumnEvaluator() 
  149.                     {
  150.                         public Object getColumnValue(ITableColumn objColumn,
  151.                                 Object objRow) 
  152.                         {
  153.                             return ((DataItem) objRow).getLastName();
  154.                         }
  155.                     }, true);
  156.             ITableColumn column3 = new SimpleTableColumn("FirstName""FirstName",
  157.                     new ITableColumnEvaluator() {
  158.                         public Object getColumnValue(ITableColumn objColumn,
  159.                                 Object objRow) {
  160.                             return ((DataItem) objRow).getFirstName();
  161.                         }
  162.                     }, true);
  163.             ITableColumn column4 = new SimpleTableColumn("Height""Height",
  164.                     new ITableColumnEvaluator() {
  165.                         public Object getColumnValue(ITableColumn objColumn,
  166.                                 Object objRow) {
  167.                             return ((DataItem) objRow).getHeight();
  168.                         }
  169.                     }, true);
  170.             ITableColumn column5 = new SimpleTableColumn("Width""Width",
  171.                     new ITableColumnEvaluator() {
  172.                         public Object getColumnValue(ITableColumn objColumn,
  173.                                 Object objRow) {
  174.                             return ((DataItem) objRow).getHeight();
  175.                         }
  176.                     }, true);
  177.             columns.put(column1.getColumnName(), column1);
  178.             columns.put(column2.getColumnName(), column2);
  179.             columns.put(column3.getColumnName(), column3);
  180.             columns.put(getBirthDateColumn().getColumnName(), getBirthDateColumn());
  181.             columns.put(column4.getColumnName(), column4);
  182.             columns.put(column5.getColumnName(), column5);
  183.         }
  184.         public int getColumnCount() {
  185.             return this.columns.size();
  186.         }
  187.         public ITableColumn getColumn(String strName) {
  188.             return (ITableColumn) columns.get(strName);
  189.         }
  190.         public Iterator getColumns() {
  191.             return columns.values().iterator();
  192.         }
  193.     }
  194. }

EditableColumnPage.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import tapestrytables.TapestryTablesVisit;
  10. import org.apache.tapestry.IRequestCycle;
  11. import org.apache.tapestry.contrib.table.model.ITableColumn;
  12. import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
  13. import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
  14. import datasource.DataItem;
  15. import datasource.BirthDateComparator;
  16. import java.util.List;
  17. import org.apache.tapestry.event.PageEvent;
  18. import org.apache.tapestry.event.PageRenderListener;
  19. import org.apache.tapestry.html.BasePage;
  20. /**
  21.  *
  22.  */
  23. public abstract class EditableColumnPage extends BasePage implements PageRenderListener
  24. {
  25.     public abstract List getDataItems();
  26.     public abstract void setDataItems(List dataItems);
  27.     public void pageBeginRender(PageEvent event)
  28.     {
  29.         List list = getDataItems();
  30.         if (list == null)
  31.         {
  32.             setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
  33.         }
  34.     }
  35.     public ITableColumn getBirthDateColumn()
  36.     {
  37.         // The column value is extracted in a custom evaluator class
  38.         SimpleTableColumn birthDateColumn =  new SimpleTableColumn("BirthDate""Birth Date"new BirthDateColumnEvaluator(), true);
  39.         birthDateColumn.setColumnComparator(new BirthDateComparator());
  40.         return birthDateColumn;
  41.     }
  42.     /**
  43.      * A class defining the logic for getting the BirthDate from a DataItem
  44.      */
  45.     private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
  46.     {
  47.         /**
  48.          * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
  49.          */
  50.         public Object getColumnValue(ITableColumn objColumn, Object objRow)
  51.         {
  52.             DataItem dataItem = (DataItem) objRow;
  53.             return dataItem.getBirthDate();
  54.         }
  55.     }
  56.     public void formSubmit(IRequestCycle cycle)
  57.     {
  58.         System.out.println("The form was submitted");
  59.         // Process the submitted form
  60.         List list = getDataItems();
  61.         // Do something to process the list changes
  62.         //int count = list.size();
  63.         //for (int i = 0; i < count; i++)
  64.         //{
  65.         //    DataItem item = (DataItem) list.get(i);
  66.         //    System.out.println(item.getWeight());
  67.         //}
  68.         // Always important to set peristent properties; otherwise changes
  69.         // made in this request cycle will be lost.  The framework
  70.         // makes a copy of the list.
  71.         setDataItems(list);
  72.     }
  73. }

EditableColumnPage2.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import tapestrytables.TapestryTablesVisit;
  10. import org.apache.tapestry.IRequestCycle;
  11. import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
  12. import org.apache.tapestry.contrib.table.model.ITableColumn;
  13. import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
  14. import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
  15. import datasource.DataItem;
  16. import datasource.BirthDateComparator;
  17. import java.util.List;
  18. import org.apache.tapestry.event.PageEvent;
  19. import org.apache.tapestry.event.PageRenderListener;
  20. import org.apache.tapestry.html.BasePage;
  21. /**
  22.  *
  23.  */
  24. public abstract class EditableColumnPage2 extends BasePage implements PageRenderListener
  25. {
  26.     public abstract List getDataItems();
  27.     public abstract void setDataItems(List dataItems);
  28.     private IPrimaryKeyConvertor m_dataItemConvertor;
  29.     public EditableColumnPage2()
  30.     {
  31.         super();
  32.         // define a IPrimaryKeyConvertor that gets DataItems from the original list 
  33.         m_dataItemConvertor = new IPrimaryKeyConvertor()
  34.         {
  35.             public Object getPrimaryKey(Object objValue)
  36.             {
  37.                 DataItem dataItem = (DataItem) objValue;
  38.                 return dataItem.getSSN();
  39.             }
  40.             public Object getValue(Object objPrimaryKey)
  41.             {
  42.                 String SSN = (String)objPrimaryKey;
  43.                 List list = getDataItems();
  44.                 // find the item
  45.                 int count = list.size();
  46.                 for (int i = 0; i < count; i++)
  47.                 {
  48.                     DataItem item = (DataItem) list.get(i);
  49.                     if (item.getSSN().equals(SSN)){
  50.                         return item;
  51.                     }
  52.                 }
  53.                 return new DataItem(); //Handle data item not found 
  54.             }
  55.         };
  56.         
  57.     }
  58.     public IPrimaryKeyConvertor getDataItemConvertor()
  59.     {
  60.         return m_dataItemConvertor;
  61.     }
  62.     public void pageBeginRender(PageEvent event)
  63.     {
  64.         List list = getDataItems();
  65.         if (list == null)
  66.         {
  67.             setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
  68.         }
  69.     }
  70.     public ITableColumn getBirthDateColumn()
  71.     {
  72.         // The column value is extracted in a custom evaluator class
  73.         SimpleTableColumn birthDateColumn =  new SimpleTableColumn("BirthDate""Birth Date"new BirthDateColumnEvaluator(), true);
  74.         birthDateColumn.setColumnComparator(new BirthDateComparator());
  75.         return birthDateColumn;
  76.     }
  77.     /**
  78.      * A class defining the logic for getting the BirthDate from a DataItem
  79.      */
  80.     private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
  81.     {
  82.         /**
  83.          * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
  84.          */
  85.         public Object getColumnValue(ITableColumn objColumn, Object objRow)
  86.         {
  87.             DataItem dataItem = (DataItem) objRow;
  88.             if( dataItem == null )
  89.             {
  90.                 return "No Birthdate";
  91.             }
  92.             return dataItem.getBirthDate();
  93.         }
  94.     }
  95.     public void formSubmit(IRequestCycle cycle)
  96.     {
  97.         System.out.println("The form was submitted");
  98.  /*     
  99.         RequestContext context = cycle.getRequestContext();
  100.         System.out.println(context.getParameter("hiddenCurrentPage"));
  101.         
  102.         //int iterRows = Integer.parseInt(context.getParameter("iterRows"));            
  103.         String ew = "editableWeight";
  104.         for (int i=0; i < 6; i++)
  105.         {
  106.             String suffix;
  107.             if (i==0) {
  108.                 suffix = "";
  109.             } else {
  110.                 suffix = "$" + (i-1);
  111.             }
  112.             String editableWeightString = context.getParameter(ew + suffix);
  113.             if(editableWeightString != null)
  114.             {
  115.                 System.out.println("The " + ew + suffix + " parameter is: " + editableWeightString );
  116.             }
  117.         }
  118.         
  119.         // Process the submitted form
  120.         List list = getDataItems();
  121.         // Do something to process the list changes
  122.         int count = list.size();
  123.         for (int i = 0; i < 1; i++)
  124.         {
  125.             DataItem item = (DataItem) list.get(i);
  126.             System.out.println(item.getWeight());
  127.         }
  128.         // Always important to set peristent properties; otherwise changes
  129.         // made in this request cycle will be lost.  The framework
  130.         // makes a copy of the list.
  131.         setDataItems(list);
  132. */
  133.         }
  134. }

FirstPass.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import tapestrytables.TapestryTablesVisit;
  10. import java.util.List;
  11. import org.apache.tapestry.event.PageEvent;
  12. import org.apache.tapestry.event.PageRenderListener;
  13. import org.apache.tapestry.html.BasePage;
  14. /**
  15.  *
  16.  */
  17. public abstract class FirstPass extends BasePage implements PageRenderListener
  18. {
  19.     public abstract List getDataItems();
  20.     public abstract void setDataItems(List dataItems);
  21.     public void pageBeginRender(PageEvent event)
  22.     {
  23.         List list = getDataItems();
  24.         if (list == null)
  25.         {
  26.             setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
  27.         }
  28.     }
  29. }

TapestryTablesVisit.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  *
  8.  * This class pretty much corresponds to a users session object
  9.  * It is accessible from all of the pages in the application
  10.  */
  11. package tapestrytables;
  12. import datasource.DataSource;
  13. import java.io.Serializable;
  14. import java.util.List;
  15. /**
  16.  * 
  17.  */
  18. public class TapestryTablesVisit implements Serializable
  19. {
  20.     DataSource dataSource;
  21.     public TapestryTablesVisit()
  22.     {
  23.         dataSource = new DataSource();
  24.     }
  25.     /**
  26.      * @return Returns the list of Data Items.
  27.      */
  28.     public List getDataItems() {
  29.         return dataSource.getDataItems();
  30.     }
  31. }

TestPage.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import java.util.List;
  10. import org.apache.tapestry.IRequestCycle;
  11. import org.apache.tapestry.contrib.table.components.TableView;
  12. import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
  13. import org.apache.tapestry.event.PageEvent;
  14. import org.apache.tapestry.event.PageRenderListener;
  15. import org.apache.tapestry.form.IPropertySelectionModel;
  16. import org.apache.tapestry.form.StringPropertySelectionModel;
  17. import org.apache.tapestry.html.BasePage;
  18. import org.apache.tapestry.request.RequestContext;
  19. import org.apache.tapestry.valid.ValidationDelegate;
  20. import datasource.DataItem;
  21. /**
  22.  *
  23.  */
  24. public abstract class TestPage extends BasePage implements PageRenderListener
  25. {
  26.     public abstract List getDataItems();
  27.     public abstract void setDataItems(List dataItems);
  28.     public abstract String getColumnsString();
  29.     public abstract void setColumnsString(String cols);
  30.     public static final IPropertySelectionModel COLUMNS_MODEL = 
  31.         new StringPropertySelectionModel(new String[] { 
  32.                 "SSN, FirstName, LastName"
  33.                 "SSN, LastName, FirstName"
  34.                 "LastName, FirstName"
  35.                 "LastName, SSN, FirstName" });
  36.    
  37.     
  38.     private IPrimaryKeyConvertor m_dataItemConvertor;
  39.     public TestPage()
  40.     {
  41.         super();
  42.         
  43.         // define a IPrimaryKeyConvertor that gets DataItems from the original list 
  44.         m_dataItemConvertor = new IPrimaryKeyConvertor()
  45.         {
  46.             public Object getPrimaryKey(Object objValue)
  47.             {
  48.                 DataItem dataItem = (DataItem) objValue;
  49.                 return dataItem.getSSN();
  50.             }
  51.             public Object getValue(Object objPrimaryKey)
  52.             {
  53.                 String SSN = (String)objPrimaryKey;
  54.                 List list = getDataItems();
  55.                 // find the item
  56.                 int count = list.size();
  57.                 for (int i = 0; i < count; i++)
  58.                 {
  59.                     DataItem item = (DataItem) list.get(i);
  60.                     if (item.getSSN().equals(SSN)){
  61.                         return item;
  62.                     }
  63.                 }
  64.                 return new DataItem(); //Handle data item not found 
  65.             }
  66.         };
  67.         
  68.     }
  69.     public IPrimaryKeyConvertor getDataItemConvertor()
  70.     {
  71.         return m_dataItemConvertor;
  72.     }
  73.     
  74.     String colsString =  "SSN, FirstName, LastName";
  75.     //int count = 0;
  76.     public void pageBeginRender(PageEvent event)
  77.     {
  78.         List list = getDataItems();
  79.         if (list == null)
  80.         {
  81.             setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
  82.         }
  83.         //String colStrings = event.getPage().getMessage("ColumnsString");
  84.         //setColumnsString(columnsStrings[count%3]);
  85.         setColumnsString(colsString);
  86.         System.out.println("setColumnsString(" + colsString + ")");
  87.     }
  88.         
  89.     public void formSubmit(IRequestCycle cycle)
  90.     {
  91.         colsString = getColumnsString();
  92.         
  93.         System.out.println("The form was submitted");
  94.         ValidationDelegate delegate = (ValidationDelegate)getBeans().getBean("delegate");
  95.         if(delegate.getHasErrors()) {
  96.             // there are errors
  97.             RequestContext context = cycle.getRequestContext();
  98.             String currentPage = context.getParameter("hiddenCurrentPage");
  99.             int currentPageInt = new Integer(currentPage).intValue();
  100.             System.out.println("The current page is: " + currentPageInt );
  101.             
  102.             TableView tableView = (TableView)getComponent("tableView");
  103.             if( tableView != null )
  104.             {
  105.                 System.out.println("Setting the current page back to " + currentPageInt);
  106.                 // Remember, "hiddenCurrentPage" starts at "1": setCurrentPage is "0" based
  107.                 tableView.getTableModel().getPagingState().setCurrentPage(currentPageInt-1);
  108.             }
  109.             return;
  110.         }
  111.     }
  112. }

ValidateEditableColumnPage.java

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import tapestrytables.TapestryTablesVisit;
  10. import org.apache.tapestry.IRequestCycle;
  11. import org.apache.tapestry.contrib.table.components.FormTable;
  12. import org.apache.tapestry.contrib.table.components.TableView;
  13. import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
  14. import org.apache.tapestry.contrib.table.model.ITableColumn;
  15. import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
  16. import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
  17. import datasource.DataItem;
  18. import datasource.BirthDateComparator;
  19. import java.util.List;
  20. import org.apache.tapestry.event.PageEvent;
  21. import org.apache.tapestry.event.PageRenderListener;
  22. import org.apache.tapestry.html.BasePage;
  23. import org.apache.tapestry.request.RequestContext;
  24. import org.apache.tapestry.valid.ValidationDelegate;
  25. /**
  26.  *
  27.  */
  28. public abstract class ValidateEditableColumnPage extends BasePage implements PageRenderListener
  29. {
  30.     public abstract List getDataItems();
  31.     public abstract void setDataItems(List dataItems);
  32.     private IPrimaryKeyConvertor m_dataItemConvertor;
  33.     public ValidateEditableColumnPage()
  34.     {
  35.         super();
  36.         // define a IPrimaryKeyConvertor that gets DataItems from the original list 
  37.         m_dataItemConvertor = new IPrimaryKeyConvertor()
  38.         {
  39.             public Object getPrimaryKey(Object objValue)
  40.             {
  41.                 DataItem dataItem = (DataItem) objValue;
  42.                 return dataItem.getSSN();
  43.             }
  44.             public Object getValue(Object objPrimaryKey)
  45.             {
  46.                 String SSN = (String)objPrimaryKey;
  47.                 List list = getDataItems();
  48.                 // find the item
  49.                 int count = list.size();
  50.                 for (int i = 0; i < count; i++)
  51.                 {
  52.                     DataItem item = (DataItem) list.get(i);
  53.                     if (item.getSSN().equals(SSN)){
  54.                         return item;
  55.                     }
  56.                 }
  57.                 return new DataItem(); //Handle data item not found 
  58.             }
  59.         };
  60.         
  61.     }
  62.     public IPrimaryKeyConvertor getDataItemConvertor()
  63.     {
  64.         return m_dataItemConvertor;
  65.     }
  66.     public void pageBeginRender(PageEvent event)
  67.     {
  68.         List list = getDataItems();
  69.         if (list == null)
  70.         {
  71.             setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
  72.         }
  73.     }
  74.     public ITableColumn getBirthDateColumn()
  75.     {
  76.         // The column value is extracted in a custom evaluator class
  77.         SimpleTableColumn birthDateColumn =  new SimpleTableColumn("BirthDate""Birth Date"new BirthDateColumnEvaluator(), true);
  78.         birthDateColumn.setColumnComparator(new BirthDateComparator());
  79.         return birthDateColumn;
  80.     }
  81.     /**
  82.      * A class defining the logic for getting the BirthDate from a DataItem
  83.      */
  84.     private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
  85.     {
  86.         /**
  87.          * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
  88.          */
  89.         public Object getColumnValue(ITableColumn objColumn, Object objRow)
  90.         {
  91.             DataItem dataItem = (DataItem) objRow;
  92.             if( dataItem == null )
  93.             {
  94.                 return "No Birthdate";
  95.             }
  96.             return dataItem.getBirthDate();
  97.         }
  98.     }
  99.     public void formSubmit(IRequestCycle cycle) {
  100.         System.out.println("The form was submitted");
  101.         ValidationDelegate delegate = (ValidationDelegate) getBeans().getBean(
  102.                 "delegate");
  103.         if (delegate.getHasErrors()) {
  104.             // there are errors
  105.             RequestContext context = cycle.getRequestContext();
  106.             String currentPage = context.getParameter("hiddenCurrentPage");
  107.             if (currentPage != null) { 
  108.                 int currentPageInt = new Integer(currentPage).intValue();
  109.                 System.out.println("The current page is: " + currentPageInt);
  110.                 FormTable formTable = (FormTable) getComponent("table");
  111.                 if (formTable != null) {
  112.                     System.out.println("Setting the current page back to "
  113.                             + currentPageInt);
  114.                     // Remember, "hiddenCurrentPage" starts at "1":
  115.                     // setCurrentPage is "0" based
  116.                     formTable.getTableModel().getPagingState().setCurrentPage(
  117.                             currentPageInt - 1);
  118.                 } 
  119.             }else {
  120.                 System.out.println("The parameter hiddenCurrentPage doesn't exist");
  121. //              hiddenCurrentPage doesn't exist if there is only one page in the table
  122.             }
  123.             return;
  124.         }
  125.     }
  126. }
ValidateEditableColumnPage2.java

 

  1. /* Contributed by John Reynolds - October 2004
  2.  * This work is hereby released into the Public Domain. 
  3.  * To view a copy of the public domain dedication, visit 
  4.  * http://creativecommons.org/licenses/publicdomain/ 
  5.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  6.  * Stanford, California 94305, USA.
  7.  */
  8. package tapestrytables;
  9. import tapestrytables.TapestryTablesVisit;
  10. import org.apache.tapestry.IRequestCycle;
  11. import org.apache.tapestry.contrib.table.components.FormTable;
  12. import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
  13. import org.apache.tapestry.contrib.table.model.ITableColumn;
  14. import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
  15. import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
  16. import datasource.DataItem;
  17. import datasource.BirthDateComparator;
  18. import java.util.List;
  19. import org.apache.tapestry.event.PageEvent;
  20. import org.apache.tapestry.event.PageRenderListener;
  21. import org.apache.tapestry.html.BasePage;
  22. import org.apache.tapestry.request.RequestContext;
  23. import org.apache.tapestry.valid.ValidationDelegate;
  24. /**
  25.  *
  26.  */
  27. public abstract class ValidateEditableColumnPage2 extends BasePage implements PageRenderListener
  28. {
  29.     public abstract List getDataItems();
  30.     public abstract void setDataItems(List dataItems);
  31.     private IPrimaryKeyConvertor m_dataItemConvertor;
  32.     public ValidateEditableColumnPage2()
  33.     {
  34.         super();
  35.         // define a IPrimaryKeyConvertor that gets DataItems from the original list 
  36.         m_dataItemConvertor = new IPrimaryKeyConvertor()
  37.         {
  38.             public Object getPrimaryKey(Object objValue)
  39.             {
  40.                 DataItem dataItem = (DataItem) objValue;
  41.                 return dataItem.getSSN();
  42.             }
  43.             public Object getValue(Object objPrimaryKey)
  44.             {
  45.                 String SSN = (String)objPrimaryKey;
  46.                 List list = getDataItems();
  47.                 // find the item
  48.                 int count = list.size();
  49.                 for (int i = 0; i < count; i++)
  50.                 {
  51.                     DataItem item = (DataItem) list.get(i);
  52.                     if (item.getSSN().equals(SSN)){
  53.                         return item;
  54.                     }
  55.                 }
  56.                 return new DataItem(); //Handle data item not found 
  57.             }
  58.         };
  59.         
  60.     }
  61.     public IPrimaryKeyConvertor getDataItemConvertor()
  62.     {
  63.         return m_dataItemConvertor;
  64.     }
  65.     public void pageBeginRender(PageEvent event)
  66.     {
  67.         List list = getDataItems();
  68.         if (list == null)
  69.         {
  70.             setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
  71.         }
  72.     }
  73.     public ITableColumn getBirthDateColumn()
  74.     {
  75.         // The column value is extracted in a custom evaluator class
  76.         SimpleTableColumn birthDateColumn =  new SimpleTableColumn("BirthDate""BirthDate"new BirthDateColumnEvaluator(), true);
  77.         birthDateColumn.setColumnComparator(new BirthDateComparator());
  78.         // Pick up any settings from the template and page
  79.         birthDateColumn.loadSettings(this);
  80.         return birthDateColumn;
  81.     }
  82.     /**
  83.      * A class defining the logic for getting the BirthDate from a DataItem
  84.      */
  85.     private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
  86.     {
  87.         /**
  88.          * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
  89.          */
  90.         public Object getColumnValue(ITableColumn objColumn, Object objRow)
  91.         {
  92.             DataItem dataItem = (DataItem) objRow;
  93.             if( dataItem == null )
  94.             {
  95.                 return "No Birthdate";
  96.             }
  97.             return dataItem.getBirthDate();
  98.         }
  99.     }
  100.     public void formSubmit(IRequestCycle cycle) {
  101.         System.out.println("The form was submitted");
  102.         ValidationDelegate delegate = (ValidationDelegate) getBeans().getBean(
  103.                 "delegate");
  104.         if (delegate.getHasErrors()) {
  105.             // there are errors
  106.             RequestContext context = cycle.getRequestContext();
  107.             String currentPage = context.getParameter("hiddenCurrentPage");
  108.             if (currentPage != null) { 
  109.                 int currentPageInt = new Integer(currentPage).intValue();
  110.                 System.out.println("The current page is: " + currentPageInt);
  111.                 FormTable formTable = (FormTable) getComponent("table");
  112.                 if (formTable != null) {
  113.                     System.out.println("Setting the current page back to "
  114.                             + currentPageInt);
  115.                     // Remember, "hiddenCurrentPage" starts at "1":
  116.                     // setCurrentPage is "0" based
  117.                     formTable.getTableModel().getPagingState().setCurrentPage(
  118.                             currentPageInt - 1);
  119.                 } 
  120.             }else {
  121.                 System.out.println("The parameter hiddenCurrentPage doesn't exist");
  122. //              hiddenCurrentPage doesn't exist if there is only one page in the table
  123.             }
  124.             return;
  125.         }
  126.     }
  127. }

style.css

  1. body  
  2. {
  3.   font-family : Trebuchet MS, san serif;
  4.   font-weight : normal;
  5. }
  6. table.mytable 
  7. {
  8.   border-stylesolid;
  9.   border-colorblack;
  10.   border-width1px;
  11. }
  12. th.columnheader
  13. {
  14.   background-colorrgb(228,228,228);
  15. }
  16. td.tablepager
  17. {
  18.   background-colorrgb(228,228,228);
  19. }
  20. tr.even
  21. {
  22.   background-color: lightblue;
  23. }
  24. tr.odd
  25. {
  26.   background-colorrgb(228,255,228);
  27. }
  28. code.snippet
  29. {
  30.   colorred;
  31. }
  32. code.highlight
  33. {
  34.   colorred;
  35.   background-colorrgb(255,255,128);
  36. }
  37. span.inputerror
  38. {
  39.   colorred;
  40.   font-weight : strong;
  41.   background-color: yellow;
  42. }
  43. div.code
  44. {
  45.   colorred;
  46.   background-colorrgb(255,255,228);
  47. }
  48. div.note
  49. {
  50.   background-colorrgb(228,255,228);
  51. }
  52. TABLE.palette TH
  53. {
  54.   font-size9pt;
  55.   font-weightbold;
  56.   colorwhite;
  57.   background-color#330066;
  58.   text-aligncenter;
  59. }
  60. TABLE.palette SELECT
  61. {
  62.   font-weightbold;
  63.   background-color#839cd1;
  64.   width200px;
  65. }
  66. TABLE.palette TD.controls
  67. {
  68.    text-aligncenter;
  69.    vertical-alignmiddle;
  70.    width60px;
  71. }

ColumnChooser.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Choosing and Ordering Columns</h1>
  7. <div class="note">
  8.     This page demonstrates how to choose and order the table columns at runtime.
  9. </div>            
  10. <p>The columns that are displayed in the table can be dynamically specified
  11.     rather then hard-coded.  It's a simple as setting the <code>columns</code>
  12.     parameter to an expression rather then a string. 
  13. </p><p>
  14.     To demonstrate run-time column selection, we'll use a two-step process.    
  15.     Use the following <code>contrib:Palette</code> to select
  16.     the columns that you wish to see in the table (select at least one column), 
  17.     and then select the <code>Continue</code> button to see the results.  
  18. </p>
  19. <form jwcid="@Form" listener="ognl:listeners.formSubmit">
  20. <table class="form">
  21.     <tr>
  22.         <th>Columns:</th>
  23.         <td><input jwcid="chooseColumns"/></td>
  24.     </tr>
  25.     <tr>
  26.         <td></td>
  27.         <td>
  28.              <input type="submit" value="Continue"/>
  29.              <code class="highlight"><span jwcid="@Insert" value="ognl:errorMsg"/></code>
  30.         </td>
  31.     </tr>
  32. </table>
  33. <p>
  34.     I chose to use the <code>contrib:Palette</code> for this example because
  35.     it is fairly straight-forward to use.  Regardless of how you choose to 
  36.     specify the columns and their order, you must pass the columns
  37.     to the Table's page before activating the page.  Here is the 
  38.     relevent code from <code>ColumnChooserPage.java</code>:
  39. <pre><code class="snippet">
  40.   public void formSubmit(IRequestCycle cycle)
  41.   {
  42.       ColumnChooserPage2 resultsPage = (ColumnChooserPage2) cycle.getPage("ColumnChooser2");
  43.       if( _selectedColumns != null && _selectedColumns.size()>0)
  44.       {
  45.         // Convert the List to a String of comma-seperated ColumnIDs
  46.         StringBuffer selectedColumns = new StringBuffer();
  47.         for (int i=0; i < _selectedColumns.size(); i++) {
  48.             // Crude mapping of Labels to ColumnIDs
  49.             String columnString = (String)_selectedColumns.get(i);
  50.             if (columnString.equals("First Name")) {
  51.                 selectedColumns.append("FirstName");
  52.             } else if (columnString.equals("Last Name")) {
  53.                 selectedColumns.append("LastName");
  54.             } else if (columnString.equals("Birth Date")) {
  55.                 selectedColumns.append("=birthDateColumn");
  56.             } else {
  57.                 selectedColumns.append(columnString);
  58.             }
  59.             if( i < (_selectedColumns.size()-1)) {
  60.                 selectedColumns.append(",");
  61.             }
  62.         }
  63. <code class="highlight">        resultsPage.setSelectedColumns(selectedColumns.toString());
  64.         cycle.activate(resultsPage);
  65. </code>    }
  66.   }
  67. </code></pre>        
  68. </form>
  69. <p>
  70.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  71. </body>
  72. </html>
  73. <!--
  74.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  75.  * This work is hereby released into the Public Domain. 
  76.  * To view a copy of the public domain dedication, visit 
  77.  * http://creativecommons.org/licenses/publicdomain/ 
  78.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  79.  * Stanford, California 94305, USA.
  80. -->

ColumnChooser.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!--
  6.  * Contributed by John Reynolds - October 2004
  7.  * This work is hereby released into the Public Domain. 
  8.  * To view a copy of the public domain dedication, visit 
  9.  * http://creativecommons.org/licenses/publicdomain/ 
  10.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  11.  * Stanford, California 94305, USA.
  12. -->
  13. <page-specification class="tapestrytables.ColumnChooserPage">
  14.   <context-asset name="stylesheet" path="css/style.css"/>
  15.   <component id="chooseColumns" type="contrib:Palette">
  16.     <binding name="model" expression="columnModel"/>
  17.     <binding name="selected" expression="selectedColumns"/>
  18.     <binding name="sort" expression="sort"/>
  19.     <static-binding name="tableClass" value="palette"/>
  20.   </component>
  21. </page-specification>

ColumnChooser2.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Choosing and Ordering Columns</h1>
  7. <div class="note">
  8.     This page demonstrates how to choose and order the table columns at runtime.
  9. </div>            
  10. <p>
  11.     The following <code>Table</code> should display the columns that you
  12.     specified on the previous page (in the order you chose):
  13. </p><p>
  14.     <form jwcid="form">
  15.     <table class="mytable" jwcid="table">
  16.         <th>SSN</th>
  17.         <th>First Name</th>
  18.         <th>Last Name</th>
  19.         <th>Birth Date</th>
  20.         <th>Height</th>
  21.         <th>Weight</th>
  22.         <tr class="even">
  23.             <td>123-44-5555</td>
  24.             <td>John</td>
  25.             <td>Reynolds</td>
  26.             <td>10/01/2004</td>
  27.             <td>5' 11"</td>
  28.             <td>185</td>
  29.         </tr>
  30.         <tr class="odd">
  31.             <td>123-44-5555</td>
  32.             <td>John</td>
  33.             <td>Reynolds</td>
  34.             <td>10/01/2004</td>
  35.             <td>5' 11"</td>
  36.             <td>185</td>
  37.         </tr>
  38.         <tr class="even">
  39.             <td>123-44-5555</td>
  40.             <td>John</td>
  41.             <td>Reynolds</td>
  42.             <td>10/01/2004"</td>
  43.             <td>5' 11"</td>
  44.             <td>185</td>
  45.         </tr>
  46.         <tr class="odd">
  47.             <td>123-44-5555</td>
  48.             <td>John</td>
  49.             <td>Reynolds</td>
  50.             <td>10/01/2004</td>
  51.             <td>5' 11"</td>
  52.             <td>185</td>
  53.         </tr>
  54.     </table>
  55.     </form>
  56. </p><p>
  57.     If you take a look at the files <code>ColumnChooser2.html</code>,
  58.     <code>ColumnChooser2.page</code> and <code>ColumnChooserPage2.java</code> 
  59.     you will see the elements necessary to specify the columns at runtime.
  60. </p><p>
  61.     Here are the relevent additions to <code>ColumnChooser2.page</code> 
  62.     that sets up the <code>Table</code> to get the <code>columns</code>
  63.     by evaluating an expression:
  64. </p><p>
  65.    
  66. <pre><code class="snippet">        
  67.     <component id="table" type="contrib:FormTable">
  68.         <binding name="source" expression="dataItems"/>
  69.         <binding name="convertor" expression="dataItemConvertor"/>
  70.         <code class="highlight"><binding name="columns" expression="ColumnsString" /></code>
  71.         <binding name="rowsClass" expression="beans.evenOdd.next"/>
  72.         <binding name="pageSize" expression="6"/>
  73.     </component>
  74. </code></pre>
  75. </p><p>
  76. </p><p>
  77.     Here is the method that was added to <code>ColumnChooserPage2.java</code> 
  78.     to accept output from the column selector on the previous page:
  79. </p><p>
  80. <code class="highlight"><pre>
  81.     public void setSelectedColumns( String selectedColumns)
  82.     {
  83.         _selectedColumns = selectedColumns;
  84.         colsString = selectedColumns;
  85.     }
  86. </pre></code>    
  87. </p><p>
  88.     That's all there is to it.  Simply pass the desired columns to the page
  89.     before it is rendered.
  90. </p><p>
  91.     <a href="#" jwcid="@PageLink" page="TenthPass">Using TableView, TableColumns, and TableFormRows...</a>
  92. </p><p>
  93.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  94. </p>
  95. </body>
  96. </html>
  97. <!--
  98.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  99.  * This work is hereby released into the Public Domain. 
  100.  * To view a copy of the public domain dedication, visit 
  101.  * http://creativecommons.org/licenses/publicdomain/ 
  102.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  103.  * Stanford, California 94305, USA.
  104. -->

ColumnChooser2.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <page-specification class="tapestrytables.ColumnChooserPage2">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17.         <property-specification name="columnsString" type="java.lang.String" persistent="yes"/>
  18.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  19.         <component id="form" type="Form">
  20.             <binding name="listener" expression="listeners.formSubmit"/>
  21.         </component>
  22.         <component id="table" type="contrib:FormTable">
  23.             <binding name="source" expression="dataItems"/>
  24.             <binding name="convertor" expression="dataItemConvertor"/>
  25.             <binding name="columns" expression="ColumnsString" />
  26.             <binding name="rowsClass" expression="beans.evenOdd.next"/>
  27.             <binding name="pageSize" expression="6"/>
  28.         </component>
  29. </page-specification>

ColumnChooser2.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight

DirectLinkColumn.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Direct Links</h1>
  7. <div class="note">
  8.     This page demonstrates how to embed direct links in a column.
  9. </div>            
  10. <p>        
  11.     Rick Austin provided the prototype for this page.
  12.     The key, as discovered by Rick, is to use two components; a DirectLink 
  13.     for the link functionality and an InsertText to render the text.
  14.     When you click
  15.     on one of the SSN links, the label below the table will be updated to indicate
  16.     your selection:
  17. </p><p>
  18.     <form jwcid="form">
  19.     <table class="mytable" jwcid="table">
  20.        <span jwcid="SSNColumnValue@Block">
  21.           <span jwcid="SSNLink">
  22.              <span jwcid="SSNText"/>
  23.           </span>
  24.        </span>
  25.         <th>SSN</th>
  26.         <th>First Name</th>
  27.         <th>Last Name</th>
  28.         <th>Birth Date</th>
  29.         <th>Height</th>
  30.         <th>Weight</th>
  31.         <tr class="even">
  32.             <td>123-44-5555</td>
  33.             <td>John</td>
  34.             <td>Reynolds</td>
  35.             <td>10/01/2004</td>
  36.             <td>5' 11"</td>
  37.             <td>185</td>
  38.         </tr>
  39.         <tr class="odd">
  40.             <td>123-44-5555</td>
  41.             <td>John</td>
  42.             <td>Reynolds</td>
  43.             <td>10/01/2004</td>
  44.             <td>5' 11"</td>
  45.             <td>185</td>
  46.         </tr>
  47.         <tr class="even">
  48.             <td>123-44-5555</td>
  49.             <td>John</td>
  50.             <td>Reynolds</td>
  51.             <td>10/01/2004"</td>
  52.             <td>5' 11"</td>
  53.             <td>185</td>
  54.         </tr>
  55.         <tr class="odd">
  56.             <td>123-44-5555</td>
  57.             <td>John</td>
  58.             <td>Reynolds</td>
  59.             <td>10/01/2004</td>
  60.             <td>5' 11"</td>
  61.             <td>185</td>
  62.         </tr>
  63.     </table>
  64.     <input type="submit" value="Update"/>
  65.     </form>
  66. <div class="note">
  67.     The last SSN that was selected was:
  68.     <code class="highlight"><span jwcid="SelectedSSNText"/></code>
  69. </div>
  70. </p><p>
  71.     If you take a look at the files <code>DirectLinkColumn.html</code>,
  72.     <code>DirectLinkColumn.page</code> and <code>DirectLinkColumn.java</code> 
  73.     you will see the elements necessary to embed direct links in a column.
  74. </p><p>
  75.     Here are the relevent additions to <code>DirectLinkColumn.page</code> 
  76.     that sets up the components necessary for the links:
  77. </p><p>
  78.    
  79. <code class="highlight"><pre>
  80. <!--
  81.  * Used to create a link which has a listener and passes in the current
  82.  * SSN as a parameter.
  83. -->
  84. <component id="SSNLink" type="DirectLink">
  85.     <binding name="listener" expression="listeners.SelectListener"/>
  86.     <binding name="parameters" expression="components.table.tableRow.SSN"/>
  87. </component> 
  88. <!--
  89.  * Used to output the SSN value into the row since the SSNLink component
  90.  * creates a link but does not have a way of providing the link text.
  91. -->
  92. <component id="SSNText" type="InsertText">
  93.     <binding name="value" expression="components.table.tableRow.SSN"/>
  94. </component> 
  95. </pre></code>        
  96. </p><p>
  97.     Here is the relevent snippet from <code>DirectLink.html</code> 
  98.     that sets up the links:
  99. </p><p>
  100.    
  101. <code class="snippet"><pre>
  102.   <table class="mytable" jwcid="table">
  103.      <code class="highlight"><span jwcid="SSNColumnValue@Block">
  104.        <span jwcid="SSNLink">
  105.          <span jwcid="SSNText"/>
  106.        </span>
  107.      </span></code>
  108. </pre></code>
  109. </p><p>
  110. </p><p>
  111.     Here is the method that was added to <code>DirectLinkColumnPage.java</code> 
  112.     to process the links:
  113. </p><p>
  114. <code class="highlight"><pre>
  115.     // authored by Rick Austin
  116.     public void SelectListener(IRequestCycle cycle) {
  117.         Object[] parameters = cycle.getServiceParameters();
  118.         String SSN = (String)parameters[0];
  119.         // Output the parameter value to the console to see if
  120.         // this works.
  121.         System.out.println("Selected SSN: " + SSN);
  122.     }
  123. </pre></code>    
  124. </p><p>
  125. <a href="#" jwcid="@PageLink" page="DirectLinkTableColumn">Direct Link using TableColumns...</a>
  126. </p><p>
  127. <a href="#" jwcid="@PageLink" page="ColumnChooser">Choosing and Ordering Columns...</a>
  128. </p><p>
  129.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  130. </p>
  131. </body>
  132. </html>
  133. <!--
  134.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  135.  * This work is hereby released into the Public Domain. 
  136.  * To view a copy of the public domain dedication, visit 
  137.  * http://creativecommons.org/licenses/publicdomain/ 
  138.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  139.  * Stanford, California 94305, USA.
  140. -->

DirectLinkColumn.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <page-specification class="tapestrytables.DirectLinkColumnPage">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17.         <property-specification name="selectedSSN" type="java.lang.String" persistent="yes"/>
  18.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  19.         <component id="form" type="Form">
  20.             <binding name="listener" expression="listeners.formSubmit"/>
  21.         </component>
  22.         <component id="table" type="contrib:FormTable">
  23.             <binding name="source" expression="dataItems"/>
  24.             <binding name="convertor" expression="dataItemConvertor"/>
  25.             <static-binding name="columns"
  26.                 value="
  27.                     SSN, 
  28.                     FirstName, 
  29.                     LastName, 
  30.                     =birthDateColumn, 
  31.                     Height, 
  32.                     Weight"/>
  33.             <binding name="rowsClass" expression="beans.evenOdd.next"/>
  34.             <binding name="pageSize" expression="6"/>
  35.             <static-binding  name="initialSortColumn" value="BirthDate"/>
  36.         </component>
  37.         <!--
  38.         * Used to create a link which has a listener and passes in the current
  39.         * SSN as a parameter.
  40.         -->
  41.         <component id="SSNLink" type="DirectLink">
  42.            <binding name="listener" expression="listeners.SelectListener"/>
  43.            <binding name="parameters" expression="components.table.tableRow.SSN"/>
  44.         </component> 
  45.         <!--
  46.         * Used to output the SSN value into the row since the SSNLink component
  47.         * creates a link but does not have a way of providing the link text.
  48.         -->
  49.         <component id="SSNText" type="InsertText">
  50.           <binding name="value" expression="components.table.tableRow.SSN"/>
  51.         </component> 
  52.         <!--
  53.         * Used to output the selected SSN value.
  54.         -->
  55.         <component id="SelectedSSNText" type="InsertText">
  56.           <binding name="value" expression="selectedSSN"/>
  57.         </component> 
  58. </page-specification>

DirectLinkColumn.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight

DirectLinkTableColumn.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Direct Links when using TableColumns</h1>
  7. <div class="note">
  8.     This page demonstrates how to embed direct links in a column when using
  9.     a TableColumns object to define the columns.
  10. </div>            
  11. <p>        
  12.     A question from Christian M�hlethaler prompted me to create this example.
  13. </p><p>
  14.     The previous Direct Link example works if the columns are defined using a String, but
  15.     it wasn't obvious how to make this work if the columns are defined using
  16.     a <code>TableColumns</code> object.
  17. </p><p>
  18.     The "trick" is to define a Column within your TableColumns that will get its
  19.     ValueRenderer from your HTML template.
  20. </p><p>
  21.     <form jwcid="form">
  22.     <table class="mytable" jwcid="table">
  23.        <span jwcid="SSNColumnValue@Block">
  24.           <span jwcid="SSNLink">
  25.              <span jwcid="SSNText"/>
  26.           </span>
  27.        </span>
  28.         <th>SSN</th>
  29.         <th>First Name</th>
  30.         <th>Last Name</th>
  31.         <th>Birth Date</th>
  32.         <th>Height</th>
  33.         <th>Weight</th>
  34.         <tr class="even">
  35.             <td>123-44-5555</td>
  36.             <td>John</td>
  37.             <td>Reynolds</td>
  38.             <td>10/01/2004</td>
  39.             <td>5' 11"</td>
  40.             <td>185</td>
  41.         </tr>
  42.         <tr class="odd">
  43.             <td>123-44-5555</td>
  44.             <td>John</td>
  45.             <td>Reynolds</td>
  46.             <td>10/01/2004</td>
  47.             <td>5' 11"</td>
  48.             <td>185</td>
  49.         </tr>
  50.         <tr class="even">
  51.             <td>123-44-5555</td>
  52.             <td>John</td>
  53.             <td>Reynolds</td>
  54.             <td>10/01/2004"</td>
  55.             <td>5' 11"</td>
  56.             <td>185</td>
  57.         </tr>
  58.         <tr class="odd">
  59.             <td>123-44-5555</td>
  60.             <td>John</td>
  61.             <td>Reynolds</td>
  62.             <td>10/01/2004</td>
  63.             <td>5' 11"</td>
  64.             <td>185</td>
  65.         </tr>
  66.     </table>
  67.     <input type="submit" value="Update"/>
  68.     </form>
  69. <div class="note">
  70.     The last SSN that was selected was:
  71.     <code class="highlight"><span jwcid="SelectedSSNText"/></code>
  72. </div>
  73. </p><p>
  74.     If you take a look at the files <code>DirectLinkTableColumn.html</code>,
  75.     <code>DirectLinkTableColumn.page</code> and <code>DirectLinkTableColumn.java</code> 
  76.     you will see the elements necessary to embed direct links when using <code>TableColumns</code>.
  77. </p><p>
  78.     Here are the relevent additions to <code>DirectTableLinkColumn.page</code> 
  79.     that sets up the table to use a <code>TableColumns</code> object:
  80. </p><p>
  81.    
  82. <code class="snippet"><pre>
  83. <component id="table" type="contrib:FormTable">
  84.     <binding name="source" expression="dataItems"/>
  85.     <binding name="convertor" expression="dataItemConvertor"/>
  86.     <binding name="columns"
  87.         <code class="highlight">expression="columnModel"</code>/>
  88.     <binding name="rowsClass" expression="beans.evenOdd.next"/>
  89.     <binding name="pageSize" expression="6"/>
  90.     <static-binding  name="initialSortColumn" value="BirthDate"/>
  91. </component>
  92.     
  93. </pre></code>        
  94. </p><p>
  95.     Here is the method and the private class that was added to <code>DirectLinkTableColumnPage.java</code> 
  96.     to define the TableColumnModel:
  97. </p><p>
  98. <div class="code"><pre>
  99.     public ITableColumnModel getColumnModel()
  100.     {
  101.         return new ColumnModel();
  102.     }
  103.     class ColumnModel implements ITableColumnModel {
  104.         private HashMap columns;
  105.         public ColumnModel() {
  106.             this.columns = new HashMap();
  107.             SimpleTableColumn column1 = new SimpleTableColumn("SSN", "SSN",
  108.                     new ITableColumnEvaluator() 
  109.                     {
  110.                         public Object getColumnValue(ITableColumn objColumn,
  111.                                 Object objRow) 
  112.                         {
  113.                             return ((DataItem) objRow).getSSN();
  114.                         }
  115.                     }, true);
  116. <code class="highlight">
  117.             // The following overrides the default ValueRendererSource to
  118.             // render the Block component we defined on the HTML template
  119.             column1.setValueRendererSource( 
  120.                 new BlockTableRendererSource(
  121.                     new ComponentAddress(
  122.                         getComponent("SSNColumnValue"))));
  123. </code>            
  124.             ITableColumn column2 = new SimpleTableColumn("LastName", "LastName",
  125.                     new ITableColumnEvaluator() 
  126.                     {
  127.                         public Object getColumnValue(ITableColumn objColumn,
  128.                                 Object objRow) 
  129.                         {
  130.                             return ((DataItem) objRow).getLastName();
  131.                         }
  132.                     }, true);
  133.             ITableColumn column3 = new SimpleTableColumn("FirstName", "FirstName",
  134.                     new ITableColumnEvaluator() {
  135.                         public Object getColumnValue(ITableColumn objColumn,
  136.                                 Object objRow) {
  137.                             return ((DataItem) objRow).getFirstName();
  138.                         }
  139.                     }, true);
  140.             ITableColumn column4 = new SimpleTableColumn("Height", "Height",
  141.                     new ITableColumnEvaluator() {
  142.                         public Object getColumnValue(ITableColumn objColumn,
  143.                                 Object objRow) {
  144.                             return ((DataItem) objRow).getHeight();
  145.                         }
  146.                     }, true);
  147.             ITableColumn column5 = new SimpleTableColumn("Width", "Width",
  148.                     new ITableColumnEvaluator() {
  149.                         public Object getColumnValue(ITableColumn objColumn,
  150.                                 Object objRow) {
  151.                             return ((DataItem) objRow).getHeight();
  152.                         }
  153.                     }, true);
  154.             columns.put(column1.getColumnName(), column1);
  155.             columns.put(column2.getColumnName(), column2);
  156.             columns.put(column3.getColumnName(), column3);
  157.             columns.put(getBirthDateColumn().getColumnName(), getBirthDateColumn());
  158.             columns.put(column4.getColumnName(), column4);
  159.             columns.put(column5.getColumnName(), column5);
  160.         }
  161.         public int getColumnCount() {
  162.             return this.columns.size();
  163.         }
  164.         public ITableColumn getColumn(String strName) {
  165.             return (ITableColumn) columns.get(strName);
  166.         }
  167.         // Quick and dirty iterator
  168.         public Iterator getColumns() {
  169.             return columns.values().iterator();
  170.         }
  171.     }        
  172. </pre></div>
  173. </p>
  174. <div class="note">    
  175.     Note that the column ordering is "wierd" only because my quick and dirty example
  176.     uses a <code>HashMap</code> to hold the <code>SimpleTableColumn</code> objects.
  177.     
  178. </div>
  179. <p>
  180. <a href="#" jwcid="@PageLink" page="ColumnChooser">Choosing and Ordering Columns...</a>
  181. </p><p>
  182.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  183. </p>
  184. </body>
  185. </html>
  186. <!--
  187.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  188.  * This work is hereby released into the Public Domain. 
  189.  * To view a copy of the public domain dedication, visit 
  190.  * http://creativecommons.org/licenses/publicdomain/ 
  191.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  192.  * Stanford, California 94305, USA.
  193. -->

DirectLinkTableColumn.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <page-specification class="tapestrytables.DirectLinkTableColumnPage">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17.         <property-specification name="selectedSSN" type="java.lang.String" persistent="yes"/>
  18.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  19.         <component id="form" type="Form">
  20.             <binding name="listener" expression="listeners.formSubmit"/>
  21.         </component>
  22.         <component id="table" type="contrib:FormTable">
  23.             <binding name="source" expression="dataItems"/>
  24.             <binding name="convertor" expression="dataItemConvertor"/>
  25.             <binding name="columns"
  26.                 expression="columnModel"/>
  27.             <binding name="rowsClass" expression="beans.evenOdd.next"/>
  28.             <binding name="pageSize" expression="6"/>
  29.             <static-binding  name="initialSortColumn" value="BirthDate"/>
  30.         </component>
  31.         <!--
  32.         * Used to create a link which has a listener and passes in the current
  33.         * SSN as a parameter.
  34.         -->
  35.         <component id="SSNLink" type="DirectLink">
  36.            <binding name="listener" expression="listeners.SelectListener"/>
  37.            <binding name="parameters" expression="components.table.tableRow.SSN"/>
  38.         </component> 
  39.         <!--
  40.         * Used to output the SSN value into the row since the SSNLink component
  41.         * creates a link but does not have a way of providing the link text.
  42.         -->
  43.         <component id="SSNText" type="InsertText">
  44.           <binding name="value" expression="components.table.tableRow.SSN"/>
  45.         </component> 
  46.         <!--
  47.         * Used to output the selected SSN value.
  48.         -->
  49.         <component id="SelectedSSNText" type="InsertText">
  50.           <binding name="value" expression="selectedSSN"/>
  51.         </component> 
  52. </page-specification>

DirectLinkTableColumn.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight

EighthPass.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Validating Editable Columns</h1>
  7. <div class="note">
  8.     This page demonstrates how to validate user input in an editable table.
  9. </div>            
  10. <p>        
  11.     It's almost always necessary to check the user's input before accepting it.
  12. </p><p>
  13.     Try entering a non-numeric value in any of the <code>Weight</code> fields in
  14.     the following table.
  15. </p><p>
  16.     <form jwcid="form">
  17.     <table class="mytable" jwcid="table">
  18.         <span jwcid="WeightColumnValue">
  19.            <span jwcid="editableWeight"/>
  20.         </span>
  21.         <th>SSN</th>
  22.         <th>First Name</th>
  23.         <th>Last Name</th>
  24.         <th>Birth Date</th>
  25.         <th>Height</th>
  26.         <th>Weight</th>
  27.         <tr class="even">
  28.             <td>123-44-5555</td>
  29.             <td>John</td>
  30.             <td>Reynolds</td>
  31.             <td>10/01/2004</td>
  32.             <td>5' 11"</td>
  33.             <td>185</td>
  34.         </tr>
  35.         <tr class="odd">
  36.             <td>123-44-5555</td>
  37.             <td>John</td>
  38.             <td>Reynolds</td>
  39.             <td>10/01/2004</td>
  40.             <td>5' 11"</td>
  41.             <td>185</td>
  42.         </tr>
  43.         <tr class="even">
  44.             <td>123-44-5555</td>
  45.             <td>John</td>
  46.             <td>Reynolds</td>
  47.             <td>10/01/2004"</td>
  48.             <td>5' 11"</td>
  49.             <td>185</td>
  50.         </tr>
  51.         <tr class="odd">
  52.             <td>123-44-5555</td>
  53.             <td>John</td>
  54.             <td>Reynolds</td>
  55.             <td>10/01/2004</td>
  56.             <td>5' 11"</td>
  57.             <td>185</td>
  58.         </tr>
  59.         <tr class="even">
  60.             <td>123-44-5555</td>
  61.             <td>John</td>
  62.             <td>Reynolds</td>
  63.             <td>10/01/2004</td>
  64.             <td>5' 11"</td>
  65.             <td>185</td>
  66.         </tr>
  67.         <tr class="odd">
  68.             <td>123-44-5555</td>
  69.             <td>John</td>
  70.             <td>Reynolds</td>
  71.             <td>10/01/2004</td>
  72.             <td>5' 11"</td>
  73.             <td>185</td>
  74.         </tr>
  75.     </table>
  76.     <input type="submit" value="Update"/>
  77.     <span class="inputerror"><span jwcid="errors"/></span>
  78.     </form>
  79. </p><p>
  80.     If you take a look at the files <code>Eighth.html</code><code>EighthPass.page</code> 
  81.     and <code>ValidateEditableColumnPage.java</code> 
  82.     you will see the changes necessary to validate the user's input.
  83. </p><p>
  84.     In the file <code>Eighth.html</code> we added the following to display any errors:
  85. </p><p>
  86.     <code class="highlight">
  87.     <span class="inputerror"><span jwcid="errors"/><span>
  88.     </code>
  89. </p><p>
  90.     Here is the relevent snippets from <code>EighthPass.page</code> 
  91.     that sets up this component:
  92. </p><p>
  93. <pre>   
  94. <code class="snippet">
  95. <code class="highlight">
  96.    <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
  97.    
  98.    <bean name="numberValidator" class="org.apache.tapestry.valid.NumberValidator" lifecycle="page">
  99.        <set-property name="required" expression="true"/>
  100.        <set-property name="clientScriptingEnabled" expression="false"/>
  101.    </bean>
  102. </code>        
  103.    <component id="form" type="Form">
  104.        <binding name="listener" expression="listeners.formSubmit"/>
  105. <code class="highlight">
  106.        <binding name="delegate" expression="beans.delegate"/>
  107. </code>
  108.    </component>
  109.                 
  110.    <component id="table" type="contrib:FormTable">
  111.        <binding name="source" expression="dataItems"/>
  112.        <binding name="convertor" expression="dataItemConvertor"/>
  113.        <static-binding name="columns"
  114.            value="
  115.                SSN, 
  116.                FirstName, 
  117.                LastName, 
  118.                =birthDateColumn, 
  119.                Height, 
  120.                Weight"/>
  121.        <binding name="rowsClass" expression="beans.evenOdd.next"/>
  122.        <binding name="pageSize" expression="6"/>
  123.        <static-binding  name="initialSortColumn" value="BirthDate"/>
  124.    </component>
  125.    <component id="WeightColumnValue" type="Block"/>
  126.         
  127.    <component id="editableWeight" <code class="highlight">type="ValidField"></code>
  128.        <static-binding name="displayName">Weight</static-binding>
  129.        <binding name="value" expression="components.table.tableRow.Weight"/>
  130.        <binding name="size" expression="4"/>
  131.        <code class="highlight"><binding name="validator" expression='beans.numberValidator'/></code>    
  132.    </component>
  133. <code class="highlight">
  134.    <component id="errors" type="Delegator">
  135.        <binding name="delegate" expression="beans.delegate.firstError"/>
  136.    </component>
  137. </code>
  138. </code>
  139. </pre>
  140. </p><p>
  141.     The response to validation errors is handled in <code>ValidateEditableColumnPage.java</code>:
  142. <code class="snippet">
  143. <pre>
  144.     public void formSubmit(IRequestCycle cycle) {
  145.         System.out.println("The form was submitted");
  146. <code class="highlight">        ValidationDelegate delegate = (ValidationDelegate) getBeans().getBean(
  147.                 "delegate");
  148.         if (delegate.getHasErrors()) {
  149.             // there are errors
  150.             RequestContext context = cycle.getRequestContext();
  151.             String currentPage = context.getParameter("hiddenCurrentPage");
  152.             if (currentPage != null) { 
  153.                 int currentPageInt = new Integer(currentPage).intValue();
  154.                 System.out.println("The current page is: " + currentPageInt);
  155.                 FormTable formTable = (FormTable) getComponent("table");
  156.                 if (formTable != null) {
  157.                     System.out.println("Setting the current page back to "
  158.                             + currentPageInt);
  159.                     // Remember, "hiddenCurrentPage" starts at "1":
  160.                     // setCurrentPage is "0" based
  161.                     formTable.getTableModel().getPagingState().setCurrentPage(
  162.                             currentPageInt - 1);
  163.                 } 
  164.             }else {
  165.                 System.out.println("The parameter hiddenCurrentPage doesn't exist");
  166.                 // hiddenCurrentPage doesn't exist if there is only one page in the table            }
  167.             return;
  168.         }
  169.     }
  170. </code></pre></code>        
  171. <a href="#" jwcid="@PageLink" page="NinthPass">Combining Validation and Sorting...</a>
  172. </p><p>
  173.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  174. </p>
  175. </body>
  176. </html>
  177. <!--
  178.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  179.  * This work is hereby released into the Public Domain. 
  180.  * To view a copy of the public domain dedication, visit 
  181.  * http://creativecommons.org/licenses/publicdomain/ 
  182.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  183.  * Stanford, California 94305, USA.
  184. -->

EighthPass.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <page-specification class="tapestrytables.ValidateEditableColumnPage">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  18.         <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
  19.         
  20.         <bean name="numberValidator" class="org.apache.tapestry.valid.NumberValidator" lifecycle="page">
  21.             <set-property name="required" expression="false"/>
  22.             <set-property name="clientScriptingEnabled" expression="true"/>
  23.         </bean>
  24.         
  25.         <component id="form" type="Form">
  26.             <binding name="listener" expression="listeners.formSubmit"/>
  27.             <binding name="delegate" expression="beans.delegate"/>
  28.         </component>
  29.                 
  30.         <component id="table" type="contrib:FormTable">
  31.             <binding name="source" expression="dataItems"/>
  32.             <binding name="convertor" expression="dataItemConvertor"/>
  33.             <static-binding name="columns"
  34.                 value="
  35.                     SSN, 
  36.                     FirstName, 
  37.                     LastName, 
  38.                     =birthDateColumn, 
  39.                     Height, 
  40.                     Weight"/>
  41.             <binding name="rowsClass" expression="beans.evenOdd.next"/>
  42.             <binding name="pageSize" expression="6"/>
  43.             <static-binding  name="initialSortColumn" value="BirthDate"/>
  44.         </component>
  45.         <component id="WeightColumnValue" type="Block"/>
  46.         
  47.         <component id="editableWeight" type="ValidField">
  48.             <static-binding name="displayName">Weight</static-binding>
  49.             <binding name="value" expression="components.table.tableRow.Weight"/>
  50.             <binding name="size" expression="4"/>
  51.             <binding name="validator" expression='beans.numberValidator'/>
  52.         </component>
  53.         <component id="errors" type="Delegator">
  54.             <binding name="delegate" expression="beans.delegate.firstError"/>
  55.         </component>
  56. </page-specification>

EighthPass.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight

FifthPass.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Simple Editable Column</h1>
  7. <div class="note">
  8.     This page demonstrates how to implement a table with an editable column.
  9. </div>            
  10. <p>        
  11.     This example for using the Tapestry Table components is going to move
  12.     beyond the initial requirements.  We are now going to implement an editable column,
  13.     transforming the table from read-only to gathering user input.
  14. </p><p>
  15.     The table below allows the user to edit the <code>Weight</code> column.  Hopefully
  16.     these values are stable or heading down ;-)
  17. </p><p>
  18.     <form jwcid="@Form" listener="ognl:listeners.formSubmit">
  19.     <table class="mytable" jwcid="table@contrib:Table" 
  20.     source="ognl:dataItems"
  21.     columns="SSN, FirstName, LastName, 
  22.         =birthDateColumn, Height, Weight"
  23.     rowsClass="ognl:beans.evenOdd.next"
  24.     pageSize="6"
  25.     initialSortColumn="BirthDate">
  26.         <span jwcid="WeightColumnValue@Block">
  27.            <span jwcid="editableWeight@TextField" value="ognl:components.table.tableRow.Weight" size="4"/>
  28.         </span>
  29.         <th>SSN</th>
  30.         <th>First Name</th>
  31.         <th>Last Name</th>
  32.         <th>Birth Date</th>
  33.         <th>Height</th>
  34.         <th>Weight</th>
  35.         <tr class="even">
  36.             <td>123-44-5555</td>
  37.             <td>John</td>
  38.             <td>Reynolds</td>
  39.             <td>10/01/2004</td>
  40.             <td>5' 11"</td>
  41.             <td>185</td>
  42.         </tr>
  43.         <tr class="odd">
  44.             <td>123-44-5555</td>
  45.             <td>John</td>
  46.             <td>Reynolds</td>
  47.             <td>10/01/2004</td>
  48.             <td>5' 11"</td>
  49.             <td>185</td>
  50.         </tr>
  51.         <tr class="even">
  52.             <td>123-44-5555</td>
  53.             <td>John</td>
  54.             <td>Reynolds</td>
  55.             <td>10/01/2004"</td>
  56.             <td>5' 11"</td>
  57.             <td>185</td>
  58.         </tr>
  59.         <tr class="odd">
  60.             <td>123-44-5555</td>
  61.             <td>John</td>
  62.             <td>Reynolds</td>
  63.             <td>10/01/2004</td>
  64.             <td>5' 11"</td>
  65.             <td>185</td>
  66.         </tr>
  67.         <tr class="even">
  68.             <td>123-44-5555</td>
  69.             <td>John</td>
  70.             <td>Reynolds</td>
  71.             <td>10/01/2004</td>
  72.             <td>5' 11"</td>
  73.             <td>185</td>
  74.         </tr>
  75.         <tr class="odd">
  76.             <td>123-44-5555</td>
  77.             <td>John</td>
  78.             <td>Reynolds</td>
  79.             <td>10/01/2004</td>
  80.             <td>5' 11"</td>
  81.             <td>185</td>
  82.         </tr>
  83.     </table>
  84.     <input type="submit" value="Update"/>
  85.     </form>
  86. </p><p>
  87.     <b>Note:</b> The changes you make in the table on this page will not be submitted 
  88.     unless you press the <code>Update</code> button.  
  89.     Ideally any changes that the user makes would 
  90.     be submitted prior to paging or sorting the table.  
  91.     We'll take care of that later.  The really observant out there
  92.     have probably also noticed that the <code>Weight</code> column doesn't
  93.     validate the user's input.  We'll get around to dealing with that too.
  94. </p><p>
  95.     If you take a look at the files <code>FifthPass.html</code><code>FifthPass.page</code> 
  96.     and <code>EditableColumnPage.java</code>
  97.     you will see the changes made to make the <code>Weight</code> column editable.  
  98.     We've inserted a <code>TextField</code> component, but the same technique
  99.     could be used for other components.
  100. </p><p>
  101.     Here are the relevent HTML snippets from <code>FifthPass.html</code> 
  102.     that sets up this component:
  103. </p><p>
  104.     To begin, we had to wrap the <code>table</code> inside a form and we added a button
  105.     to submit any changes:
  106. </p><p>
  107. <code class="highlight">
  108.     <form jwcid="@Form" listener="ognl:listeners.formSubmit">
  109. </code>
  110. </p><p>
  111. <code class="highlight">
  112.     <input type="submit" value="Update"/>
  113. </code>
  114. </p><p>
  115.     We then made the following changes to the <code>Weight</code> column in the <code>table</code>:
  116. </p><p>
  117.    
  118. <code class="snippet"><pre>    
  119.     <table class="mytable" jwcid="table@contrib:Table" 
  120.     source="ognl:dataItems"
  121.     columns="SSN, FirstName, LastName, 
  122.     =birthDateColumn, Height,
  123.     <code class="highlight">Weight</code>"
  124.     rowsClass="ognl:beans.evenOdd.next"
  125.     pageSize="6"    
  126.     initialSortColumn="BirthDate">
  127. <code class="highlight">        
  128.     <span jwcid="WeightColumnValue@Block">
  129.     <span jwcid="editableWeight@TextField" value="ognl:components.table.tableRow.Weight" size="4"/>
  130.     </span>
  131. </code>
  132. </pre></code>        
  133. </p><p>
  134.     The expression <code>jwcid="WeightColumnValue@Block"</code> tells Tapestry to 
  135.     suspend normal processing when rendering values for the <code>Weight</code> column.
  136.     Instead of normal rendering, the <code>editableWeight</code> component 
  137.     (a <code>TextField</code>) will be displayed.
  138. </p><p>
  139.     The <code>editableWeight</code> gets its values by evaluating the expression 
  140.     <code>ognl:components.table.tableRow.Weight</code>.  In a nutshell, the
  141.     <code>getWeight()</code> is being called on the <code>DataItem</code> object
  142.     that represents the current row of the table.
  143. </p><p>
  144.     To process form submissions we had to change the <code>BasePage</code> derivative
  145.     that underlies this page.  This change is accomplished by making the following change to
  146.     <code>FifthPass.page</code>:
  147. </p><p>
  148. <code class="snippet">
  149. <page-specification 
  150.     <code class="highlight">class="tapestrytables.EditableColumnPage"</code>>
  151. </code>    
  152. </p><p>
  153.     With the additional requirement to process form submissions, we need to add a bit of code to our underlying <code>Page</code> object.  
  154.     <code>EditableColumnPage.java</code> is the result.
  155. </p><p>
  156.     Below is the code added to <code>EditableColumnPage.java</code> that handles
  157.     form submissions:
  158. </p><pre>
  159. <code class="highlight">
  160.     public void formSubmit(IRequestCycle cycle)
  161.     {
  162.         // Process the submitted form
  163.         List list = getDataItems();
  164.         // Do something to process the list changes
  165.         int count = list.size();
  166.         for (int i = 0; i < count; i++)
  167.         {
  168.             DataItem item = (DataItem) list.get(i);
  169.             System.out.println(item.getWeight());
  170.         }
  171.         // Always important to set peristent properties; otherwise changes
  172.         // made in this request cycle will be lost.  The framework
  173.         // makes a copy of the list.
  174.         setDataItems(list);
  175.     }
  176. </code>    
  177. </pre>
  178.     As you can see, it isn't very difficult make a column editable, 
  179.     but this example is unsatisfying because the user will lose changes
  180.     unless the <code>Update</code> button is pressed prior to paging or sorting.
  181.     A further problem concerns validating user input prior to updating the
  182.     source data.
  183. <p>
  184. </p><p>
  185. <a href="#" jwcid="@PageLink" page="SixthPass">Editable Column with Implicit Submit...</a>
  186. </p><p>
  187.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  188. </p>
  189. </body>
  190. </html>
  191. <!--
  192.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  193.  * This work is hereby released into the Public Domain. 
  194.  * To view a copy of the public domain dedication, visit 
  195.  * http://creativecommons.org/licenses/publicdomain/ 
  196.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  197.  * Stanford, California 94305, USA.
  198. -->

FifthPass.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <page-specification class="tapestrytables.EditableColumnPage">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  18.         
  19. </page-specification>

FifthPass.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight

FirstPass.html

  1. <html jwcid="@Shell" title="Tapestry Table Examples" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6. <h1>Paging and Sortable Table</h1>
  7. <div class="note">
  8.     This page demonstrates how to implement a multi-page table that is sortable
  9.     per column.
  10. </div>            
  11. <p>
  12.     This is our first pass at implementing the desired table using Tapestry components.
  13.     As mentioned before, the data that populates the table is coming from a Java
  14.     Bean.
  15. </p><p>
  16.     <table class="mytable" jwcid="table@contrib:Table"
  17.     source="ognl:dataItems"
  18.     columns="SSN, FirstName, LastName, BirthDate, Height, Weight">
  19.         <th>SSN</th>
  20.         <th>First Name</th>
  21.         <th>Last Name</th>
  22.         <th>Birth Date</th>
  23.         <th>Height</th>
  24.         <th>Weight</th>
  25.         <tr class="even">
  26.             <td>123-44-5555</td>
  27.             <td>John</td>
  28.             <td>Reynolds</td>
  29.             <td>10/01/2004</td>
  30.             <td>5' 11"</td>
  31.             <td>185</td>
  32.         </tr>
  33.         <tr class="odd">
  34.             <td>123-44-5555</td>
  35.             <td>John</td>
  36.             <td>Reynolds</td>
  37.             <td>10/01/2004</td>
  38.             <td>5' 11"</td>
  39.             <td>185</td>
  40.         </tr>
  41.         <tr class="even">
  42.             <td>123-44-5555</td>
  43.             <td>John</td>
  44.             <td>Reynolds</td>
  45.             <td>10/01/2004"</td>
  46.             <td>5' 11"</td>
  47.             <td>185</td>
  48.         </tr>
  49.         <tr class="odd">
  50.             <td>123-44-5555</td>
  51.             <td>John</td>
  52.             <td>Reynolds</td>
  53.             <td>10/01/2004</td>
  54.             <td>5' 11"</td>
  55.             <td>185</td>
  56.         </tr>
  57.         <tr class="even">
  58.             <td>123-44-5555</td>
  59.             <td>John</td>
  60.             <td>Reynolds</td>
  61.             <td>10/01/2004</td>
  62.             <td>5' 11"</td>
  63.             <td>185</td>
  64.         </tr>
  65.         <tr class="odd">
  66.             <td>123-44-5555</td>
  67.             <td>John</td>
  68.             <td>Reynolds</td>
  69.             <td>10/01/2004</td>
  70.             <td>5' 11"</td>
  71.             <td>185</td>
  72.         </tr>
  73.     </table>
  74.     
  75. </p><p>
  76.     If you take a look at the files <code>TapestryTables.application</code><code>FirstPass.html</code> and <code>FirstPass.page</code>
  77.     you will see that we
  78.     have accomplished a great deal of functionality with very little work.
  79.     The table on this page displays data from our <code>DataSource</code> Java Bean 
  80.     on multiple pages,  
  81.     a navigation component helps the user page through the table, and the table
  82.     is sortable on any column (Observant folks may notice that sorting on the 
  83.     <code>BirthDate</code> column isn't quite right.  We will address that 
  84.     <a href="#" jwcid="@PageLink" page="FourthPass">later</a>).
  85. </p><p>
  86.     Here is the relevent HTML snippet from <code>FirstPass.html</code> 
  87.     that sets up this component:
  88. </p><p>
  89.    
  90. <code class="highlight">    
  91.     <table class="mytable" jwcid="table@contrib:Table" 
  92. <br>
  93.     source="ognl:dataItems"
  94. <br>    
  95.     columns="SSN, FirstName, LastName, BirthDate, Height, Weight">
  96. </code>        
  97. </p><p>
  98.     The <code>source</code> is set up by adding the following lines to 
  99.     <code>FirstPass.page</code>:
  100. </p><p>
  101. <code clas="snippet">
  102. <page-specification 
  103.     <code class="highlight">
  104.         class="tapestrytables.FirstPass"</code>>
  105. <br>
  106.         <property-specification 
  107.     <code class="highlight">name="dataItems"</code> 
  108.         type="java.util.List" persistent="yes"/>
  109. </page-specification>
  110. </code>    
  111. </p><p>
  112.     In a nutshell, this page specification tells Tapestry to instantiate and maintain a persitent
  113.     <code>List</code> by invoking the method 
  114.     <code>tapestrytables.FirstPass.getDataItems()</code>
  115. </p><p>
  116.     Functionally, this page is pretty awesome, but the table doesn't look right.
  117.     We'll have to do some more work to match the vision of our HTML designer.
  118. </p><p>
  119. <a href="#" jwcid="@PageLink" page="SecondPass">Column Headings...</a>
  120. </p>
  121. <p>
  122.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  123. </p>
  124. </body>
  125. </html>
  126. <!--
  127.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/
  128.  * October 2004
  129.  * This work is hereby released into the Public Domain. 
  130.  * To view a copy of the public domain dedication, visit 
  131.  * http://creativecommons.org/licenses/publicdomain/ 
  132.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  133.  * Stanford, California 94305, USA.
  134. -->

FirstPass.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <page-specification class="tapestrytables.FirstPass">
  6.         <context-asset name="stylesheet" path="css/style.css"/>
  7.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  8. </page-specification>

FourthPass.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Custom Column Sorting</h1>
  7. <div class="note">  
  8.     This page demonstrates how to implement custom sorting on a column, how
  9.     to set the initial sort column, and how to disable sorting on a column.
  10. </div>            
  11. <p>
  12.     This is our fourth pass at implementing the table using Tapestry components.
  13.     Our third pass got the "look" of the page right, but we need to go back and
  14.     address the <code>Birth Date</code> column sorting problem we noticed earlier.
  15. </p><p>
  16. <div class="note">
  17.      <b>Note:</b>  We could avoid implementing a custom sort by simply returning a
  18.     <code>Date</code> object from the underlying <code>DataItem.getBirthDate()</code>
  19.     but I wanted to demonstrate custom column sorting.
  20. </div>        
  21. </p><p>
  22.     By default, the sorting is based on the "type" of the data item rendered
  23.     for each column.  Our <code>Birth Date</code> column contains <code>Strings</code> in MM/DD/YYYY format,
  24.     so a simple string compare won't suffice.  The following table correctly sorts on the 
  25.     <code>BirthDate</code> column: 
  26. </p><p>
  27.     <table class="mytable" jwcid="table@contrib:Table"
  28.     source="ognl:dataItems"
  29.     columns="SSN, !FirstName, LastName, 
  30.         =birthDateColumn, Height, Weight"
  31.     rowsClass="ognl:beans.evenOdd.next"
  32.     pageSize="6"    
  33.     initialSortColumn="BirthDate">
  34.         <th>SSN</th>
  35.         <th>First Name</th>
  36.         <th>Last Name</th>
  37.         <th>Birth Date</th>
  38.         <th>Height</th>
  39.         <th>Weight</th>
  40.         <tr class="even">
  41.             <td>123-44-5555</td>
  42.             <td>John</td>
  43.             <td>Reynolds</td>
  44.             <td>10/01/2004</td>
  45.             <td>5' 11"</td>
  46.             <td>185</td>
  47.         </tr>
  48.         <tr class="odd">
  49.             <td>123-44-5555</td>
  50.             <td>John</td>
  51.             <td>Reynolds</td>
  52.             <td>10/01/2004</td>
  53.             <td>5' 11"</td>
  54.             <td>185</td>
  55.         </tr>
  56.         <tr class="even">
  57.             <td>123-44-5555</td>
  58.             <td>John</td>
  59.             <td>Reynolds</td>
  60.             <td>10/01/2004"</td>
  61.             <td>5' 11"</td>
  62.             <td>185</td>
  63.         </tr>
  64.         <tr class="odd">
  65.             <td>123-44-5555</td>
  66.             <td>John</td>
  67.             <td>Reynolds</td>
  68.             <td>10/01/2004</td>
  69.             <td>5' 11"</td>
  70.             <td>185</td>
  71.         </tr>
  72.         <tr class="even">
  73.             <td>123-44-5555</td>
  74.             <td>John</td>
  75.             <td>Reynolds</td>
  76.             <td>10/01/2004</td>
  77.             <td>5' 11"</td>
  78.             <td>185</td>
  79.         </tr>
  80.         <tr class="odd">
  81.             <td>123-44-5555</td>
  82.             <td>John</td>
  83.             <td>Reynolds</td>
  84.             <td>10/01/2004</td>
  85.             <td>5' 11"</td>
  86.             <td>185</td>
  87.         </tr>
  88.     </table>
  89.     
  90. </p><p>
  91.     If you take a look at the files <code>FouthPass.html</code><code>FourthPass.page</code> 
  92.     and <code>CustomSortColumnPage.java</code>
  93.     you will see the changes made to get the <code>Birth Date</code> column to sort properly.
  94. </p><p>
  95.     Here is the relevent HTML snippet from <code>FourthPass.html</code> 
  96.     that sets up this component:
  97. <pre><code class="snippet">    
  98.     <table class="mytable" jwcid="table@contrib:Table" 
  99.     source="ognl:dataItems"
  100.     columns="SSN, <code class="highlight">!FirstName</code>, LastName, <code class="highlight">=birthDateColumn</code>, Height, Weight"    
  101.     rowsClass="ognl:beans.evenOdd.next"
  102.     pageSize="6" 
  103.     <code class="highlight">initialSortColumn="BirthDate"</code>>
  104. </code>
  105. </pre>        
  106. </p><p>
  107.     To demonstrate that you can disable sorting on a column I simply preceded the column ID <code>FirstName</code> with a '!'.
  108. </p><p>
  109.     To make it more obvious that sorting is working for this example, I set the 
  110.     initial sort column to the birth date column by setting the following <code>Table</code> attribute:
  111.     <code>initialSortColumn="BirthDate"</code> ("BirthDate" is the ID of the column).
  112. </p><p>
  113.     Custom sorting is a bit more involved.
  114.     The expression <code>=birthDateColumn</code> tells Tapestry to get an ITableColumn
  115.     object for this column from a method named
  116.     <code>getBirthDateColumn()</code>.
  117. </p><p>
  118.     To define this object, we'll have to change the <code>BasePage</code> derivative
  119.     that underlies our page.  This is accomplished by making the following change to
  120.     <code>FourthPass.page</code>:
  121. </p><p>
  122. <code class="snippet">
  123. <page-specification 
  124.     <code class="highlight">class="tapestrytables.CustomSortColumnPage"</code>>
  125. </code>    
  126. </p><p>
  127.     Up until this example, all of our pages have been using the same 
  128.     <code>BasePage</code> derivative.  With the additional requirement to implement
  129.     custom sorting for one of the columns, we need to add a bit of code.  
  130.     <code>CustomSortColumnPage.java</code> is the result.
  131. </p><p>
  132.     Below is the code added to <code>CustomSortColumnPage.java</code> that provides custom 
  133.     sorting on the <code>BirthDate</code> column:
  134. </p><p>
  135. <pre><code class="highlight">
  136.     public ITableColumn getBirthDateColumn()
  137.     {
  138.         // The column value is extracted in a custom evaluator class
  139.         SimpleTableColumn birthDateColumn =  
  140.            new SimpleTableColumn("Birth Date", new BirthDateColumnEvaluator(), true);
  141.         birthDateColumn.setColumnComparator(new BirthDateComparator());
  142.         return birthDateColumn;
  143.     }
  144.     /**
  145.      * A class defining the logic for getting the BirthDate from a DataItem
  146.      */
  147.     private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
  148.     {
  149.         /**
  150.          * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
  151.          */
  152.         public Object getColumnValue(ITableColumn objColumn, Object objRow)
  153.         {
  154.             DataItem dataItem = (DataItem) objRow;
  155.             return dataItem.getBirthDate();
  156.         }
  157.     }
  158. </code></pre>    
  159. </p><p>
  160.     Not shown here is the custom comparator that I created to compare two 
  161.     <code>BirthDate</code> strings.  My <code>BirthDateComparator.java</code> is an 
  162.     embarrassing hack, but it's sufficient to make this example work.
  163. </p><p>
  164.     At this point, our read-only table is pretty much complete.  There are a few more
  165.     tweaks we could perform, but it's probably more interesting to move on to embedding
  166.     components for individual fields in the table.
  167. </p><p>
  168. <a href="#" jwcid="@PageLink" page="FifthPass">Simple Editable Column...</a>
  169. </p><p>
  170.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  171. </p>
  172. </body>
  173. </html>
  174. <!--
  175.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  176.  * This work is hereby released into the Public Domain. 
  177.  * To view a copy of the public domain dedication, visit 
  178.  * http://creativecommons.org/licenses/publicdomain/ 
  179.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  180.  * Stanford, California 94305, USA.
  181. -->
FourthPass.page

 

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <page-specification class="tapestrytables.CustomSortColumnPage">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  18.         
  19. </page-specification>

FourthPass.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight

Home.html

  1. <html jwcid="@Shell" title="Using The Tapestry Table Control" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Using The Tapestry Table Control</h1> 
  7. <div class="note">    
  8.     by John Reynolds: Updated on October 26th 2004
  9. </div>
  10. <p>
  11.     This application demonstrates some common ways to use the Tapestry Table components.  
  12.     Thanks to
  13.     Howard Lewis Ship and the many subscribers of the Tapestry Users List who offered 
  14.     suggestions and guidance. 
  15. </p><p>
  16.     The Table component and its supporting cast of components are very powerful
  17.     and very flexible.  This is a double-edged sword that can result in confusion 
  18.     when first learning how to use these components.
  19. </p><p>
  20.     This application provides a series of pages that demonstrate one way of configuring
  21.     the Table to produce desired behaviors.  The chosen techniques may not be optimal,
  22.     but hopefully they will be understandable and will help you figure out how to reach
  23.     your own objectives.    
  24. </p><p>
  25.     Below is a standard HTML table that will serve as the basis for all of the 
  26.     examples.
  27.     A guiding principal of Tapestry is to preserve the ability to view the HTML 
  28.     templates in a standard browser.  In the spirit of this principal, I will use
  29.     the following HTML table as the starting point for all that follows:
  30. </p><p>
  31.     <table class="mytable">
  32.         <th>SSN</th>
  33.         <th>First Name</th>
  34.         <th>Last Name</th>
  35.         <th>Birth Date</th>
  36.         <th>Height</th>
  37.         <th>Weight</th>
  38.         <tr class="even">
  39.             <td>123-44-5555</td>
  40.             <td>John</td>
  41.             <td>Reynolds</td>
  42.             <td>06/02/1960</td>
  43.             <td>5' 11"</td>
  44.             <td>185</td>
  45.         </tr>
  46.         <tr class="odd">
  47.             <td>123-44-5555</td>
  48.             <td>John</td>
  49.             <td>Reynolds</td>
  50.             <td>06/02/1960</td>
  51.             <td>5' 11"</td>
  52.             <td>185</td>
  53.         </tr>
  54.         <tr class="even">
  55.             <td>123-44-5555</td>
  56.             <td>John</td>
  57.             <td>Reynolds</td>
  58.             <td>06/02/1960"</td>
  59.             <td>5' 11"</td>
  60.             <td>185</td>
  61.         </tr>
  62.         <tr class="odd">
  63.             <td>123-44-5555</td>
  64.             <td>John</td>
  65.             <td>Reynolds</td>
  66.             <td>06/02/1960</td>
  67.             <td>5' 11"</td>
  68.             <td>185</td>
  69.         </tr>
  70.         <tr class="even">
  71.             <td>123-44-5555</td>
  72.             <td>John</td>
  73.             <td>Reynolds</td>
  74.             <td>10/01/2004</td>
  75.             <td>5' 11"</td>
  76.             <td>185</td>
  77.         </tr>
  78.         <tr class="odd">
  79.             <td>123-44-5555</td>
  80.             <td>John</td>
  81.             <td>Reynolds</td>
  82.             <td>10/01/2004</td>
  83.             <td>5' 11"</td>
  84.             <td>185</td>
  85.         </tr>
  86.     </table>
  87. </p><p>
  88.     The previous table is representative of the input that a Tapestry developer might
  89.     receive from an HTML designer.  The table reflects the desired layout of the 
  90.     columns and demonstrates the desired "look
  91.     and feel" by using a css style sheet to dictate the appearance of the
  92.     table.
  93. </p><p>
  94.     The data displayed by the table on this page is hard-coded.  The "real" data will be supplied
  95.     by a Java Bean, and the data set will contain many more rows then conveniently fit
  96.     on a single page.  The final application will split the data into multiple pages and 
  97.     allow sorting on any column of the table... but we're getting ahead of ourselves...
  98. </p><p>
  99. <a href="#" jwcid="@PageLink" page="FirstPass">Basic Paging and Sortable Table...</a>
  100. </p><p>
  101. <a href="#" jwcid="@PageLink" page="SecondPass">Column Headings...</a>
  102. </p><p>
  103. <a href="#" jwcid="@PageLink" page="ThirdPass">Alternating Row Colors...</a>
  104. </p><p>
  105. <a href="#" jwcid="@PageLink" page="FourthPass">Custom Column Sorting...</a>
  106. </p><p>
  107. <a href="#" jwcid="@PageLink" page="FifthPass">Simple Editable Column...</a>
  108. </p><p>
  109. <a href="#" jwcid="@PageLink" page="SixthPass">Editable Column with Implicit Submit...</a>
  110. </p><p>
  111. <a href="#" jwcid="@PageLink" page="SeventhPass">Editable Columns using Formal Parameter Coding Style...</a>
  112. </p><p>
  113. <a href="#" jwcid="@PageLink" page="EighthPass">Validating Editable Columns...</a>
  114. </p><p>
  115. <a href="#" jwcid="@PageLink" page="NinthPass">Combining Validation and Sorting...</a>
  116. </p><p>
  117. <a href="#" jwcid="@PageLink" page="DirectLinkColumn">Direct Link Columns...</a>
  118. </p><p>
  119. <a href="#" jwcid="@PageLink" page="ColumnChooser">Choosing and Ordering Columns...</a>
  120. </p><p>
  121. <a href="#" jwcid="@PageLink" page="TenthPass">Using TableView, TableColumns, and TableFormRows..</a>
  122. <a href="#" jwcid="@PageLink" page="Test">.</a>
  123. </p>
  124. </body>
  125. </html>
  126. <!--
  127.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/
  128.  * October 2004
  129.  * This work is hereby released into the Public Domain. 
  130.  * To view a copy of the public domain dedication, visit 
  131.  * http://creativecommons.org/licenses/publicdomain/ 
  132.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  133.  * Stanford, California 94305, USA.
  134. -->

Home.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <page-specification class="org.apache.tapestry.html.BasePage">
  15.     <description><![CDATA[   This is the home page   ]]></description>
  16.     <context-asset name="stylesheet" path="css/style.css"/>
  17. </page-specification>

NinthPass.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Combining Validation and Sorting</h1>
  7. <div class="note">
  8.     This page demonstrates how to implement an editable column that must be validated
  9.     and has custom sorting.
  10. </div>            
  11. <p>
  12.     It's sometimes necessary to combine validation and custom sorting.  This is actually
  13.     very easy to do, and it's demonstrated below by making the Birth Date column editable
  14.     while preserving the earlier custom sorting:
  15. </p><p>
  16.     <form jwcid="form">
  17.     <table class="mytable" jwcid="table">
  18.         <span jwcid="BirthDateColumnValue@Block">
  19.            <span jwcid="editableBirthDate"/>
  20.         </span>
  21.         <span jwcid="WeightColumnValue@Block">
  22.            <span jwcid="editableWeight"/>
  23.         </span>
  24.         <th>SSN</th>
  25.         <th>First Name</th>
  26.         <th>Last Name</th>
  27.         <th>Birth Date</th>
  28.         <th>Height</th>
  29.         <th>Weight</th>
  30.         <tr class="even">
  31.             <td>123-44-5555</td>
  32.             <td>John</td>
  33.             <td>Reynolds</td>
  34.             <td>10/01/2004</td>
  35.             <td>5' 11"</td>
  36.             <td>185</td>
  37.         </tr>
  38.         <tr class="odd">
  39.             <td>123-44-5555</td>
  40.             <td>John</td>
  41.             <td>Reynolds</td>
  42.             <td>10/01/2004</td>
  43.             <td>5' 11"</td>
  44.             <td>185</td>
  45.         </tr>
  46.         <tr class="even">
  47.             <td>123-44-5555</td>
  48.             <td>John</td>
  49.             <td>Reynolds</td>
  50.             <td>10/01/2004"</td>
  51.             <td>5' 11"</td>
  52.             <td>185</td>
  53.         </tr>
  54.         <tr class="odd">
  55.             <td>123-44-5555</td>
  56.             <td>John</td>
  57.             <td>Reynolds</td>
  58.             <td>10/01/2004</td>
  59.             <td>5' 11"</td>
  60.             <td>185</td>
  61.         </tr>
  62.         <tr class="even">
  63.             <td>123-44-5555</td>
  64.             <td>John</td>
  65.             <td>Reynolds</td>
  66.             <td>10/01/2004</td>
  67.             <td>5' 11"</td>
  68.             <td>185</td>
  69.         </tr>
  70.         <tr class="odd">
  71.             <td>123-44-5555</td>
  72.             <td>John</td>
  73.             <td>Reynolds</td>
  74.             <td>10/01/2004</td>
  75.             <td>5' 11"</td>
  76.             <td>185</td>
  77.         </tr>
  78.     </table>
  79.     <input type="submit" value="Update"/>
  80.     <span class="inputerror"><span jwcid="errors"/></span>
  81.     </form>
  82.     
  83. </p><p>
  84. </p><p>
  85.     If you take a look at the files <code>NinthPass.page</code> 
  86.     and <code>ValidateEditableColumnPage2.page</code> 
  87.     you will see the changes necessary to validate the user's input.
  88. </p><p>
  89.     Here are the relevent snippets from <code>NinthPass.page</code> 
  90.     that sets up validation for the <code>BirthDate</code> using the 
  91.     bundled <code>PatternValidator</code> class:
  92. <pre>
  93. <code class="highlight">
  94.    <bean name="birthDateValidator" class="org.apache.tapestry.valid.PatternValidator" lifecycle="page">
  95.        <set-property name="required" expression="true"/>
  96.        <set-property name="clientScriptingEnabled" expression="true"/>
  97.        <set-property name="patternString">"//d//d///d//d///d//d//d//d$"</set-property> <
  98.        <set-property name="patternNotMatchedMessage">
  99.            "Error: Date improperly formatted.  Should be like: MM/DD/YYYY"</set-property>
  100.    </bean>
  101.    <component id="editableBirthDate" type="ValidField">
  102.        <static-binding name="displayName">Weight</static-binding>
  103.        <binding name="value" expression="components.table.tableRow.BirthDate"/>
  104.        <binding name="size" expression="4"/>
  105.        <binding name="validator" expression='beans.birthDateValidator'/>
  106.    </component>
  107. </code>        
  108. </pre>
  109. </p><p>
  110.     Here is the relevent snippet from <code>NinthPass.html</code> 
  111.     that sets up validation for the <code>BirthDate</code>:
  112. <pre>
  113. <code class="snippet">
  114.     <table class="mytable" jwcid="table">
  115. <code class="highlight">        <span jwcid="BirthDateColumnValue@Block">
  116.            <span jwcid="editableBirthDate"/>
  117.         </span>
  118. </code>        <span jwcid="WeightColumnValue@Block">
  119.            <span jwcid="editableWeight"/>
  120.         </span>
  121. </code>        
  122. </pre>    
  123. </p><p>
  124.     Finally, here is the relevent snippet from <code>ValidateEditableColumnPage2.java</code> 
  125.     that picks up the <code>ValidField</code> component for the <code>BirthDate</code>:
  126. <pre>
  127. <code class="snippet">
  128.     public ITableColumn getBirthDateColumn()
  129.     {
  130.         // The column value is extracted in a custom evaluator class
  131.         SimpleTableColumn birthDateColumn =  new SimpleTableColumn("BirthDate", new BirthDateColumnEvaluator(), true);
  132.         birthDateColumn.setColumnComparator(new BirthDateComparator());
  133. <code class="highlight">        // Pick up any settings from the template and page
  134.         birthDateColumn.loadSettings(this);
  135. </code>
  136.         return birthDateColumn;
  137.     }
  138. </code>    
  139. </pre>
  140. </p><p>
  141.     The method <code>birthDateColumn.loadSettings(this)</code> picks up any relevent
  142.     Blocks defined for <code>BirthDate</code> in the template of this page, exactly as if
  143.     the column was defined in the standard way.
  144. </p><p>
  145. <a href="#" jwcid="@PageLink" page="DirectLinkColumn">Direct Link Columns...</a>
  146. </p><p>
  147.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  148. </p>
  149. </body>
  150. </html>
  151. <!--
  152.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  153.  * This work is hereby released into the Public Domain. 
  154.  * To view a copy of the public domain dedication, visit 
  155.  * http://creativecommons.org/licenses/publicdomain/ 
  156.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  157.  * Stanford, California 94305, USA.
  158. -->

NinthPass.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <page-specification class="tapestrytables.ValidateEditableColumnPage2">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  18.         <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
  19.         
  20.         <bean name="numberValidator" class="org.apache.tapestry.valid.NumberValidator" lifecycle="page">
  21.             <set-property name="required" expression="true"/>
  22.             <set-property name="clientScriptingEnabled" expression="false"/>
  23.         </bean>
  24.         <bean name="birthDateValidator" class="org.apache.tapestry.valid.PatternValidator" lifecycle="page">
  25.             <set-property name="required" expression="true"/>
  26.             <set-property name="clientScriptingEnabled" expression="false"/>
  27.             <set-property name="patternString">"//d//d///d//d///d//d//d//d$"</set-property> 
  28.             <set-property name="patternNotMatchedMessage">
  29.                 "Error: Date improperly formatted.  Should be like: MM/DD/YYYY"</set-property>
  30.         </bean>
  31.         
  32.         <component id="form" type="Form">
  33.             <binding name="listener" expression="listeners.formSubmit"/>
  34.             <binding name="delegate" expression="beans.delegate"/>
  35.         </component>
  36.                 
  37.         <component id="table" type="contrib:FormTable">
  38.             <binding name="source" expression="dataItems"/>
  39.             <binding name="convertor" expression="dataItemConvertor"/>
  40.             <static-binding name="columns"
  41.                 value="
  42.                     SSN, 
  43.                     FirstName, 
  44.                     LastName, 
  45.                     =birthDateColumn, 
  46.                     Height, 
  47.                     Weight"/>
  48.             <binding name="rowsClass" expression="beans.evenOdd.next"/>
  49.             <binding name="pageSize" expression="6"/>
  50.             <static-binding  name="initialSortColumn" value="BirthDate"/>
  51.         </component>
  52.         <component id="editableBirthDate" type="ValidField">
  53.             <static-binding name="displayName">Weight</static-binding>
  54.             <binding name="value" expression="components.table.tableRow.BirthDate"/>
  55.             <binding name="size" expression="10"/>
  56.             <binding name="validator" expression='beans.birthDateValidator'/>
  57.         </component>
  58.         
  59.         <component id="editableWeight" type="ValidField">
  60.             <static-binding name="displayName">Weight</static-binding>
  61.             <binding name="value" expression="components.table.tableRow.Weight"/>
  62.             <binding name="size" expression="4"/>
  63.             <binding name="validator" expression='beans.numberValidator'/>
  64.         </component>
  65.         <component id="errors" type="Delegator">
  66.             <binding name="delegate" expression="beans.delegate.firstError"/>
  67.         </component>
  68. </page-specification>

NinthPass.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight

SecondPass.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.         <h1>Column Headings</h1>
  7. <div class="note">
  8.     This page demonstrates how to get column names from a property file.
  9. </div>            
  10. <p>
  11.     This is our second attempt to implement the table using Tapestry components.
  12.     Our first pass was functionally awesome, but the "look" of the page left
  13.     much to be desired.  In the table below, you will see that we've cleaned
  14.     up the column names:
  15. </p><p>
  16.     <table class="mytable" jwcid="table@contrib:Table"
  17.     source="ognl:dataItems"
  18.     columns="SSN, FirstName, LastName, 
  19.         BirthDate, Height, Weight">
  20.         <th>SSN</th>
  21.         <th>First Name</th>
  22.         <th>Last Name</th>
  23.         <th>Birth Date</th>
  24.         <th>Height</th>
  25.         <th>Weight</th>
  26.         <tr class="even">
  27.             <td>123-44-5555</td>
  28.             <td>John</td>
  29.             <td>Reynolds</td>
  30.             <td>06/02/1960</td>
  31.             <td>5' 11"</td>
  32.             <td>185</td>
  33.         </tr>
  34.         <tr class="odd">
  35.             <td>123-44-5555</td>
  36.             <td>John</td>
  37.             <td>Reynolds</td>
  38.             <td>06/02/1960</td>
  39.             <td>5' 11"</td>
  40.             <td>185</td>
  41.         </tr>
  42.         <tr class="even">
  43.             <td>123-44-5555</td>
  44.             <td>John</td>
  45.             <td>Reynolds</td>
  46.             <td>06/02/1960"</td>
  47.             <td>5' 11"</td>
  48.             <td>185</td>
  49.         </tr>
  50.         <tr class="odd">
  51.             <td>123-44-5555</td>
  52.             <td>John</td>
  53.             <td>Reynolds</td>
  54.             <td>06/02/1960</td>
  55.             <td>5' 11"</td>
  56.             <td>185</td>
  57.         </tr>
  58.         <tr class="even">
  59.             <td>123-44-5555</td>
  60.             <td>John</td>
  61.             <td>Reynolds</td>
  62.             <td>06/02/1960</td>
  63.             <td>5' 11"</td>
  64.             <td>185</td>
  65.         </tr>
  66.         <tr class="odd">
  67.             <td>123-44-5555</td>
  68.             <td>John</td>
  69.             <td>Reynolds</td>
  70.             <td>06/02/1960</td>
  71.             <td>5' 11"</td>
  72.             <td>185</td>
  73.         </tr>
  74.     </table>
  75.     
  76. </p><p>
  77.     If you take a look at the file <code>SecondPass.properties</code> 
  78.     you will see what we had to do to improve the "look" of this page.
  79.     The files <code>SecondPass.html</code> and <code>SecondPass.page</code>
  80.     are just renamed copies of the files from the previous example.
  81. </p><p>      
  82.     When you create a properties file, 
  83.     the properties defined in the file will override any column names defined in 
  84.     the "page" or html "template".
  85.     For example, the title for the <code>BirthDate</code> column on this page is coming from  
  86.     <code>SecondPass.properties</code>.  
  87.     The string '<code>BirthBirthDate = Birth Date</code>' overrides any setting in
  88.     <code>SecondPass.html</code>. This is a very
  89.     valuable technique, especially when you want to internationalize your applications.
  90. </p><p>
  91.     Here are the property definitions from <code>SecondPass.properties</code>:
  92. <pre><code class="highlight">
  93. SSNSSN = SSN
  94. FirstFirstName = First Name
  95. LastLastName = Last Name
  96. BirthBirthDate = Birth Date
  97. HeightHeight = Height
  98. WeightWeight = Weight
  99. </code></pre>    
  100. </p><p>
  101.     
  102.     We still haven't achieved the "look" that we want, but we are getting closer.
  103. </p><p>
  104. <a href="#" jwcid="@PageLink" page="ThirdPass">Alternating Row Colors...</a>
  105. </p><p>
  106.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  107. </p>
  108. </body>
  109. </html>
  110. <!--
  111.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  112.  * This work is hereby released into the Public Domain. 
  113.  * To view a copy of the public domain dedication, visit 
  114.  * http://creativecommons.org/licenses/publicdomain/ 
  115.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  116.  * Stanford, California 94305, USA.
  117. -->

SecondPass.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <page-specification class="tapestrytables.FirstPass">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17. </page-specification>

SecondPass.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight

SeventhPass.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Editable Columns using Formal Parameter Coding Style</h1>
  7. <div class="note">
  8.     This page demonstrates how to use Tapestry's "formal" parameter style to 
  9.     more cleanly divide the HTML from the component specifications.
  10. </div>            
  11. <p>        
  12.     This page has the same functionality as the 
  13.     <a href="#" jwcid="@PageLink" page="SixthPass">Editable Column with Implicit Submit</a>
  14.     example, but I have
  15.     switched from specifying details in the <code>html</code> file to specifying
  16.     details in the <code>page</code> file.  This is referred to as using <code>formal</code>
  17.     parameters.
  18. </p><p>
  19.     <form jwcid="form">
  20.     <table class="mytable" jwcid="table">
  21.         <span jwcid="WeightColumnValue">
  22.            <span jwcid="editableWeight"/>
  23.         </span>
  24.         <th>SSN</th>
  25.         <th>First Name</th>
  26.         <th>Last Name</th>
  27.         <th>Birth Date</th>
  28.         <th>Height</th>
  29.         <th>Weight</th>
  30.         <tr class="even">
  31.             <td>123-44-5555</td>
  32.             <td>John</td>
  33.             <td>Reynolds</td>
  34.             <td>10/01/2004</td>
  35.             <td>5' 11"</td>
  36.             <td>185</td>
  37.         </tr>
  38.         <tr class="odd">
  39.             <td>123-44-5555</td>
  40.             <td>John</td>
  41.             <td>Reynolds</td>
  42.             <td>10/01/2004</td>
  43.             <td>5' 11"</td>
  44.             <td>185</td>
  45.         </tr>
  46.         <tr class="even">
  47.             <td>123-44-5555</td>
  48.             <td>John</td>
  49.             <td>Reynolds</td>
  50.             <td>10/01/2004"</td>
  51.             <td>5' 11"</td>
  52.             <td>185</td>
  53.         </tr>
  54.         <tr class="odd">
  55.             <td>123-44-5555</td>
  56.             <td>John</td>
  57.             <td>Reynolds</td>
  58.             <td>10/01/2004</td>
  59.             <td>5' 11"</td>
  60.             <td>185</td>
  61.         </tr>
  62.         <tr class="even">
  63.             <td>123-44-5555</td>
  64.             <td>John</td>
  65.             <td>Reynolds</td>
  66.             <td>10/01/2004</td>
  67.             <td>5' 11"</td>
  68.             <td>185</td>
  69.         </tr>
  70.         <tr class="odd">
  71.             <td>123-44-5555</td>
  72.             <td>John</td>
  73.             <td>Reynolds</td>
  74.             <td>10/01/2004</td>
  75.             <td>5' 11"</td>
  76.             <td>185</td>
  77.         </tr>
  78.     </table>
  79.     <input type="submit" value="Update"/>
  80.     </form>
  81.     
  82. </p><p>
  83. </p><p>
  84.     If you take a look at the files <code>SeventhPass.html</code>
  85.     and <code>SeventhPass.page</code>
  86.     you will notice significant changes from the earlier <code>html</code> and
  87.     <code>page</code> files.  This is more a matter of style rather then substance,
  88.     switching from the use of informal parameters to formal parameters.  Generally,
  89.     more sophisticated pages benefit from formal parameters by reducing the "clutter"
  90.     in the <code>html</code> file.
  91. </p><p>
  92.     Here are the relevent HTML snippets from <code>SeventhPass.html</code> 
  93.     that sets up this component:
  94. </p><p>
  95.    
  96. <code class="highlight">
  97.     <form jwcid="form">
  98. <br>        <table class="mytable" jwcid="table">
  99. <br>        <span jwcid="WeightColumnValue">
  100. <br>           <span jwcid="editableWeight"/>
  101. <br>        </span>
  102. </code>        
  103. </p><p>
  104.     As you can see, this is much less invasive.
  105. </p><p>
  106.     Here is the relevent snippets from <code>SeventhPass.page</code> 
  107.     that sets up this component:
  108. </p><p>
  109.    
  110. <code class="highlight">
  111.     <pre>
  112. <component id="form" type="Form">
  113.     <binding name="listener" expression="listeners.formSubmit">
  114. </component>
  115. <component id="table" type="contrib:FormTable">
  116.     <binding name="source" expression="dataItems"/>
  117.     <binding name="convertor" expression="dataItemConvertor"/>
  118.     <static-binding name="columns"
  119.         value="
  120.             SSN, 
  121.             FirstName, 
  122.             LastName, 
  123.             =birthDateColumn, 
  124.             Height, 
  125.             Weight"/>
  126.     <binding name="rowsClass" expression="beans.evenOdd.next"/>
  127.     <binding name="pageSize" expression="6"/>
  128.     <static-binding  name="initialSortColumn" value="BirthDate"/>
  129. </component>
  130. <component id="WeightColumnValue" type="Block"/>
  131. <component id="editableWeight" type="TextField">
  132.     <binding name="value" expression="components.table.tableRow.Weight"/>
  133.     <binding name="size" expression="4"/>
  134. </component>
  135.     </pre>    
  136. </code>
  137. </p><p>
  138.     As you can see, the world isn't quite perfect.  You must indicate on the
  139.     <code>html</code> template whenever you wish to override the rendering of
  140.     a column in a table even though the component is specified in the 
  141.     <code>page</code> file.  Judging from the Tapestry Users List, this seems 
  142.     to trip up newbies quite often.
  143. </p><p>
  144.     Now that we've changed coding styles, it's time to get back to adding 
  145.     functionality.
  146. </p><p>
  147. <a href="#" jwcid="@PageLink" page="EighthPass">Validating Editable Columns...</a>
  148. </p><p>
  149.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  150. </p>
  151. </body>
  152. </html>
  153. <!--
  154.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  155.  * This work is hereby released into the Public Domain. 
  156.  * To view a copy of the public domain dedication, visit 
  157.  * http://creativecommons.org/licenses/publicdomain/ 
  158.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  159.  * Stanford, California 94305, USA.
  160. -->

SeventhPass.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->

  14. <page-specification class="tapestrytables.EditableColumnPage2">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>

  18.         <component id="form" type="Form">
  19.             <binding name="listener" expression="listeners.formSubmit"/>
  20.         </component>

  21.         <component id="table" type="contrib:FormTable">
  22.             <binding name="source" expression="dataItems"/>
  23.             <binding name="convertor" expression="dataItemConvertor"/>
  24.             <static-binding name="columns"
  25.                 value="
  26.                     SSN, 
  27.                     FirstName, 
  28.                     LastName, 
  29.                     =birthDateColumn, 
  30.                     Height, 
  31.                     Weight"/>
  32.             <binding name="rowsClass" expression="beans.evenOdd.next"/>
  33.             <binding name="pageSize" expression="6"/>
  34.             <static-binding  name="initialSortColumn" value="BirthDate"/>
  35.         </component>

  36.         <component id="WeightColumnValue" type="Block"/>
  37.         <component id="editableWeight" type="TextField">
  38.             <binding name="value" expression="components.table.tableRow.Weight"/>
  39.             <binding name="size" expression="4"/>
  40.         </component>

  41. </page-specification>

SeventhPass.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight
SixthPass.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Editable Column with Implicit Submit</h1>
  7. <div class="note">
  8.     This page demonstrates how to implement a table with an editable column
  9.     that saves changes when "paging" or "sorting" the table.
  10. </div>            
  11. <p>        
  12.     The first implementation of an editable column had a few drawbacks, one
  13.     of which was the requirement to press the <code>Update</code> button
  14.     to submit changes.
  15. </p><p>
  16.     The table below captures changes before changing the sort order or moving
  17.     to another page:
  18. </p><p>
  19.     <form jwcid="@Form" listener="ognl:listeners.formSubmit"  >
  20.     <table class="mytable" jwcid="table@contrib:FormTable"
  21.     source="ognl:dataItems"
  22.     convertor="ognl:dataItemConvertor"
  23.     columns="SSN, FirstName, LastName, 
  24.         =birthDateColumn, Height, Weight"
  25.     rowsClass="ognl:beans.evenOdd.next"
  26.     pageSize="6"
  27.     initialSortColumn="BirthDate"    >
  28.         <span jwcid="WeightColumnValue@Block">
  29.            <span jwcid="editableWeight@TextField" value="ognl:components.table.tableRow.Weight" size="4"/>
  30.         </span>
  31.         <th>SSN</th>
  32.         <th>First Name</th>
  33.         <th>Last Name</th>
  34.         <th>Birth Date</th>
  35.         <th>Height</th>
  36.         <th>Weight</th>
  37.         <tr class="even">
  38.             <td>123-44-5555</td>
  39.             <td>John</td>
  40.             <td>Reynolds</td>
  41.             <td>10/01/2004</td>
  42.             <td>5' 11"</td>
  43.             <td>185</td>
  44.         </tr>
  45.         <tr class="odd">
  46.             <td>123-44-5555</td>
  47.             <td>John</td>
  48.             <td>Reynolds</td>
  49.             <td>10/01/2004</td>
  50.             <td>5' 11"</td>
  51.             <td>185</td>
  52.         </tr>
  53.         <tr class="even">
  54.             <td>123-44-5555</td>
  55.             <td>John</td>
  56.             <td>Reynolds</td>
  57.             <td>10/01/2004"</td>
  58.             <td>5' 11"</td>
  59.             <td>185</td>
  60.         </tr>
  61.         <tr class="odd">
  62.             <td>123-44-5555</td>
  63.             <td>John</td>
  64.             <td>Reynolds</td>
  65.             <td>10/01/2004</td>
  66.             <td>5' 11"</td>
  67.             <td>185</td>
  68.         </tr>
  69.         <tr class="even">
  70.             <td>123-44-5555</td>
  71.             <td>John</td>
  72.             <td>Reynolds</td>
  73.             <td>10/01/2004</td>
  74.             <td>5' 11"</td>
  75.             <td>185</td>
  76.         </tr>
  77.         <tr class="odd">
  78.             <td>123-44-5555</td>
  79.             <td>John</td>
  80.             <td>Reynolds</td>
  81.             <td>10/01/2004</td>
  82.             <td>5' 11"</td>
  83.             <td>185</td>
  84.         </tr>
  85.     </table>
  86.     <input type="submit" value="Update"/>
  87.     </form>
  88.     
  89. </p><p>
  90. </p><p>
  91.     If you take a look at the files <code>SixthPass.html</code><code>SixthPass.page</code> 
  92.     and <code>EditableColumnPage2.java</code>
  93.     you will see the changes made to submit the form before changing the sort order
  94.     or paging.
  95. </p><p>
  96.     Here are the relevent HTML snippets from <code>SixthPass.html</code> 
  97.     that sets up this component:
  98. </p><p>
  99.    
  100. <code class="snippet"><pre>    
  101.     <table class="mytable" <code class="highlight">jwcid="table@contrib:FormTable"</code> 
  102.     source="ognl:dataItems"
  103.     <code class="highlight">convertor="ognl:dataItemConvertor"</code>
  104.     columns="SSN, FirstName, LastName, 
  105.     =birthDateColumn, Height, Weight"
  106.     rowsClass="ognl:beans.evenOdd.next"
  107.     pageSize="6"    
  108.     initialSortColumn="BirthDate" >
  109.             
  110.     <span jwcid="WeightColumnValue@Block">
  111.     <span jwcid="editableWeight@TextField" value="ognl:components.table.tableRow.Weight" size="4"/>
  112.     </span>
  113. </pre></code>        
  114. </p><p>
  115.     There are some big changes here, the table is now based on <code>contrib:FormTable</code>
  116.     rather then <code>contrib:Table</code>.  <code>FormTable</code> does many things for us, 
  117.     including making sure that the form is submitted whenever the table is paged or the sort
  118.     order is changed. 
  119. </p><p>
  120.     <code>FormTable</code> also stores data into the form itself
  121.     using hidden fields to avoid a <code>StaleLinkException</code> if the data changes on
  122.     the server before the form is submitted.  
  123.     A side effect of this is that the default behavior of the <code>FormTable</code> is to modify 
  124.     copies of the data rather then the source data itself.  Eventually we will need this behavior,
  125.     but for this page we will force the <code>FormTable</code> to use the source objects directly.
  126.     To do this
  127.     we must implement an <code>IPrimaryKeyConvertor</code> and pass it to the <code>FormTable</code>.
  128. </p><p>
  129.     The line:<code>convertor="ognl:dataItemConvertor"</code> configures the <code>FormTable</code>
  130.     to get each <code>DataItem</code> by calling <code>getDataItemConvertor().getValue(Object objPrimaryKey)</code>.
  131.     To create an <code>IPrimaryKeyConvertor</code> to return the original source objects, we added
  132.     the following to <code>EditableColumnPage2.java</code>.
  133. </p><p>
  134. <code class="highlight">
  135. <pre>
  136.     private IPrimaryKeyConvertor m_dataItemConvertor;
  137.     public EditableColumnPage2()
  138.     {
  139.         super();
  140.         // define a IPrimaryKeyConvertor that gets DataItems from the original list 
  141.         m_dataItemConvertor = new IPrimaryKeyConvertor()
  142.         {
  143.             public Object getPrimaryKey(Object objValue)
  144.             {
  145.                 DataItem dataItem = (DataItem) objValue;
  146.                 return dataItem.getSSN();
  147.             }
  148.             public Object getValue(Object objPrimaryKey)
  149.             {
  150.                 String SSN = (String)objPrimaryKey;
  151.                 List list = getDataItems();
  152.                 // find the item
  153.                 int count = list.size();
  154.                 for (int i = 0; i < count; i++)
  155.                 {
  156.                     DataItem item = (DataItem) list.get(i);
  157.                     if (item.getSSN().equals(SSN)){
  158.                         return item;
  159.                     }
  160.                 }
  161.                 return new DataItem(); //Handle data item not found 
  162.             }
  163.         };
  164.         
  165.     }
  166.     public IPrimaryKeyConvertor getDataItemConvertor()
  167.     {
  168.         return m_dataItemConvertor;
  169.     }
  170. </pre></code>    
  171. </p><p>
  172.     This looks like an aweful lot of work just to get the <code>FormTable</code> to
  173.     update the original source objects rather then copies, but you would seldomly
  174.     do things this way.  Generally, when users are updating values, you will want
  175.     to validate the input.  We'll get to that soon.
  176. </p><p>
  177. <a href="#" jwcid="@PageLink" page="SeventhPass">Using Formal Parameter Coding Style...</a>
  178. </p><p>
  179.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  180. </p>
  181. </body>
  182. </html>
  183. <!--
  184.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  185.  * This work is hereby released into the Public Domain. 
  186.  * To view a copy of the public domain dedication, visit 
  187.  * http://creativecommons.org/licenses/publicdomain/ 
  188.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  189.  * Stanford, California 94305, USA.
  190. -->
SixthPass.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->

  14. <page-specification class="tapestrytables.EditableColumnPage2">
  15.         <context-asset name="stylesheet" path="css/style.css"/>

  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  18.         
  19. </page-specification>
SixthPass.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight
TapestryTables.application

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE application
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->


  14. <application name="TapestryTables" engine-class="org.apache.tapestry.engine.BaseEngine" >

  15.     <description><![CDATA[   This application demonstrates the Tapestry Table components   ]]></description>
  16.     <property name="org.apache.tapestry.visit-class">tapestrytables.TapestryTablesVisit</property>
  17.     <library id="contrib" specification-path="/org/apache/tapestry/contrib/Contrib.library"/>
  18.     <page name="Home" specification-path="Home.page"/>
  19. </application>
TenthPass.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Using TableView, TableColumns, and TableFormRows</h1>
  7. <div class="note">
  8.     This page demonstrates how to implement a table using TableView, TableColumns, and TableFormRows.
  9. </div>            
  10. <p>
  11.     The <code>Table</code> and <code>FormTable</code> components wrap several underlying components 
  12.     to simplify common usage scenarios.  If you need to exert more control over the look of your table
  13.     you can use these building blocks directly.  For example, you can control where the 
  14.     "paging" component is displayed:
  15. </p><p>
  16.     <form jwcid="form">

  17.     <table class="mytable" jwcid="tableView">
  18.       <span jwcid="tableColumns"/>
  19.       <span jwcid="tableRows">
  20.           <span jwcid="BirthDateColumnValue@Block">
  21.              <span jwcid="editableBirthDate"/>
  22.           </span>
  23.           <span jwcid="WeightColumnValue@Block">
  24.              <span jwcid="editableWeight"/>
  25.           </span>
  26.           <span jwcid="tableValues@contrib:TableValues"/>
  27.       </span>
  28.       <tr>
  29.          <td colspan="7" class="tablepager">
  30.             <span jwcid="tablePages@contrib:TableFormPages"/>
  31.          </td>   
  32.       </tr>
  33. <span jwcid="$remove$">
  34.         <th>SSN</th>
  35.         <th>First Name</th>
  36.         <th>Last Name</th>
  37.         <th>Birth Date</th>
  38.         <th>Height</th>
  39.         <th>Weight</th>
  40.         <tr class="even">
  41.             <td>123-44-5555</td>
  42.             <td>John</td>
  43.             <td>Reynolds</td>
  44.             <td>10/01/2004</td>
  45.             <td>5' 11"</td>
  46.             <td>185</td>
  47.         </tr>
  48.         <tr class="odd">
  49.             <td>123-44-5555</td>
  50.             <td>John</td>
  51.             <td>Reynolds</td>
  52.             <td>10/01/2004</td>
  53.             <td>5' 11"</td>
  54.             <td>185</td>
  55.         </tr>
  56.         <tr class="even">
  57.             <td>123-44-5555</td>
  58.             <td>John</td>
  59.             <td>Reynolds</td>
  60.             <td>10/01/2004"</td>
  61.             <td>5' 11"</td>
  62.             <td>185</td>
  63.         </tr>
  64.         <tr class="odd">
  65.             <td>123-44-5555</td>
  66.             <td>John</td>
  67.             <td>Reynolds</td>
  68.             <td>10/01/2004</td>
  69.             <td>5' 11"</td>
  70.             <td>185</td>
  71.         </tr>
  72.         <tr class="even">
  73.             <td>123-44-5555</td>
  74.             <td>John</td>
  75.             <td>Reynolds</td>
  76.             <td>10/01/2004</td>
  77.             <td>5' 11"</td>
  78.             <td>185</td>
  79.         </tr>
  80.         <tr class="odd">
  81.             <td>123-44-5555</td>
  82.             <td>John</td>
  83.             <td>Reynolds</td>
  84.             <td>10/01/2004</td>
  85.             <td>5' 11"</td>
  86.             <td>185</td>
  87.         </tr>
  88. </span>        
  89.     </table>
  90.     <input type="submit" value="Update"/>
  91.     <span class="inputerror"><span jwcid="errors"/></span>
  92.     </form>
  93.     
  94. </p><p>
  95. </p><p>
  96.     If you take a look at the files <code>TenthPass.page</code> 
  97.     and <code>TenthPass.html</code> 
  98.     you will see the changes necessary to implement this table.
  99. </p><p>
  100.     Here are the relevent snippets from <code>TenthPass.page</code> 
  101.     :
  102. <pre>
  103. <code class="highlight">
  104.     <component id="tableView" type="contrib:TableView">
  105.         <binding name="source" expression="dataItems"/>
  106.         <static-binding name="columns"
  107.             value="
  108.                 SSN, 
  109.                 FirstName, 
  110.                 LastName, 
  111.                 =birthDateColumn, 
  112.                 Height, 
  113.                 Weight"/>
  114.         <binding name="pageSize" expression="6"/>
  115.         <static-binding  name="initialSortColumn" value="BirthDate"/>
  116.         <static-binding name="cellpadding" value="2"/> 
  117.         <static-binding name="cellspacing" value="0"/>
  118.     </component>

  119.     <component id="tableColumns" type="contrib:TableColumns">
  120.         <static-binding name="class" value="columnheader"/>
  121.     </component>

  122.     <component id="tableRows" type="contrib:TableFormRows">
  123.         <binding name="convertor" expression="dataItemConvertor"/>
  124.         <binding name="class" expression="beans.evenOdd.next"/>
  125.     </component>
  126. </code><code class="snippet">
  127.     <component id="editableBirthDate" type="ValidField">
  128.         <static-binding name="displayName">Weight</static-binding>
  129.         <binding name="value" <code class="highlight">expression="components.tableRows.tableRow.BirthDate"</code>/>
  130.         <binding name="size" expression="10"/>
  131.         <binding name="validator" expression='beans.birthDateValidator'/>
  132.     </component>

  133.     <component id="editableWeight" type="ValidField">
  134.         <static-binding name="displayName">Weight</static-binding>
  135.         <binding name="value" <code class="highlight">expression="components.tableRows.tableRow.Weight"</code>/>
  136.         <binding name="size" expression="4"/>
  137.         <binding name="validator" expression='beans.numberValidator'/>
  138.     </component>
  139. </code>        
  140. </pre>
  141. </p><p>
  142.     Here is the relevent snippet from <code>TenthPass.html</code> 
  143.     that sets up the layout:
  144. <pre>
  145. <code class="highlight">
  146.     <table class="mytable" jwcid="tableView">
  147.       <span jwcid="tableColumns"/>
  148.       <span jwcid="tableRows">
  149.           <span jwcid="BirthDateColumnValue@Block">
  150.              <span jwcid="editableBirthDate"/>
  151.           </span>
  152.           <span jwcid="WeightColumnValue@Block">
  153.              <span jwcid="editableWeight"/>
  154.           </span>
  155.           <span jwcid="tableValues@contrib:TableValues"/>
  156.       </span>
  157.       <tr>
  158.          <td colspan="7" class="tablepager">
  159.             <span jwcid="tablePages@contrib:TableFormPages"/>
  160.          </td>   
  161.       </tr>
  162. </code>        
  163. </pre>    
  164. </p><p>
  165. <!--
  166. </p><p>
  167. <a href="#" jwcid="@PageLink" page="FourthPass">Fourth Pass...</a>
  168. -->
  169. </p><p>
  170.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  171. </p>
  172. </body>
  173. </html>
  174. <!--
  175.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
  176.  * This work is hereby released into the Public Domain. 
  177.  * To view a copy of the public domain dedication, visit 
  178.  * http://creativecommons.org/licenses/publicdomain/ 
  179.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  180.  * Stanford, California 94305, USA.
  181. -->
TenthPass.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->

  14. <page-specification class="tapestrytables.ValidateEditableColumnPage2">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>

  17.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>

  18.         <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
  19.         
  20.         <bean name="numberValidator" class="org.apache.tapestry.valid.NumberValidator" lifecycle="page">
  21.             <set-property name="required" expression="true"/>
  22.             <set-property name="clientScriptingEnabled" expression="false"/>
  23.         </bean>

  24.         <bean name="birthDateValidator" class="org.apache.tapestry.valid.PatternValidator" lifecycle="page">
  25.             <set-property name="required" expression="true"/>
  26.             <set-property name="clientScriptingEnabled" expression="false"/>
  27.             <set-property name="patternString">"//d//d///d//d///d//d//d//d$"</set-property> 
  28.             <set-property name="patternNotMatchedMessage">
  29.                 "Error: Date improperly formatted.  Should be like: MM/DD/YYYY"</set-property>
  30.         </bean>
  31.         
  32.         <component id="form" type="Form">
  33.             <binding name="listener" expression="listeners.formSubmit"/>
  34.             <binding name="delegate" expression="beans.delegate"/>
  35.         </component>
  36.                 
  37.         <component id="tableView" type="contrib:TableView">
  38.             <binding name="source" expression="dataItems"/>
  39.             <static-binding name="columns"
  40.                 value="
  41.                     SSN, 
  42.                     FirstName, 
  43.                     LastName, 
  44.                     =birthDateColumn, 
  45.                     Height, 
  46.                     Weight"/>
  47.             <binding name="pageSize" expression="6"/>
  48.             <static-binding  name="initialSortColumn" value="BirthDate"/>
  49.             <static-binding name="cellpadding" value="2"/> 
  50.             <static-binding name="cellspacing" value="0"/>
  51.         </component>

  52.         <component id="tableColumns" type="contrib:TableColumns">
  53.             <static-binding name="class" value="columnheader"/>
  54.         </component>

  55.         <component id="tableRows" type="contrib:TableFormRows">
  56.             <binding name="convertor" expression="dataItemConvertor"/>
  57.             <binding name="class" expression="beans.evenOdd.next"/>
  58.         </component>

  59.         <component id="editableBirthDate" type="ValidField">
  60.             <static-binding name="displayName">Weight</static-binding>
  61.             <binding name="value" expression="components.tableRows.tableRow.BirthDate"/>
  62.             <binding name="size" expression="10"/>
  63.             <binding name="validator" expression='beans.birthDateValidator'/>
  64.         </component>

  65.         
  66.         <component id="editableWeight" type="ValidField">
  67.             <static-binding name="displayName">Weight</static-binding>
  68.             <binding name="value" expression="components.tableRows.tableRow.Weight"/>
  69.             <binding name="size" expression="4"/>
  70.             <binding name="validator" expression='beans.numberValidator'/>
  71.         </component>

  72.         <component id="errors" type="Delegator">
  73.             <binding name="delegate" expression="beans.delegate.firstError"/>
  74.         </component>
  75. </page-specification>
TenthPass.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight
Test.html

  1. <html jwcid="@Shell" title="Test" stylesheet="ognl:assets.stylesheet">
  2. <!--
  3.   Released in the Public Domain by John Reynolds
  4. -->
  5. <head jwcid="@Block">
  6.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  7. </head>
  8. <body jwcid="@Body">
  9.     <h1>Test</h1> This page is a work in progress
  10. <p>
  11.     <form jwcid="form">
  12.     <table class="mytable" jwcid="tableView">
  13.     <span jwcid="tablePages@contrib:TableFormPages" class="tablepager"/>
  14.     <span jwcid="tableColumns"/>
  15.     <span jwcid="tableRows">
  16.         <span jwcid="SelectRowColumnValue@Block">
  17.            <span jwcid="selectRow"/>
  18.         </span>
  19.         <span jwcid="SSNColumnValue@Block">
  20.            <span jwcid="editableSSN"/>
  21.         </span>
  22.         <span jwcid="tableValues@contrib:TableValues"/>
  23.     </span>
  24.     </table>
  25.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  26.     <input type="submit" value="Update"/>
  27.     <span class="inputerror"><span jwcid="errors"/></span>
  28. Columns: <span jwcid="@PropertySelection" model="ognl:@tapestrytables.TestPage@COLUMNS_MODEL" value="ognl:columnsString" submitOnChange="true" />
  29.     </form>
  30. </p><p>
  31.     Here's a list of examples to add:
  32.     <ul>
  33.         <li>Create a checkbox per row, and a "select all" checkbox</li>
  34.         <li>Demonstrate a custom  TableModel for handling a huge number of rows</li>
  35.     </ul>
  36. </p>    
  37. </body>
  38. </html>
Test.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">

  5. <page-specification class="tapestrytables.TestPage">
  6.         <context-asset name="stylesheet" path="css/style.css"/>
  7.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>

  8.         <property-specification name="columnsString" type="java.lang.String" persistent="yes"/>
  9.         
  10.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  11.         <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
  12.         <bean name="ssnValidator" class="org.apache.tapestry.valid.PatternValidator" lifecycle="page">
  13.             <set-property name="required" expression="true"/>
  14.             <set-property name="clientScriptingEnabled" expression="false"/>
  15.             <set-property name="patternString">"//d//d//d-//d//d-//d//d//d//d$"</set-property> 
  16.             <set-property name="patternNotMatchedMessage">
  17.                 "Error: SSN improperly formatted."</set-property>
  18.         </bean>

  19.         <component id="form" type="Form">
  20.             <binding name="listener" expression="listeners.formSubmit"/>
  21.             <binding name="delegate" expression="beans.delegate"/>
  22.         </component>

  23.         <component id="tableView" type="contrib:TableView">
  24.             <binding name="source" expression="dataItems"/>
  25.             <binding name="columns" expression="ColumnsString" />
  26.                 
  27. <!--            
  28.             <static-binding name="columns"
  29.                 value="
  30.                     !SelectRow,
  31.                     SSN,
  32.                     FirstName,
  33.                     LastName" />
  34. -->                    
  35.             <binding name="pageSize" expression="12"/>
  36.             <static-binding name="cellpadding" value="2"/> 
  37.             <static-binding name="cellspacing" value="0"/>
  38.             <static-binding name="initialSortColumn" value="LastName"/>

  39.         </component>

  40.         <component id="tableColumns" type="contrib:TableColumns">
  41.             <static-binding name="class" value="columnheader"/>
  42.         </component>

  43.         <component id="tableRows" type="contrib:TableFormRows">
  44.             <binding name="convertor" expression="dataItemConvertor"/>
  45.             <binding name="class" expression="beans.evenOdd.next"/>
  46.         </component>

  47.         <component id="editableSSN" type="ValidField">
  48.             <static-binding name="displayName">SSN</static-binding>
  49.             <binding name="value" expression="components.tableRows.tableRow.SSN"/>
  50.             <binding name="size" expression="9"/>
  51.             <binding name="validator" expression="beans.ssnValidator"/>
  52.         </component>

  53.         
  54.         <component id="selectRow" type="Checkbox">
  55.             <binding name="selected" expression="components.tableRows.tableRow.Selected"/>
  56.         </component>
  57.             
  58.         <component id="errors" type="Delegator">
  59.             <binding name="delegate" expression="beans.delegate.firstError"/>
  60.         </component> 
  61. </page-specification>
Test.properties
  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight
  7. ColumnsString = FirstName, LastName, SSN

ThirdPass.html

  1. <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
  2. <head jwcid="@Block">
  3.     <link rel="stylesheet" type="text/css" href="../css/style.css"/>
  4. </head>
  5. <body jwcid="@Body">
  6.     <h1>Alternating Row Colors</h1>
  7. <div class="note">
  8.     This page demonstrates how to implement a table with alternating row colors and
  9.     set the number of rows displayed on a page.
  10. </div>            
  11. <p>        
  12.     This is our third pass at implementing the table using Tapestry components.
  13.     Our second pass looked better, but the "look" of the page still wasn't right.
  14.     We weren't picking up the "styles" that our HTML designer specified.
  15. </p><p>
  16.     <table class="mytable" jwcid="table@contrib:Table"
  17.     source="ognl:dataItems"
  18.     columns="SSN, FirstName, LastName, 
  19.         BirthDate, Height, Weight"
  20.     rowsClass="ognl:beans.evenOdd.next"
  21.     pageSize="6"    >
  22.         <th>SSN</th>
  23.         <th>First Name</th>
  24.         <th>Last Name</th>
  25.         <th>Birth Date</th>
  26.         <th>Height</th>
  27.         <th>Weight</th>
  28.         <tr class="even">
  29.             <td>123-44-5555</td>
  30.             <td>John</td>
  31.             <td>Reynolds</td>
  32.             <td>10/01/2004</td>
  33.             <td>5' 11"</td>
  34.             <td>185</td>
  35.         </tr>
  36.         <tr class="odd">
  37.             <td>123-44-5555</td>
  38.             <td>John</td>
  39.             <td>Reynolds</td>
  40.             <td>10/01/2004</td>
  41.             <td>5' 11"</td>
  42.             <td>185</td>
  43.         </tr>
  44.         <tr class="even">
  45.             <td>123-44-5555</td>
  46.             <td>John</td>
  47.             <td>Reynolds</td>
  48.             <td>10/01/2004"</td>
  49.             <td>5' 11"</td>
  50.             <td>185</td>
  51.         </tr>
  52.         <tr class="odd">
  53.             <td>123-44-5555</td>
  54.             <td>John</td>
  55.             <td>Reynolds</td>
  56.             <td>10/01/2004</td>
  57.             <td>5' 11"</td>
  58.             <td>185</td>
  59.         </tr>
  60.         <tr class="even">
  61.             <td>123-44-5555</td>
  62.             <td>John</td>
  63.             <td>Reynolds</td>
  64.             <td>10/01/2004</td>
  65.             <td>5' 11"</td>
  66.             <td>185</td>
  67.         </tr>
  68.         <tr class="odd">
  69.             <td>123-44-5555</td>
  70.             <td>John</td>
  71.             <td>Reynolds</td>
  72.             <td>10/01/2004</td>
  73.             <td>5' 11"</td>
  74.             <td>185</td>
  75.         </tr>
  76.     </table>
  77.     
  78. </p><p>
  79.     If you take a look at the files <code>ThirdPass.html</code> and <code>ThirdPass.page</code>
  80.     you will see the changes made to improve the "look" of this page.  Tapestry includes
  81.     a bean called <code>EvenOdd</code> that produces the alternating strings 
  82.     "even" and "odd".  
  83.     By binding the <code>rowsClass</code> attribute of the <code>Table</code> to the 
  84.     <code>EvenOdd</code> Java Bean, we are able to specify alternating <code>class</code>
  85.     attributes on each row of the table.  Coupled with the CSS style sheet, this gives
  86.     us the altenating row colors that our HTML designer specified (Note: the CSS styles
  87.     must be "even" and "odd" for this to work).
  88. </p><p>
  89.     Here is the relevent HTML snippet from <code>ThirdPass.html</code> 
  90.     that sets up this component:
  91. </p><p>
  92.    
  93. <code class="snippet">    
  94.     <table class="mytable" jwcid="table@contrib:Table" 
  95. <br>
  96.     source="ognl:dataItems"
  97. <br>
  98.     columns="SSN, FirstName, LastName, BirthDate, Height, Weight"
  99. <br>    
  100.     <code class="highlight">rowsClass="ognl:beans.evenOdd.next"</code>
  101. <br>    
  102.     <code class="highlight">pageSize="6"</code> >
  103. </code>        
  104. </p><p>
  105.     The <code>evenOdd</code> bean was added to this page's context in 
  106.     <code>ThirdPass.page</code> by adding the following line:
  107. </p><p>
  108. <code class="highlight">    
  109.     <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  110. </code>    
  111. </p><p>
  112.     To really understand what's going on you will have to delve deeper into the
  113.     Tapestry documentation, but I think this illustrates that the effort is worthwhile.
  114. </p><p>
  115.     You may have also noticed that the table is now displaying a maximum of 6 rows 
  116.     per page.  
  117.     This was accomplished by setting the <code>pageSize</code> attribute of the Table.
  118. </p><p>
  119.     We're very close to being done.
  120. </p><p>
  121. <a href="#" jwcid="@PageLink" page="FourthPass">Custom Column Sorting...</a>
  122. </p><p>
  123.     <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
  124. </p>
  125. </body>
  126. </html>
  127. <!--
  128.  * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ 
  129.  * October 2004
  130.  * This work is hereby released into the Public Domain. 
  131.  * To view a copy of the public domain dedication, visit 
  132.  * http://creativecommons.org/licenses/publicdomain/ 
  133.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  134.  * Stanford, California 94305, USA.
  135. -->
ThirdPass.page

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE page-specification
  3.       PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  4.       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <page-specification class="tapestrytables.FirstPass">
  15.         <context-asset name="stylesheet" path="css/style.css"/>
  16.         <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
  17.         <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
  18.         
  19. </page-specification>
ThirdPass.properties

  1. SSNSSN = SSN
  2. FirstFirstName = First Name
  3. LastLastName = Last Name
  4. BirthBirthDate = Birth Date
  5. HeightHeight = Height
  6. WeightWeight = Weight
web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE web-app
  3.       PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  4.       "http://java.sun.com/dtd/web-app_2_3.dtd">
  5. <!-- generated by Spindle, http://spindle.sourceforge.net -->
  6. <!--
  7.  * Contributed by John Reynolds - October 2004
  8.  * This work is hereby released into the Public Domain. 
  9.  * To view a copy of the public domain dedication, visit 
  10.  * http://creativecommons.org/licenses/publicdomain/ 
  11.  * or send a letter to Creative Commons, 559 Nathan Abbott Way, 
  12.  * Stanford, California 94305, USA.
  13. -->
  14. <web-app>
  15.     <display-name>TapestryTables</display-name>
  16.     <filter>
  17.         <filter-name>redirect</filter-name>
  18.         <filter-class>org.apache.tapestry.RedirectFilter</filter-class>
  19.     </filter>
  20.     <filter-mapping>
  21.         <filter-name>redirect</filter-name>
  22.         <url-pattern>/</url-pattern>
  23.     </filter-mapping>
  24.     <servlet>
  25.         <servlet-name>TapestryTables</servlet-name>
  26.         <servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
  27.         <load-on-startup>1</load-on-startup>
  28.     </servlet>
  29.     <servlet-mapping>
  30.         <servlet-name>TapestryTables</servlet-name>
  31.         <url-pattern>/app</url-pattern>
  32.     </servlet-mapping>
  33. </web-app>

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐