Tapstry3之Table组件全攻略
这是T3版本下Table组件的使用例程。代码是国外大师级人物所写,现在把源代码整理出来:如下图所示建立工程:所需jar包一览如下:bsf-2.3.0.jarcommons-beanutils-1.6.1.jarcommons-codec-1.2.jarcommons-collections-2.1.jarcommons-digester-1.5.jarcommons-fil
这是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
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package datasource;
- import java.util.Comparator;
- /**
- * This is a very hokey and error prone comparator cobbled together
- * to demonstrate a point. Don't use this in production.
- */
- public class BirthDateComparator implements Comparator
- {
- // This comparator is designed to compare two
- // MM/DD/YYYY formatted Strings
- public int compare(Object o1, Object o2)
- {
- // return -1 if o1 < o2
- // return 0 if o1 == o2
- // return 1 if o1 > o2
- String month1 = "01";
- String day1 = "01";
- String year1 = "1900";
- if (o1 instanceof String) {
- String birthDate1 = (String) o1 ;
- //extract the month, date and year
- month1 = birthDate1.substring(0,2);
- day1 = birthDate1.substring(3,5);
- year1 = birthDate1.substring(6,10);
- }
- String month2 = "01";
- String day2 = "01";
- String year2 = "1900";
- if (o2 instanceof String) {
- String birthDate2 = (String) o2 ;
- //extract the month, date and year
- month2 = birthDate2.substring(0,2);
- day2 = birthDate2.substring(3,5);
- year2 = birthDate2.substring(6,10);
- }
- //System.out.println("month1 = " + month1 + " day1 = " + day1 + " year1 = " + year1);
- //System.out.println("month2 = " + month2 + " day2 = " + day2 + " year2 = " + year2);
- int yearCompare = year1.compareTo(year2);
- if(yearCompare !=0) {
- return yearCompare;
- }
- else {
- int monthCompare = month1.compareTo(month2);
- if(monthCompare !=0) {
- return monthCompare;
- }
- else
- {
- return day1.compareTo(day2);
- }
- }
- }
- }
DataItem.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package datasource;
- import java.io.Serializable;
- /**
- */
- public class DataItem implements Serializable
- {
- String SSN;
- String FirstName;
- String LastName;
- String BirthDate;
- String Height;
- String Weight;
- boolean Selected;
- /**
- * @param ssn
- * @param firstName
- * @param lastName
- * @param birthDate
- * @param height
- * @param weight
- */
- public DataItem(String ssn, String firstName, String lastName,
- String birthDate, String height, String weight) {
- super();
- SSN = ssn;
- FirstName = firstName;
- LastName = lastName;
- BirthDate = birthDate;
- Height = height;
- Weight = weight;
- Selected = false;
- }
- public DataItem()
- {
- SSN = "ssn";
- FirstName = "firstName";
- LastName = "lastName";
- BirthDate = "birthDate";
- Height = "height";
- Weight = "100";
- }
- /**
- * @return Returns the birthDate.
- */
- public String getBirthDate() {
- return BirthDate;
- }
- /**
- * @param birthDate The birthDate to set.
- */
- public void setBirthDate(String birthDate) {
- BirthDate = birthDate;
- }
- /**
- * @return Returns the firstName.
- */
- public String getFirstName() {
- return FirstName;
- }
- /**
- * @param firstName The firstName to set.
- */
- public void setFirstName(String firstName) {
- FirstName = firstName;
- }
- /**
- * @return Returns the height.
- */
- public String getHeight() {
- return Height;
- }
- /**
- * @param height The height to set.
- */
- public void setHeight(String height) {
- Height = height;
- }
- /**
- * @return Returns the lastName.
- */
- public String getLastName() {
- return LastName;
- }
- /**
- * @param lastName The lastName to set.
- */
- public void setLastName(String lastName) {
- LastName = lastName;
- }
- /**
- * @return Returns the sSN.
- */
- public String getSSN() {
- return SSN;
- }
- /**
- * @param ssn The sSN to set.
- */
- public void setSSN(String ssn) {
- SSN = ssn;
- }
- /**
- * @return Returns the weight.
- */
- public String getWeight() {
- return Weight;
- }
- /**
- * @param weight The weight to set.
- */
- public void setWeight(String weight) {
- Weight = weight;
- }
- /**
- * @return Returns the birthDate.
- */
- public boolean getSelected() {
- return Selected;
- }
- /**
- * @param birthDate The birthDate to set.
- */
- public void setSelected(boolean selected) {
- Selected = selected;
- }
- }
DataSource.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package datasource;
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.List;
- /**
- */
- public class DataSource implements Serializable {
- List dataItems;
- private static String[] firstNames = {
- "Carol", "John", "Frank", "Barbara", "Julie", "Ted", "Ted", "Bob", "Mary", "Alice", "Fran"
- ,"Carrie", "John", "Frank", "Barbara", "Julie", "Bob", "Mary", "Alice", "Fran"
- ,"Carol", "John", "Frank", "Barbara", "Julie", "Ted", "Bob", "Mary", "Alice", "Fran"
- ,"Carol", "John", "John", "Frank", "Barbara", "Barbara", "Julie", "Ted", "Bob", "Mary", "Alice", "Fran"
- ,"Carol", "John", "Frank", "Barbara", "Julie", "Ted", "Bob", "Mary", "Alice", "Fran"
- ,"Carrol", "John", "Kenneth", "Barbara", "Julie", "Ted", "Bob", "Mary", "Alice", "Fran"
- ,"Carol", "John", "Frank", "Barbara", "Julie", "Ted", "Bob", "Mary", "Alice", "Fran"
- ,"Carol", "John", "Frank", "Mary", "Julie", "Ted", "Bob", "Mary", "Alice", "Fran"
- ,"Carl", "John", "Elizabeth", "Barbara", "Julie", "Ted", "Bob", "Mary", "Alice", "Fran"
- ,"Carol", "John", "Frank", "Barbara", "Julie", "Ted", "Bob", "Mary", "Alice", "Fran"
- };
- private static String[] lastNames = {
- "Smith", "Jones", "Johnson", "Reynolds", "Robinson", "Clark", "Lewis", "Washington", "Franklin", "Pierce"
- ,"Wilson","Smith", "Jones", "Johnson", "Reynolds", "Robinson", "Clark", "Lewis", "Washington", "Franklin", "Pierce"
- ,"Nixon","Smith", "Jones", "Johnson", "Reynolds", "Robinson", "Clark", "Lewis", "Washington", "Franklin", "Pierce"
- ,"Patterson","Smith", "Jones", "Johnson", "Reynolds", "Robinson", "Clark", "Lewis", "Washington", "Franklin", "Pierce"
- ,"Franklin","Smith", "Jones", "Johnson", "Reynolds", "Robinson", "Clark", "Lewis", "Washington", "Franklin", "Pierce"
- ,"Jetson","Smith", "Jones", "Johnson", "Reynolds", "Robinson", "Clark", "Lewis", "Washington", "Franklin", "Pierce"
- ,"Adams","Smith", "Jones", "Johnson", "Reynolds", "Robinson", "Clark", "Lewis", "Washington", "Franklin", "Pierce"
- ,"Carleson","Smith", "Jones", "Johnson", "Reynolds", "Robinson", "Clark", "Lewis", "Washington", "Franklin", "Pierce"
- ,"Smith", "Jones", "Johnson", "Reynolds", "Robinson", "Clark", "Lewis", "Washington", "Franklin", "Pierce"
- ,"Smith", "Jones", "Johnson", "Reynolds", "Robinson", "Clark", "Lewis", "Washington", "Franklin", "Pierce"
- };
- private static String[] birthDates = {
- "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"
- ,"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"
- , "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"
- ,"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"
- , "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"
- ,"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"
- , "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"
- ,"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"
- , "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"
- ,"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"
- };
- private static String[] heights = {
- "6' 4/"", "5' 11/"", "4' 11/"", "5' 2/"", "6'", "5' 5/"", "5' 8/"", "4' 9/"", "5'", "5' 9/""
- ,"5' 2/"","6' 4/"", "5' 11/"", "4' 11/"", "5' 2/"", "6'", "5' 5/"", "5' 8/"", "4' 9/"", "5'", "5' 9/""
- ,"6' 4/"", "5' 11/"", "4' 11/"", "5' 2/"", "6'", "5' 5/"", "5' 8/"", "4' 9/"", "5'", "5' 9/""
- ,"5' 2/"","6' 4/"", "5' 11/"", "4' 11/"", "5' 2/"", "6'", "5' 5/"", "5' 8/"", "4' 9/"", "5'", "5' 9/""
- ,"6' 4/"", "5' 11/"", "4' 11/"", "5' 2/"", "6'", "5' 5/"", "5' 8/"", "4' 9/"", "5'", "5' 9/""
- ,"5' 2/"","6' 4/"", "5' 11/"", "4' 11/"", "5' 2/"", "6'", "5' 5/"", "5' 8/"", "4' 9/"", "5'", "5' 9/""
- ,"6' 4/"", "5' 11/"", "4' 11/"", "4' 11/"", "5' 2/"", "6'", "5' 5/"", "5' 8/"", "4' 9/"", "5'", "5' 9/""
- ,"5' 2/"","6' 4/"", "5' 11/"", "4' 11/"", "5' 2/"", "6'", "5' 5/"", "5' 8/"", "4' 9/"", "5'", "5' 9/""
- ,"6' 4/"", "5' 11/"", "5' 2/"", "6'", "5' 5/"", "5' 8/"", "4' 9/"", "5'", "5' 9/""
- ,"6' 4/"", "5' 11/"", "4' 11/"", "5' 2/"", "6'", "5' 5/"", "5' 8/"", "4' 9/"", "5'", "5' 9/""
- };
- private static int[] weights = {
- 210, 185, 140, 152, 200, 210, 160, 108, 100, 155
- ,210, 185, 140, 152, 200, 210, 160, 108, 100, 155
- , 140,210, 185, 140, 152, 200, 210, 160, 108, 100, 155
- ,210, 185, 140, 152, 200, 210, 160, 108, 100, 155
- ,210, 185, 140, 152, 200, 210, 160, 108, 100, 155
- , 140,210, 185, 140, 152, 200, 210, 160, 108, 100, 155
- ,210, 185, 140, 152, 200, 210, 160, 108, 100, 155
- , 140,210, 185, 140, 152, 200, 210, 160, 108, 100, 155
- ,210, 185, 140, 152, 200, 210, 160, 108, 100, 155
- ,210, 185, 140, 152, 200, 210, 160, 108, 100, 155
- };
- public DataSource() {
- if (dataItems == null) {
- dataItems = new ArrayList();
- int SSN = 1000;
- for (int i = 0; i < 100; i++) {
- dataItems.add(new DataItem("123-45-" + (SSN + i), firstNames[i],
- lastNames[i], birthDates[i], heights[i], new String(""+ weights[i])));
- }
- }
- }
- public List getDataItems() {
- return dataItems;
- }
- }
ColumnChooserPage.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import java.util.List;
- import org.apache.tapestry.IRequestCycle;
- import org.apache.tapestry.contrib.palette.SortMode;
- import org.apache.tapestry.form.IPropertySelectionModel;
- import org.apache.tapestry.form.StringPropertySelectionModel;
- import org.apache.tapestry.html.BasePage;
- /**
- *
- */
- public class ColumnChooserPage extends BasePage
- {
- private List _selectedColumns;
- private SortMode _sort = SortMode.USER;
- private IPropertySelectionModel _sortModel;
- public ColumnChooserPage()
- {
- super();
- }
- public void initialize()
- {
- super.initialize();
- _sort = SortMode.USER;
- _selectedColumns = null;
- }
- public void formSubmit(IRequestCycle cycle)
- {
- ColumnChooserPage2 resultsPage = (ColumnChooserPage2) cycle.getPage("ColumnChooser2");
- if( _selectedColumns != null && _selectedColumns.size()>0)
- {
- // Convert the List to a String of
- // comma-seperated ColumnIDs
- StringBuffer selectedColumns = new StringBuffer();
- for (int i=0; i < _selectedColumns.size(); i++)
- {
- // Crude mapping of Labels to ColumnIDs
- String columnString = (String)_selectedColumns.get(i);
- if (columnString.equals("First Name")){
- selectedColumns.append("FirstName");
- } else if (columnString.equals("Last Name"))
- {
- selectedColumns.append("LastName");
- } else if (columnString.equals("Birth Date"))
- {
- selectedColumns.append("=birthDateColumn");
- } else {
- selectedColumns.append(columnString);
- }
- if( i < (_selectedColumns.size()-1))
- {
- selectedColumns.append(",");
- }
- }
- resultsPage.setSelectedColumns(selectedColumns.toString());
- cycle.activate(resultsPage);
- } else {
- _errorMsg = "Select at least one column";
- }
- }
- private IPropertySelectionModel columnModel;
- private String[] columns = { "SSN", "First Name", "Last Name", "Birth Date", "Height", "Weight" };
- public IPropertySelectionModel getColumnModel()
- {
- if (columnModel == null)
- columnModel = new StringPropertySelectionModel(columns);
- return columnModel;
- }
- public void setSort(SortMode value)
- {
- _sort = value;
- }
- public SortMode getSort()
- {
- return _sort;
- }
- public IPropertySelectionModel getSortModel()
- {
- return _sortModel;
- }
- public List getSelectedColumns()
- {
- return _selectedColumns;
- }
- public void setSelectedColumns(List selectedColumns)
- {
- _selectedColumns = selectedColumns;
- }
- String _errorMsg;
- public String getErrorMsg()
- {
- return _errorMsg;
- }
- }
ColumnChooserPage2.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import java.util.List;
- import org.apache.tapestry.IRequestCycle;
- import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
- import org.apache.tapestry.contrib.table.model.ITableColumn;
- import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
- import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
- import org.apache.tapestry.event.PageEvent;
- import org.apache.tapestry.event.PageRenderListener;
- import org.apache.tapestry.html.BasePage;
- import datasource.BirthDateComparator;
- import datasource.DataItem;
- /**
- *
- */
- public abstract class ColumnChooserPage2 extends BasePage implements PageRenderListener
- {
- public abstract List getDataItems();
- public abstract void setDataItems(List dataItems);
- public abstract String getColumnsString();
- public abstract void setColumnsString(String cols);
- private IPrimaryKeyConvertor m_dataItemConvertor;
- public ColumnChooserPage2()
- {
- super();
- // define a IPrimaryKeyConvertor that gets DataItems from the original list
- m_dataItemConvertor = new IPrimaryKeyConvertor()
- {
- public Object getPrimaryKey(Object objValue)
- {
- DataItem dataItem = (DataItem) objValue;
- return dataItem.getSSN();
- }
- public Object getValue(Object objPrimaryKey)
- {
- String SSN = (String)objPrimaryKey;
- List list = getDataItems();
- // find the item
- int count = list.size();
- for (int i = 0; i < count; i++)
- {
- DataItem item = (DataItem) list.get(i);
- if (item.getSSN().equals(SSN)){
- return item;
- }
- }
- return new DataItem(); //Handle data item not found
- }
- };
- }
- public IPrimaryKeyConvertor getDataItemConvertor()
- {
- return m_dataItemConvertor;
- }
- public void pageBeginRender(PageEvent event)
- {
- List list = getDataItems();
- if (list == null)
- {
- setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
- }
- setColumnsString(_selectedColumns);
- System.out.println("setColumnsString(" + _selectedColumns + ")");
- }
- public ITableColumn getBirthDateColumn()
- {
- // The column value is extracted in a custom evaluator class
- SimpleTableColumn birthDateColumn = new SimpleTableColumn("BirthDate", "Birth Date", new BirthDateColumnEvaluator(), true);
- birthDateColumn.setColumnComparator(new BirthDateComparator());
- return birthDateColumn;
- }
- /**
- * A class defining the logic for getting the BirthDate from a DataItem
- */
- private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
- {
- /**
- * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
- */
- public Object getColumnValue(ITableColumn objColumn, Object objRow)
- {
- DataItem dataItem = (DataItem) objRow;
- if( dataItem == null )
- {
- return "No Birthdate";
- }
- return dataItem.getBirthDate();
- }
- }
- public void formSubmit(IRequestCycle cycle)
- {
- System.out.println("The form was submitted");
- }
- String _selectedColumns = "No Columns Selected";
- public void setSelectedColumns( String selectedColumns)
- {
- _selectedColumns = selectedColumns;
- }
- }
CustomSortColumnPage.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import tapestrytables.TapestryTablesVisit;
- import org.apache.tapestry.contrib.table.model.ITableColumn;
- import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
- import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
- import datasource.DataItem;
- import datasource.BirthDateComparator;
- import java.util.List;
- import org.apache.tapestry.event.PageEvent;
- import org.apache.tapestry.event.PageRenderListener;
- import org.apache.tapestry.html.BasePage;
- /**
- *
- */
- public abstract class CustomSortColumnPage extends BasePage implements PageRenderListener
- {
- public abstract List getDataItems();
- public abstract void setDataItems(List dataItems);
- public void pageBeginRender(PageEvent event)
- {
- List list = getDataItems();
- if (list == null)
- {
- setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
- }
- }
- public ITableColumn getBirthDateColumn()
- {
- // The column value is extracted in a custom evaluator class
- SimpleTableColumn birthDateColumn = new SimpleTableColumn("BirthDate", "Birth Date", new BirthDateColumnEvaluator(), true);
- birthDateColumn.setColumnComparator(new BirthDateComparator());
- return birthDateColumn;
- }
- /**
- * A class defining the logic for getting the BirthDate from a DataItem
- */
- private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
- {
- /**
- * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
- */
- public Object getColumnValue(ITableColumn objColumn, Object objRow)
- {
- DataItem dataItem = (DataItem) objRow;
- return dataItem.getBirthDate();
- }
- }
- }
DirectLinkColumnPage.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import tapestrytables.TapestryTablesVisit;
- import org.apache.tapestry.IRequestCycle;
- import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
- import org.apache.tapestry.contrib.table.model.ITableColumn;
- import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
- import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
- import datasource.DataItem;
- import datasource.BirthDateComparator;
- import java.util.List;
- import org.apache.tapestry.event.PageEvent;
- import org.apache.tapestry.event.PageRenderListener;
- import org.apache.tapestry.html.BasePage;
- /**
- *
- */
- public abstract class DirectLinkColumnPage extends BasePage implements PageRenderListener
- {
- public abstract List getDataItems();
- public abstract void setDataItems(List dataItems);
- public abstract String getSelectedSSN();
- public abstract void setSelectedSSN(String selectedSSN);
- private IPrimaryKeyConvertor m_dataItemConvertor;
- public DirectLinkColumnPage()
- {
- super();
- // define a IPrimaryKeyConvertor that gets DataItems from the original list
- m_dataItemConvertor = new IPrimaryKeyConvertor()
- {
- public Object getPrimaryKey(Object objValue)
- {
- DataItem dataItem = (DataItem) objValue;
- return dataItem.getSSN();
- }
- public Object getValue(Object objPrimaryKey)
- {
- String SSN = (String)objPrimaryKey;
- List list = getDataItems();
- // find the item
- int count = list.size();
- for (int i = 0; i < count; i++)
- {
- DataItem item = (DataItem) list.get(i);
- if (item.getSSN().equals(SSN)){
- return item;
- }
- }
- return new DataItem(); //Handle data item not found
- }
- };
- }
- // authored by Rick Austin
- public void SelectListener(IRequestCycle cycle) {
- Object[] parameters = cycle.getServiceParameters();
- String SSN = (String)parameters[0];
- // Output the parameter value to the console to see if
- // this works.
- System.out.println("Selected SSN: " + SSN);
- setSelectedSSN(SSN);
- }
- public IPrimaryKeyConvertor getDataItemConvertor()
- {
- return m_dataItemConvertor;
- }
- public void pageBeginRender(PageEvent event)
- {
- List list = getDataItems();
- if (list == null)
- {
- setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
- }
- }
- public ITableColumn getBirthDateColumn()
- {
- // The column value is extracted in a custom evaluator class
- SimpleTableColumn birthDateColumn = new SimpleTableColumn("BirthDate", "Birth Date", new BirthDateColumnEvaluator(), true);
- birthDateColumn.setColumnComparator(new BirthDateComparator());
- return birthDateColumn;
- }
- /**
- * A class defining the logic for getting the BirthDate from a DataItem
- */
- private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
- {
- /**
- * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
- */
- public Object getColumnValue(ITableColumn objColumn, Object objRow)
- {
- DataItem dataItem = (DataItem) objRow;
- if( dataItem == null )
- {
- return "No Birthdate";
- }
- return dataItem.getBirthDate();
- }
- }
- public void formSubmit(IRequestCycle cycle)
- {
- System.out.println("The form was submitted");
- /*
- RequestContext context = cycle.getRequestContext();
- System.out.println(context.getParameter("hiddenCurrentPage"));
- //int iterRows = Integer.parseInt(context.getParameter("iterRows"));
- String ew = "editableWeight";
- for (int i=0; i < 6; i++)
- {
- String suffix;
- if (i==0) {
- suffix = "";
- } else {
- suffix = "$" + (i-1);
- }
- String editableWeightString = context.getParameter(ew + suffix);
- if(editableWeightString != null)
- {
- System.out.println("The " + ew + suffix + " parameter is: " + editableWeightString );
- }
- }
- // Process the submitted form
- List list = getDataItems();
- // Do something to process the list changes
- int count = list.size();
- for (int i = 0; i < 1; i++)
- {
- DataItem item = (DataItem) list.get(i);
- System.out.println(item.getWeight());
- }
- // Always important to set peristent properties; otherwise changes
- // made in this request cycle will be lost. The framework
- // makes a copy of the list.
- setDataItems(list);
- */
- }
- }
DirectLinkTableColumnPage.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import tapestrytables.TapestryTablesVisit;
- import org.apache.tapestry.IRequestCycle;
- import org.apache.tapestry.components.Block;
- import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
- import org.apache.tapestry.contrib.table.model.ITableColumn;
- import org.apache.tapestry.contrib.table.model.ITableColumnModel;
- import org.apache.tapestry.contrib.table.model.common.BlockTableRendererSource;
- import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
- import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
- import datasource.DataItem;
- import datasource.BirthDateComparator;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import org.apache.tapestry.event.PageEvent;
- import org.apache.tapestry.event.PageRenderListener;
- import org.apache.tapestry.html.BasePage;
- import org.apache.tapestry.util.ComponentAddress;
- /**
- *
- */
- public abstract class DirectLinkTableColumnPage extends BasePage implements
- PageRenderListener {
- public abstract List getDataItems();
- public abstract void setDataItems(List dataItems);
- public abstract String getSelectedSSN();
- public abstract void setSelectedSSN(String selectedSSN);
- private IPrimaryKeyConvertor m_dataItemConvertor;
- public DirectLinkTableColumnPage() {
- super();
- // define a IPrimaryKeyConvertor that gets DataItems from the original
- // list
- m_dataItemConvertor = new IPrimaryKeyConvertor() {
- public Object getPrimaryKey(Object objValue) {
- DataItem dataItem = (DataItem) objValue;
- return dataItem.getSSN();
- }
- public Object getValue(Object objPrimaryKey) {
- String SSN = (String) objPrimaryKey;
- List list = getDataItems();
- // find the item
- int count = list.size();
- for (int i = 0; i < count; i++) {
- DataItem item = (DataItem) list.get(i);
- if (item.getSSN().equals(SSN)) {
- return item;
- }
- }
- return new DataItem(); //Handle data item not found
- }
- };
- }
- // authored by Rick Austin
- public void SelectListener(IRequestCycle cycle) {
- Object[] parameters = cycle.getServiceParameters();
- String SSN = (String) parameters[0];
- // Output the parameter value to the console to see if
- // this works.
- System.out.println("Selected SSN: " + SSN);
- setSelectedSSN(SSN);
- }
- public IPrimaryKeyConvertor getDataItemConvertor() {
- return m_dataItemConvertor;
- }
- public void pageBeginRender(PageEvent event) {
- List list = getDataItems();
- if (list == null) {
- setDataItems(((TapestryTablesVisit) getVisit()).getDataItems());
- }
- }
- public ITableColumn getBirthDateColumn() {
- // The column value is extracted in a custom evaluator class
- SimpleTableColumn birthDateColumn = new SimpleTableColumn("BirthDate",
- "Birth Date", new BirthDateColumnEvaluator(), true);
- birthDateColumn.setColumnComparator(new BirthDateComparator());
- return birthDateColumn;
- }
- /**
- * A class defining the logic for getting the BirthDate from a DataItem
- */
- private static class BirthDateColumnEvaluator implements
- ITableColumnEvaluator {
- /**
- * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn,
- * Object)
- */
- public Object getColumnValue(ITableColumn objColumn, Object objRow) {
- DataItem dataItem = (DataItem) objRow;
- if (dataItem == null) {
- return "No Birthdate";
- }
- return dataItem.getBirthDate();
- }
- }
- public void formSubmit(IRequestCycle cycle) {
- System.out.println("The form was submitted");
- /*
- * RequestContext context = cycle.getRequestContext();
- *
- * System.out.println(context.getParameter("hiddenCurrentPage"));
- *
- * //int iterRows = Integer.parseInt(context.getParameter("iterRows"));
- * String ew = "editableWeight"; for (int i=0; i < 6; i++) { String
- * suffix; if (i==0) { suffix = ""; } else { suffix = "$" + (i-1); }
- * String editableWeightString = context.getParameter(ew + suffix);
- * if(editableWeightString != null) { System.out.println("The " + ew +
- * suffix + " parameter is: " + editableWeightString ); } }
- * // Process the submitted form List list = getDataItems();
- * // Do something to process the list changes int count = list.size();
- * for (int i = 0; i < 1; i++) { DataItem item = (DataItem) list.get(i);
- * System.out.println(item.getWeight()); }
- * // Always important to set peristent properties; otherwise changes //
- * made in this request cycle will be lost. The framework // makes a
- * copy of the list. setDataItems(list);
- */
- }
- public ITableColumnModel getColumnModel()
- {
- return new ColumnModel();
- }
- class ColumnModel implements ITableColumnModel {
- private HashMap columns;
- public ColumnModel() {
- this.columns = new HashMap();
- SimpleTableColumn column1 = new SimpleTableColumn("SSN", "SSN",
- new ITableColumnEvaluator()
- {
- public Object getColumnValue(ITableColumn objColumn,
- Object objRow)
- {
- return ((DataItem) objRow).getSSN();
- }
- }, true);
- // The following overrides the default SimpleTableColumn.getColumnValue to
- // render the Block component we defined on the HTML template
- column1.setValueRendererSource(new BlockTableRendererSource(new ComponentAddress(getComponent("SSNColumnValue"))));
- ITableColumn column2 = new SimpleTableColumn("LastName", "LastName",
- new ITableColumnEvaluator()
- {
- public Object getColumnValue(ITableColumn objColumn,
- Object objRow)
- {
- return ((DataItem) objRow).getLastName();
- }
- }, true);
- ITableColumn column3 = new SimpleTableColumn("FirstName", "FirstName",
- new ITableColumnEvaluator() {
- public Object getColumnValue(ITableColumn objColumn,
- Object objRow) {
- return ((DataItem) objRow).getFirstName();
- }
- }, true);
- ITableColumn column4 = new SimpleTableColumn("Height", "Height",
- new ITableColumnEvaluator() {
- public Object getColumnValue(ITableColumn objColumn,
- Object objRow) {
- return ((DataItem) objRow).getHeight();
- }
- }, true);
- ITableColumn column5 = new SimpleTableColumn("Width", "Width",
- new ITableColumnEvaluator() {
- public Object getColumnValue(ITableColumn objColumn,
- Object objRow) {
- return ((DataItem) objRow).getHeight();
- }
- }, true);
- columns.put(column1.getColumnName(), column1);
- columns.put(column2.getColumnName(), column2);
- columns.put(column3.getColumnName(), column3);
- columns.put(getBirthDateColumn().getColumnName(), getBirthDateColumn());
- columns.put(column4.getColumnName(), column4);
- columns.put(column5.getColumnName(), column5);
- }
- public int getColumnCount() {
- return this.columns.size();
- }
- public ITableColumn getColumn(String strName) {
- return (ITableColumn) columns.get(strName);
- }
- public Iterator getColumns() {
- return columns.values().iterator();
- }
- }
- }
EditableColumnPage.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import tapestrytables.TapestryTablesVisit;
- import org.apache.tapestry.IRequestCycle;
- import org.apache.tapestry.contrib.table.model.ITableColumn;
- import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
- import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
- import datasource.DataItem;
- import datasource.BirthDateComparator;
- import java.util.List;
- import org.apache.tapestry.event.PageEvent;
- import org.apache.tapestry.event.PageRenderListener;
- import org.apache.tapestry.html.BasePage;
- /**
- *
- */
- public abstract class EditableColumnPage extends BasePage implements PageRenderListener
- {
- public abstract List getDataItems();
- public abstract void setDataItems(List dataItems);
- public void pageBeginRender(PageEvent event)
- {
- List list = getDataItems();
- if (list == null)
- {
- setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
- }
- }
- public ITableColumn getBirthDateColumn()
- {
- // The column value is extracted in a custom evaluator class
- SimpleTableColumn birthDateColumn = new SimpleTableColumn("BirthDate", "Birth Date", new BirthDateColumnEvaluator(), true);
- birthDateColumn.setColumnComparator(new BirthDateComparator());
- return birthDateColumn;
- }
- /**
- * A class defining the logic for getting the BirthDate from a DataItem
- */
- private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
- {
- /**
- * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
- */
- public Object getColumnValue(ITableColumn objColumn, Object objRow)
- {
- DataItem dataItem = (DataItem) objRow;
- return dataItem.getBirthDate();
- }
- }
- public void formSubmit(IRequestCycle cycle)
- {
- System.out.println("The form was submitted");
- // Process the submitted form
- List list = getDataItems();
- // Do something to process the list changes
- //int count = list.size();
- //for (int i = 0; i < count; i++)
- //{
- // DataItem item = (DataItem) list.get(i);
- // System.out.println(item.getWeight());
- //}
- // Always important to set peristent properties; otherwise changes
- // made in this request cycle will be lost. The framework
- // makes a copy of the list.
- setDataItems(list);
- }
- }
EditableColumnPage2.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import tapestrytables.TapestryTablesVisit;
- import org.apache.tapestry.IRequestCycle;
- import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
- import org.apache.tapestry.contrib.table.model.ITableColumn;
- import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
- import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
- import datasource.DataItem;
- import datasource.BirthDateComparator;
- import java.util.List;
- import org.apache.tapestry.event.PageEvent;
- import org.apache.tapestry.event.PageRenderListener;
- import org.apache.tapestry.html.BasePage;
- /**
- *
- */
- public abstract class EditableColumnPage2 extends BasePage implements PageRenderListener
- {
- public abstract List getDataItems();
- public abstract void setDataItems(List dataItems);
- private IPrimaryKeyConvertor m_dataItemConvertor;
- public EditableColumnPage2()
- {
- super();
- // define a IPrimaryKeyConvertor that gets DataItems from the original list
- m_dataItemConvertor = new IPrimaryKeyConvertor()
- {
- public Object getPrimaryKey(Object objValue)
- {
- DataItem dataItem = (DataItem) objValue;
- return dataItem.getSSN();
- }
- public Object getValue(Object objPrimaryKey)
- {
- String SSN = (String)objPrimaryKey;
- List list = getDataItems();
- // find the item
- int count = list.size();
- for (int i = 0; i < count; i++)
- {
- DataItem item = (DataItem) list.get(i);
- if (item.getSSN().equals(SSN)){
- return item;
- }
- }
- return new DataItem(); //Handle data item not found
- }
- };
- }
- public IPrimaryKeyConvertor getDataItemConvertor()
- {
- return m_dataItemConvertor;
- }
- public void pageBeginRender(PageEvent event)
- {
- List list = getDataItems();
- if (list == null)
- {
- setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
- }
- }
- public ITableColumn getBirthDateColumn()
- {
- // The column value is extracted in a custom evaluator class
- SimpleTableColumn birthDateColumn = new SimpleTableColumn("BirthDate", "Birth Date", new BirthDateColumnEvaluator(), true);
- birthDateColumn.setColumnComparator(new BirthDateComparator());
- return birthDateColumn;
- }
- /**
- * A class defining the logic for getting the BirthDate from a DataItem
- */
- private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
- {
- /**
- * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
- */
- public Object getColumnValue(ITableColumn objColumn, Object objRow)
- {
- DataItem dataItem = (DataItem) objRow;
- if( dataItem == null )
- {
- return "No Birthdate";
- }
- return dataItem.getBirthDate();
- }
- }
- public void formSubmit(IRequestCycle cycle)
- {
- System.out.println("The form was submitted");
- /*
- RequestContext context = cycle.getRequestContext();
- System.out.println(context.getParameter("hiddenCurrentPage"));
- //int iterRows = Integer.parseInt(context.getParameter("iterRows"));
- String ew = "editableWeight";
- for (int i=0; i < 6; i++)
- {
- String suffix;
- if (i==0) {
- suffix = "";
- } else {
- suffix = "$" + (i-1);
- }
- String editableWeightString = context.getParameter(ew + suffix);
- if(editableWeightString != null)
- {
- System.out.println("The " + ew + suffix + " parameter is: " + editableWeightString );
- }
- }
- // Process the submitted form
- List list = getDataItems();
- // Do something to process the list changes
- int count = list.size();
- for (int i = 0; i < 1; i++)
- {
- DataItem item = (DataItem) list.get(i);
- System.out.println(item.getWeight());
- }
- // Always important to set peristent properties; otherwise changes
- // made in this request cycle will be lost. The framework
- // makes a copy of the list.
- setDataItems(list);
- */
- }
- }
FirstPass.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import tapestrytables.TapestryTablesVisit;
- import java.util.List;
- import org.apache.tapestry.event.PageEvent;
- import org.apache.tapestry.event.PageRenderListener;
- import org.apache.tapestry.html.BasePage;
- /**
- *
- */
- public abstract class FirstPass extends BasePage implements PageRenderListener
- {
- public abstract List getDataItems();
- public abstract void setDataItems(List dataItems);
- public void pageBeginRender(PageEvent event)
- {
- List list = getDataItems();
- if (list == null)
- {
- setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
- }
- }
- }
TapestryTablesVisit.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- *
- * This class pretty much corresponds to a users session object
- * It is accessible from all of the pages in the application
- */
- package tapestrytables;
- import datasource.DataSource;
- import java.io.Serializable;
- import java.util.List;
- /**
- *
- */
- public class TapestryTablesVisit implements Serializable
- {
- DataSource dataSource;
- public TapestryTablesVisit()
- {
- dataSource = new DataSource();
- }
- /**
- * @return Returns the list of Data Items.
- */
- public List getDataItems() {
- return dataSource.getDataItems();
- }
- }
TestPage.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import java.util.List;
- import org.apache.tapestry.IRequestCycle;
- import org.apache.tapestry.contrib.table.components.TableView;
- import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
- import org.apache.tapestry.event.PageEvent;
- import org.apache.tapestry.event.PageRenderListener;
- import org.apache.tapestry.form.IPropertySelectionModel;
- import org.apache.tapestry.form.StringPropertySelectionModel;
- import org.apache.tapestry.html.BasePage;
- import org.apache.tapestry.request.RequestContext;
- import org.apache.tapestry.valid.ValidationDelegate;
- import datasource.DataItem;
- /**
- *
- */
- public abstract class TestPage extends BasePage implements PageRenderListener
- {
- public abstract List getDataItems();
- public abstract void setDataItems(List dataItems);
- public abstract String getColumnsString();
- public abstract void setColumnsString(String cols);
- public static final IPropertySelectionModel COLUMNS_MODEL =
- new StringPropertySelectionModel(new String[] {
- "SSN, FirstName, LastName",
- "SSN, LastName, FirstName",
- "LastName, FirstName",
- "LastName, SSN, FirstName" });
- private IPrimaryKeyConvertor m_dataItemConvertor;
- public TestPage()
- {
- super();
- // define a IPrimaryKeyConvertor that gets DataItems from the original list
- m_dataItemConvertor = new IPrimaryKeyConvertor()
- {
- public Object getPrimaryKey(Object objValue)
- {
- DataItem dataItem = (DataItem) objValue;
- return dataItem.getSSN();
- }
- public Object getValue(Object objPrimaryKey)
- {
- String SSN = (String)objPrimaryKey;
- List list = getDataItems();
- // find the item
- int count = list.size();
- for (int i = 0; i < count; i++)
- {
- DataItem item = (DataItem) list.get(i);
- if (item.getSSN().equals(SSN)){
- return item;
- }
- }
- return new DataItem(); //Handle data item not found
- }
- };
- }
- public IPrimaryKeyConvertor getDataItemConvertor()
- {
- return m_dataItemConvertor;
- }
- String colsString = "SSN, FirstName, LastName";
- //int count = 0;
- public void pageBeginRender(PageEvent event)
- {
- List list = getDataItems();
- if (list == null)
- {
- setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
- }
- //String colStrings = event.getPage().getMessage("ColumnsString");
- //setColumnsString(columnsStrings[count%3]);
- setColumnsString(colsString);
- System.out.println("setColumnsString(" + colsString + ")");
- }
- public void formSubmit(IRequestCycle cycle)
- {
- colsString = getColumnsString();
- System.out.println("The form was submitted");
- ValidationDelegate delegate = (ValidationDelegate)getBeans().getBean("delegate");
- if(delegate.getHasErrors()) {
- // there are errors
- RequestContext context = cycle.getRequestContext();
- String currentPage = context.getParameter("hiddenCurrentPage");
- int currentPageInt = new Integer(currentPage).intValue();
- System.out.println("The current page is: " + currentPageInt );
- TableView tableView = (TableView)getComponent("tableView");
- if( tableView != null )
- {
- System.out.println("Setting the current page back to " + currentPageInt);
- // Remember, "hiddenCurrentPage" starts at "1": setCurrentPage is "0" based
- tableView.getTableModel().getPagingState().setCurrentPage(currentPageInt-1);
- }
- return;
- }
- }
- }
ValidateEditableColumnPage.java
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import tapestrytables.TapestryTablesVisit;
- import org.apache.tapestry.IRequestCycle;
- import org.apache.tapestry.contrib.table.components.FormTable;
- import org.apache.tapestry.contrib.table.components.TableView;
- import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
- import org.apache.tapestry.contrib.table.model.ITableColumn;
- import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
- import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
- import datasource.DataItem;
- import datasource.BirthDateComparator;
- import java.util.List;
- import org.apache.tapestry.event.PageEvent;
- import org.apache.tapestry.event.PageRenderListener;
- import org.apache.tapestry.html.BasePage;
- import org.apache.tapestry.request.RequestContext;
- import org.apache.tapestry.valid.ValidationDelegate;
- /**
- *
- */
- public abstract class ValidateEditableColumnPage extends BasePage implements PageRenderListener
- {
- public abstract List getDataItems();
- public abstract void setDataItems(List dataItems);
- private IPrimaryKeyConvertor m_dataItemConvertor;
- public ValidateEditableColumnPage()
- {
- super();
- // define a IPrimaryKeyConvertor that gets DataItems from the original list
- m_dataItemConvertor = new IPrimaryKeyConvertor()
- {
- public Object getPrimaryKey(Object objValue)
- {
- DataItem dataItem = (DataItem) objValue;
- return dataItem.getSSN();
- }
- public Object getValue(Object objPrimaryKey)
- {
- String SSN = (String)objPrimaryKey;
- List list = getDataItems();
- // find the item
- int count = list.size();
- for (int i = 0; i < count; i++)
- {
- DataItem item = (DataItem) list.get(i);
- if (item.getSSN().equals(SSN)){
- return item;
- }
- }
- return new DataItem(); //Handle data item not found
- }
- };
- }
- public IPrimaryKeyConvertor getDataItemConvertor()
- {
- return m_dataItemConvertor;
- }
- public void pageBeginRender(PageEvent event)
- {
- List list = getDataItems();
- if (list == null)
- {
- setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
- }
- }
- public ITableColumn getBirthDateColumn()
- {
- // The column value is extracted in a custom evaluator class
- SimpleTableColumn birthDateColumn = new SimpleTableColumn("BirthDate", "Birth Date", new BirthDateColumnEvaluator(), true);
- birthDateColumn.setColumnComparator(new BirthDateComparator());
- return birthDateColumn;
- }
- /**
- * A class defining the logic for getting the BirthDate from a DataItem
- */
- private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
- {
- /**
- * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
- */
- public Object getColumnValue(ITableColumn objColumn, Object objRow)
- {
- DataItem dataItem = (DataItem) objRow;
- if( dataItem == null )
- {
- return "No Birthdate";
- }
- return dataItem.getBirthDate();
- }
- }
- public void formSubmit(IRequestCycle cycle) {
- System.out.println("The form was submitted");
- ValidationDelegate delegate = (ValidationDelegate) getBeans().getBean(
- "delegate");
- if (delegate.getHasErrors()) {
- // there are errors
- RequestContext context = cycle.getRequestContext();
- String currentPage = context.getParameter("hiddenCurrentPage");
- if (currentPage != null) {
- int currentPageInt = new Integer(currentPage).intValue();
- System.out.println("The current page is: " + currentPageInt);
- FormTable formTable = (FormTable) getComponent("table");
- if (formTable != null) {
- System.out.println("Setting the current page back to "
- + currentPageInt);
- // Remember, "hiddenCurrentPage" starts at "1":
- // setCurrentPage is "0" based
- formTable.getTableModel().getPagingState().setCurrentPage(
- currentPageInt - 1);
- }
- }else {
- System.out.println("The parameter hiddenCurrentPage doesn't exist");
- // hiddenCurrentPage doesn't exist if there is only one page in the table
- }
- return;
- }
- }
- }
- /* Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- */
- package tapestrytables;
- import tapestrytables.TapestryTablesVisit;
- import org.apache.tapestry.IRequestCycle;
- import org.apache.tapestry.contrib.table.components.FormTable;
- import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
- import org.apache.tapestry.contrib.table.model.ITableColumn;
- import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
- import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
- import datasource.DataItem;
- import datasource.BirthDateComparator;
- import java.util.List;
- import org.apache.tapestry.event.PageEvent;
- import org.apache.tapestry.event.PageRenderListener;
- import org.apache.tapestry.html.BasePage;
- import org.apache.tapestry.request.RequestContext;
- import org.apache.tapestry.valid.ValidationDelegate;
- /**
- *
- */
- public abstract class ValidateEditableColumnPage2 extends BasePage implements PageRenderListener
- {
- public abstract List getDataItems();
- public abstract void setDataItems(List dataItems);
- private IPrimaryKeyConvertor m_dataItemConvertor;
- public ValidateEditableColumnPage2()
- {
- super();
- // define a IPrimaryKeyConvertor that gets DataItems from the original list
- m_dataItemConvertor = new IPrimaryKeyConvertor()
- {
- public Object getPrimaryKey(Object objValue)
- {
- DataItem dataItem = (DataItem) objValue;
- return dataItem.getSSN();
- }
- public Object getValue(Object objPrimaryKey)
- {
- String SSN = (String)objPrimaryKey;
- List list = getDataItems();
- // find the item
- int count = list.size();
- for (int i = 0; i < count; i++)
- {
- DataItem item = (DataItem) list.get(i);
- if (item.getSSN().equals(SSN)){
- return item;
- }
- }
- return new DataItem(); //Handle data item not found
- }
- };
- }
- public IPrimaryKeyConvertor getDataItemConvertor()
- {
- return m_dataItemConvertor;
- }
- public void pageBeginRender(PageEvent event)
- {
- List list = getDataItems();
- if (list == null)
- {
- setDataItems(((TapestryTablesVisit)getVisit()).getDataItems());
- }
- }
- public ITableColumn getBirthDateColumn()
- {
- // The column value is extracted in a custom evaluator class
- SimpleTableColumn birthDateColumn = new SimpleTableColumn("BirthDate", "BirthDate", new BirthDateColumnEvaluator(), true);
- birthDateColumn.setColumnComparator(new BirthDateComparator());
- // Pick up any settings from the template and page
- birthDateColumn.loadSettings(this);
- return birthDateColumn;
- }
- /**
- * A class defining the logic for getting the BirthDate from a DataItem
- */
- private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
- {
- /**
- * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
- */
- public Object getColumnValue(ITableColumn objColumn, Object objRow)
- {
- DataItem dataItem = (DataItem) objRow;
- if( dataItem == null )
- {
- return "No Birthdate";
- }
- return dataItem.getBirthDate();
- }
- }
- public void formSubmit(IRequestCycle cycle) {
- System.out.println("The form was submitted");
- ValidationDelegate delegate = (ValidationDelegate) getBeans().getBean(
- "delegate");
- if (delegate.getHasErrors()) {
- // there are errors
- RequestContext context = cycle.getRequestContext();
- String currentPage = context.getParameter("hiddenCurrentPage");
- if (currentPage != null) {
- int currentPageInt = new Integer(currentPage).intValue();
- System.out.println("The current page is: " + currentPageInt);
- FormTable formTable = (FormTable) getComponent("table");
- if (formTable != null) {
- System.out.println("Setting the current page back to "
- + currentPageInt);
- // Remember, "hiddenCurrentPage" starts at "1":
- // setCurrentPage is "0" based
- formTable.getTableModel().getPagingState().setCurrentPage(
- currentPageInt - 1);
- }
- }else {
- System.out.println("The parameter hiddenCurrentPage doesn't exist");
- // hiddenCurrentPage doesn't exist if there is only one page in the table
- }
- return;
- }
- }
- }
style.css
- body
- {
- font-family : Trebuchet MS, san serif;
- font-weight : normal;
- }
- table.mytable
- {
- border-style: solid;
- border-color: black;
- border-width: 1px;
- }
- th.columnheader
- {
- background-color: rgb(228,228,228);
- }
- td.tablepager
- {
- background-color: rgb(228,228,228);
- }
- tr.even
- {
- background-color: lightblue;
- }
- tr.odd
- {
- background-color: rgb(228,255,228);
- }
- code.snippet
- {
- color: red;
- }
- code.highlight
- {
- color: red;
- background-color: rgb(255,255,128);
- }
- span.inputerror
- {
- color: red;
- font-weight : strong;
- background-color: yellow;
- }
- div.code
- {
- color: red;
- background-color: rgb(255,255,228);
- }
- div.note
- {
- background-color: rgb(228,255,228);
- }
- TABLE.palette TH
- {
- font-size: 9pt;
- font-weight: bold;
- color: white;
- background-color: #330066;
- text-align: center;
- }
- TABLE.palette SELECT
- {
- font-weight: bold;
- background-color: #839cd1;
- width: 200px;
- }
- TABLE.palette TD.controls
- {
- text-align: center;
- vertical-align: middle;
- width: 60px;
- }
ColumnChooser.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Choosing and Ordering Columns</h1>
- <div class="note">
- This page demonstrates how to choose and order the table columns at runtime.
- </div>
- <p>The columns that are displayed in the table can be dynamically specified
- rather then hard-coded. It's a simple as setting the <code>columns</code>
- parameter to an expression rather then a string.
- </p><p>
- To demonstrate run-time column selection, we'll use a two-step process.
- Use the following <code>contrib:Palette</code> to select
- the columns that you wish to see in the table (select at least one column),
- and then select the <code>Continue</code> button to see the results.
- </p>
- <form jwcid="@Form" listener="ognl:listeners.formSubmit">
- <table class="form">
- <tr>
- <th>Columns:</th>
- <td><input jwcid="chooseColumns"/></td>
- </tr>
- <tr>
- <td></td>
- <td>
- <input type="submit" value="Continue"/>
- <code class="highlight"><span jwcid="@Insert" value="ognl:errorMsg"/></code>
- </td>
- </tr>
- </table>
- <p>
- I chose to use the <code>contrib:Palette</code> for this example because
- it is fairly straight-forward to use. Regardless of how you choose to
- specify the columns and their order, you must pass the columns
- to the Table's page before activating the page. Here is the
- relevent code from <code>ColumnChooserPage.java</code>:
- <pre><code class="snippet">
- public void formSubmit(IRequestCycle cycle)
- {
- ColumnChooserPage2 resultsPage = (ColumnChooserPage2) cycle.getPage("ColumnChooser2");
- if( _selectedColumns != null && _selectedColumns.size()>0)
- {
- // Convert the List to a String of comma-seperated ColumnIDs
- StringBuffer selectedColumns = new StringBuffer();
- for (int i=0; i < _selectedColumns.size(); i++) {
- // Crude mapping of Labels to ColumnIDs
- String columnString = (String)_selectedColumns.get(i);
- if (columnString.equals("First Name")) {
- selectedColumns.append("FirstName");
- } else if (columnString.equals("Last Name")) {
- selectedColumns.append("LastName");
- } else if (columnString.equals("Birth Date")) {
- selectedColumns.append("=birthDateColumn");
- } else {
- selectedColumns.append(columnString);
- }
- if( i < (_selectedColumns.size()-1)) {
- selectedColumns.append(",");
- }
- }
- <code class="highlight"> resultsPage.setSelectedColumns(selectedColumns.toString());
- cycle.activate(resultsPage);
- </code> }
- }
- </code></pre>
- </form>
- <p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
ColumnChooser.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.ColumnChooserPage">
- <context-asset name="stylesheet" path="css/style.css"/>
- <component id="chooseColumns" type="contrib:Palette">
- <binding name="model" expression="columnModel"/>
- <binding name="selected" expression="selectedColumns"/>
- <binding name="sort" expression="sort"/>
- <static-binding name="tableClass" value="palette"/>
- </component>
- </page-specification>
ColumnChooser2.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Choosing and Ordering Columns</h1>
- <div class="note">
- This page demonstrates how to choose and order the table columns at runtime.
- </div>
- <p>
- The following <code>Table</code> should display the columns that you
- specified on the previous page (in the order you chose):
- </p><p>
- <form jwcid="form">
- <table class="mytable" jwcid="table">
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- </form>
- </p><p>
- If you take a look at the files <code>ColumnChooser2.html</code>,
- <code>ColumnChooser2.page</code> and <code>ColumnChooserPage2.java</code>
- you will see the elements necessary to specify the columns at runtime.
- </p><p>
- Here are the relevent additions to <code>ColumnChooser2.page</code>
- that sets up the <code>Table</code> to get the <code>columns</code>
- by evaluating an expression:
- </p><p>
- <pre><code class="snippet">
- <component id="table" type="contrib:FormTable">
- <binding name="source" expression="dataItems"/>
- <binding name="convertor" expression="dataItemConvertor"/>
- <code class="highlight"><binding name="columns" expression="ColumnsString" /></code>
- <binding name="rowsClass" expression="beans.evenOdd.next"/>
- <binding name="pageSize" expression="6"/>
- </component>
- </code></pre>
- </p><p>
- </p><p>
- Here is the method that was added to <code>ColumnChooserPage2.java</code>
- to accept output from the column selector on the previous page:
- </p><p>
- <code class="highlight"><pre>
- public void setSelectedColumns( String selectedColumns)
- {
- _selectedColumns = selectedColumns;
- colsString = selectedColumns;
- }
- </pre></code>
- </p><p>
- That's all there is to it. Simply pass the desired columns to the page
- before it is rendered.
- </p><p>
- <a href="#" jwcid="@PageLink" page="TenthPass">Using TableView, TableColumns, and TableFormRows...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
ColumnChooser2.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.ColumnChooserPage2">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <property-specification name="columnsString" type="java.lang.String" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- <component id="form" type="Form">
- <binding name="listener" expression="listeners.formSubmit"/>
- </component>
- <component id="table" type="contrib:FormTable">
- <binding name="source" expression="dataItems"/>
- <binding name="convertor" expression="dataItemConvertor"/>
- <binding name="columns" expression="ColumnsString" />
- <binding name="rowsClass" expression="beans.evenOdd.next"/>
- <binding name="pageSize" expression="6"/>
- </component>
- </page-specification>
ColumnChooser2.properties
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
DirectLinkColumn.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Direct Links</h1>
- <div class="note">
- This page demonstrates how to embed direct links in a column.
- </div>
- <p>
- Rick Austin provided the prototype for this page.
- The key, as discovered by Rick, is to use two components; a DirectLink
- for the link functionality and an InsertText to render the text.
- When you click
- on one of the SSN links, the label below the table will be updated to indicate
- your selection:
- </p><p>
- <form jwcid="form">
- <table class="mytable" jwcid="table">
- <span jwcid="SSNColumnValue@Block">
- <span jwcid="SSNLink">
- <span jwcid="SSNText"/>
- </span>
- </span>
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- <input type="submit" value="Update"/>
- </form>
- <div class="note">
- The last SSN that was selected was:
- <code class="highlight"><span jwcid="SelectedSSNText"/></code>
- </div>
- </p><p>
- If you take a look at the files <code>DirectLinkColumn.html</code>,
- <code>DirectLinkColumn.page</code> and <code>DirectLinkColumn.java</code>
- you will see the elements necessary to embed direct links in a column.
- </p><p>
- Here are the relevent additions to <code>DirectLinkColumn.page</code>
- that sets up the components necessary for the links:
- </p><p>
- <code class="highlight"><pre>
- <!--
- * Used to create a link which has a listener and passes in the current
- * SSN as a parameter.
- -->
- <component id="SSNLink" type="DirectLink">
- <binding name="listener" expression="listeners.SelectListener"/>
- <binding name="parameters" expression="components.table.tableRow.SSN"/>
- </component>
- <!--
- * Used to output the SSN value into the row since the SSNLink component
- * creates a link but does not have a way of providing the link text.
- -->
- <component id="SSNText" type="InsertText">
- <binding name="value" expression="components.table.tableRow.SSN"/>
- </component>
- </pre></code>
- </p><p>
- Here is the relevent snippet from <code>DirectLink.html</code>
- that sets up the links:
- </p><p>
- <code class="snippet"><pre>
- <table class="mytable" jwcid="table">
- <code class="highlight"><span jwcid="SSNColumnValue@Block">
- <span jwcid="SSNLink">
- <span jwcid="SSNText"/>
- </span>
- </span></code>
- </pre></code>
- </p><p>
- </p><p>
- Here is the method that was added to <code>DirectLinkColumnPage.java</code>
- to process the links:
- </p><p>
- <code class="highlight"><pre>
- // authored by Rick Austin
- public void SelectListener(IRequestCycle cycle) {
- Object[] parameters = cycle.getServiceParameters();
- String SSN = (String)parameters[0];
- // Output the parameter value to the console to see if
- // this works.
- System.out.println("Selected SSN: " + SSN);
- }
- </pre></code>
- </p><p>
- <a href="#" jwcid="@PageLink" page="DirectLinkTableColumn">Direct Link using TableColumns...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="ColumnChooser">Choosing and Ordering Columns...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
DirectLinkColumn.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.DirectLinkColumnPage">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <property-specification name="selectedSSN" type="java.lang.String" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- <component id="form" type="Form">
- <binding name="listener" expression="listeners.formSubmit"/>
- </component>
- <component id="table" type="contrib:FormTable">
- <binding name="source" expression="dataItems"/>
- <binding name="convertor" expression="dataItemConvertor"/>
- <static-binding name="columns"
- value="
- SSN,
- FirstName,
- LastName,
- =birthDateColumn,
- Height,
- Weight"/>
- <binding name="rowsClass" expression="beans.evenOdd.next"/>
- <binding name="pageSize" expression="6"/>
- <static-binding name="initialSortColumn" value="BirthDate"/>
- </component>
- <!--
- * Used to create a link which has a listener and passes in the current
- * SSN as a parameter.
- -->
- <component id="SSNLink" type="DirectLink">
- <binding name="listener" expression="listeners.SelectListener"/>
- <binding name="parameters" expression="components.table.tableRow.SSN"/>
- </component>
- <!--
- * Used to output the SSN value into the row since the SSNLink component
- * creates a link but does not have a way of providing the link text.
- -->
- <component id="SSNText" type="InsertText">
- <binding name="value" expression="components.table.tableRow.SSN"/>
- </component>
- <!--
- * Used to output the selected SSN value.
- -->
- <component id="SelectedSSNText" type="InsertText">
- <binding name="value" expression="selectedSSN"/>
- </component>
- </page-specification>
DirectLinkColumn.properties
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
DirectLinkTableColumn.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Direct Links when using TableColumns</h1>
- <div class="note">
- This page demonstrates how to embed direct links in a column when using
- a TableColumns object to define the columns.
- </div>
- <p>
- A question from Christian M�hlethaler prompted me to create this example.
- </p><p>
- The previous Direct Link example works if the columns are defined using a String, but
- it wasn't obvious how to make this work if the columns are defined using
- a <code>TableColumns</code> object.
- </p><p>
- The "trick" is to define a Column within your TableColumns that will get its
- ValueRenderer from your HTML template.
- </p><p>
- <form jwcid="form">
- <table class="mytable" jwcid="table">
- <span jwcid="SSNColumnValue@Block">
- <span jwcid="SSNLink">
- <span jwcid="SSNText"/>
- </span>
- </span>
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- <input type="submit" value="Update"/>
- </form>
- <div class="note">
- The last SSN that was selected was:
- <code class="highlight"><span jwcid="SelectedSSNText"/></code>
- </div>
- </p><p>
- If you take a look at the files <code>DirectLinkTableColumn.html</code>,
- <code>DirectLinkTableColumn.page</code> and <code>DirectLinkTableColumn.java</code>
- you will see the elements necessary to embed direct links when using <code>TableColumns</code>.
- </p><p>
- Here are the relevent additions to <code>DirectTableLinkColumn.page</code>
- that sets up the table to use a <code>TableColumns</code> object:
- </p><p>
- <code class="snippet"><pre>
- <component id="table" type="contrib:FormTable">
- <binding name="source" expression="dataItems"/>
- <binding name="convertor" expression="dataItemConvertor"/>
- <binding name="columns"
- <code class="highlight">expression="columnModel"</code>/>
- <binding name="rowsClass" expression="beans.evenOdd.next"/>
- <binding name="pageSize" expression="6"/>
- <static-binding name="initialSortColumn" value="BirthDate"/>
- </component>
- </pre></code>
- </p><p>
- Here is the method and the private class that was added to <code>DirectLinkTableColumnPage.java</code>
- to define the TableColumnModel:
- </p><p>
- <div class="code"><pre>
- public ITableColumnModel getColumnModel()
- {
- return new ColumnModel();
- }
- class ColumnModel implements ITableColumnModel {
- private HashMap columns;
- public ColumnModel() {
- this.columns = new HashMap();
- SimpleTableColumn column1 = new SimpleTableColumn("SSN", "SSN",
- new ITableColumnEvaluator()
- {
- public Object getColumnValue(ITableColumn objColumn,
- Object objRow)
- {
- return ((DataItem) objRow).getSSN();
- }
- }, true);
- <code class="highlight">
- // The following overrides the default ValueRendererSource to
- // render the Block component we defined on the HTML template
- column1.setValueRendererSource(
- new BlockTableRendererSource(
- new ComponentAddress(
- getComponent("SSNColumnValue"))));
- </code>
- ITableColumn column2 = new SimpleTableColumn("LastName", "LastName",
- new ITableColumnEvaluator()
- {
- public Object getColumnValue(ITableColumn objColumn,
- Object objRow)
- {
- return ((DataItem) objRow).getLastName();
- }
- }, true);
- ITableColumn column3 = new SimpleTableColumn("FirstName", "FirstName",
- new ITableColumnEvaluator() {
- public Object getColumnValue(ITableColumn objColumn,
- Object objRow) {
- return ((DataItem) objRow).getFirstName();
- }
- }, true);
- ITableColumn column4 = new SimpleTableColumn("Height", "Height",
- new ITableColumnEvaluator() {
- public Object getColumnValue(ITableColumn objColumn,
- Object objRow) {
- return ((DataItem) objRow).getHeight();
- }
- }, true);
- ITableColumn column5 = new SimpleTableColumn("Width", "Width",
- new ITableColumnEvaluator() {
- public Object getColumnValue(ITableColumn objColumn,
- Object objRow) {
- return ((DataItem) objRow).getHeight();
- }
- }, true);
- columns.put(column1.getColumnName(), column1);
- columns.put(column2.getColumnName(), column2);
- columns.put(column3.getColumnName(), column3);
- columns.put(getBirthDateColumn().getColumnName(), getBirthDateColumn());
- columns.put(column4.getColumnName(), column4);
- columns.put(column5.getColumnName(), column5);
- }
- public int getColumnCount() {
- return this.columns.size();
- }
- public ITableColumn getColumn(String strName) {
- return (ITableColumn) columns.get(strName);
- }
- // Quick and dirty iterator
- public Iterator getColumns() {
- return columns.values().iterator();
- }
- }
- </pre></div>
- </p>
- <div class="note">
- Note that the column ordering is "wierd" only because my quick and dirty example
- uses a <code>HashMap</code> to hold the <code>SimpleTableColumn</code> objects.
- </div>
- <p>
- <a href="#" jwcid="@PageLink" page="ColumnChooser">Choosing and Ordering Columns...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
DirectLinkTableColumn.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.DirectLinkTableColumnPage">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <property-specification name="selectedSSN" type="java.lang.String" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- <component id="form" type="Form">
- <binding name="listener" expression="listeners.formSubmit"/>
- </component>
- <component id="table" type="contrib:FormTable">
- <binding name="source" expression="dataItems"/>
- <binding name="convertor" expression="dataItemConvertor"/>
- <binding name="columns"
- expression="columnModel"/>
- <binding name="rowsClass" expression="beans.evenOdd.next"/>
- <binding name="pageSize" expression="6"/>
- <static-binding name="initialSortColumn" value="BirthDate"/>
- </component>
- <!--
- * Used to create a link which has a listener and passes in the current
- * SSN as a parameter.
- -->
- <component id="SSNLink" type="DirectLink">
- <binding name="listener" expression="listeners.SelectListener"/>
- <binding name="parameters" expression="components.table.tableRow.SSN"/>
- </component>
- <!--
- * Used to output the SSN value into the row since the SSNLink component
- * creates a link but does not have a way of providing the link text.
- -->
- <component id="SSNText" type="InsertText">
- <binding name="value" expression="components.table.tableRow.SSN"/>
- </component>
- <!--
- * Used to output the selected SSN value.
- -->
- <component id="SelectedSSNText" type="InsertText">
- <binding name="value" expression="selectedSSN"/>
- </component>
- </page-specification>
DirectLinkTableColumn.properties
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
EighthPass.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Validating Editable Columns</h1>
- <div class="note">
- This page demonstrates how to validate user input in an editable table.
- </div>
- <p>
- It's almost always necessary to check the user's input before accepting it.
- </p><p>
- Try entering a non-numeric value in any of the <code>Weight</code> fields in
- the following table.
- </p><p>
- <form jwcid="form">
- <table class="mytable" jwcid="table">
- <span jwcid="WeightColumnValue">
- <span jwcid="editableWeight"/>
- </span>
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- <input type="submit" value="Update"/>
- <span class="inputerror"><span jwcid="errors"/></span>
- </form>
- </p><p>
- If you take a look at the files <code>Eighth.html</code>, <code>EighthPass.page</code>
- and <code>ValidateEditableColumnPage.java</code>
- you will see the changes necessary to validate the user's input.
- </p><p>
- In the file <code>Eighth.html</code> we added the following to display any errors:
- </p><p>
- <code class="highlight">
- <span class="inputerror"><span jwcid="errors"/><span>
- </code>
- </p><p>
- Here is the relevent snippets from <code>EighthPass.page</code>
- that sets up this component:
- </p><p>
- <pre>
- <code class="snippet">
- <code class="highlight">
- <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
- <bean name="numberValidator" class="org.apache.tapestry.valid.NumberValidator" lifecycle="page">
- <set-property name="required" expression="true"/>
- <set-property name="clientScriptingEnabled" expression="false"/>
- </bean>
- </code>
- <component id="form" type="Form">
- <binding name="listener" expression="listeners.formSubmit"/>
- <code class="highlight">
- <binding name="delegate" expression="beans.delegate"/>
- </code>
- </component>
- <component id="table" type="contrib:FormTable">
- <binding name="source" expression="dataItems"/>
- <binding name="convertor" expression="dataItemConvertor"/>
- <static-binding name="columns"
- value="
- SSN,
- FirstName,
- LastName,
- =birthDateColumn,
- Height,
- Weight"/>
- <binding name="rowsClass" expression="beans.evenOdd.next"/>
- <binding name="pageSize" expression="6"/>
- <static-binding name="initialSortColumn" value="BirthDate"/>
- </component>
- <component id="WeightColumnValue" type="Block"/>
- <component id="editableWeight" <code class="highlight">type="ValidField"></code>
- <static-binding name="displayName">Weight</static-binding>
- <binding name="value" expression="components.table.tableRow.Weight"/>
- <binding name="size" expression="4"/>
- <code class="highlight"><binding name="validator" expression='beans.numberValidator'/></code>
- </component>
- <code class="highlight">
- <component id="errors" type="Delegator">
- <binding name="delegate" expression="beans.delegate.firstError"/>
- </component>
- </code>
- </code>
- </pre>
- </p><p>
- The response to validation errors is handled in <code>ValidateEditableColumnPage.java</code>:
- <code class="snippet">
- <pre>
- public void formSubmit(IRequestCycle cycle) {
- System.out.println("The form was submitted");
- <code class="highlight"> ValidationDelegate delegate = (ValidationDelegate) getBeans().getBean(
- "delegate");
- if (delegate.getHasErrors()) {
- // there are errors
- RequestContext context = cycle.getRequestContext();
- String currentPage = context.getParameter("hiddenCurrentPage");
- if (currentPage != null) {
- int currentPageInt = new Integer(currentPage).intValue();
- System.out.println("The current page is: " + currentPageInt);
- FormTable formTable = (FormTable) getComponent("table");
- if (formTable != null) {
- System.out.println("Setting the current page back to "
- + currentPageInt);
- // Remember, "hiddenCurrentPage" starts at "1":
- // setCurrentPage is "0" based
- formTable.getTableModel().getPagingState().setCurrentPage(
- currentPageInt - 1);
- }
- }else {
- System.out.println("The parameter hiddenCurrentPage doesn't exist");
- // hiddenCurrentPage doesn't exist if there is only one page in the table }
- return;
- }
- }
- </code></pre></code>
- <a href="#" jwcid="@PageLink" page="NinthPass">Combining Validation and Sorting...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
EighthPass.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.ValidateEditableColumnPage">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
- <bean name="numberValidator" class="org.apache.tapestry.valid.NumberValidator" lifecycle="page">
- <set-property name="required" expression="false"/>
- <set-property name="clientScriptingEnabled" expression="true"/>
- </bean>
- <component id="form" type="Form">
- <binding name="listener" expression="listeners.formSubmit"/>
- <binding name="delegate" expression="beans.delegate"/>
- </component>
- <component id="table" type="contrib:FormTable">
- <binding name="source" expression="dataItems"/>
- <binding name="convertor" expression="dataItemConvertor"/>
- <static-binding name="columns"
- value="
- SSN,
- FirstName,
- LastName,
- =birthDateColumn,
- Height,
- Weight"/>
- <binding name="rowsClass" expression="beans.evenOdd.next"/>
- <binding name="pageSize" expression="6"/>
- <static-binding name="initialSortColumn" value="BirthDate"/>
- </component>
- <component id="WeightColumnValue" type="Block"/>
- <component id="editableWeight" type="ValidField">
- <static-binding name="displayName">Weight</static-binding>
- <binding name="value" expression="components.table.tableRow.Weight"/>
- <binding name="size" expression="4"/>
- <binding name="validator" expression='beans.numberValidator'/>
- </component>
- <component id="errors" type="Delegator">
- <binding name="delegate" expression="beans.delegate.firstError"/>
- </component>
- </page-specification>
EighthPass.properties
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
FifthPass.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Simple Editable Column</h1>
- <div class="note">
- This page demonstrates how to implement a table with an editable column.
- </div>
- <p>
- This example for using the Tapestry Table components is going to move
- beyond the initial requirements. We are now going to implement an editable column,
- transforming the table from read-only to gathering user input.
- </p><p>
- The table below allows the user to edit the <code>Weight</code> column. Hopefully
- these values are stable or heading down ;-)
- </p><p>
- <form jwcid="@Form" listener="ognl:listeners.formSubmit">
- <table class="mytable" jwcid="table@contrib:Table"
- source="ognl:dataItems"
- columns="SSN, FirstName, LastName,
- =birthDateColumn, Height, Weight"
- rowsClass="ognl:beans.evenOdd.next"
- pageSize="6"
- initialSortColumn="BirthDate">
- <span jwcid="WeightColumnValue@Block">
- <span jwcid="editableWeight@TextField" value="ognl:components.table.tableRow.Weight" size="4"/>
- </span>
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- <input type="submit" value="Update"/>
- </form>
- </p><p>
- <b>Note:</b> The changes you make in the table on this page will not be submitted
- unless you press the <code>Update</code> button.
- Ideally any changes that the user makes would
- be submitted prior to paging or sorting the table.
- We'll take care of that later. The really observant out there
- have probably also noticed that the <code>Weight</code> column doesn't
- validate the user's input. We'll get around to dealing with that too.
- </p><p>
- If you take a look at the files <code>FifthPass.html</code>, <code>FifthPass.page</code>
- and <code>EditableColumnPage.java</code>,
- you will see the changes made to make the <code>Weight</code> column editable.
- We've inserted a <code>TextField</code> component, but the same technique
- could be used for other components.
- </p><p>
- Here are the relevent HTML snippets from <code>FifthPass.html</code>
- that sets up this component:
- </p><p>
- To begin, we had to wrap the <code>table</code> inside a form and we added a button
- to submit any changes:
- </p><p>
- <code class="highlight">
- <form jwcid="@Form" listener="ognl:listeners.formSubmit">
- </code>
- </p><p>
- <code class="highlight">
- <input type="submit" value="Update"/>
- </code>
- </p><p>
- We then made the following changes to the <code>Weight</code> column in the <code>table</code>:
- </p><p>
- <code class="snippet"><pre>
- <table class="mytable" jwcid="table@contrib:Table"
- source="ognl:dataItems"
- columns="SSN, FirstName, LastName,
- =birthDateColumn, Height,
- <code class="highlight">Weight</code>"
- rowsClass="ognl:beans.evenOdd.next"
- pageSize="6"
- initialSortColumn="BirthDate">
- <code class="highlight">
- <span jwcid="WeightColumnValue@Block">
- <span jwcid="editableWeight@TextField" value="ognl:components.table.tableRow.Weight" size="4"/>
- </span>
- </code>
- </pre></code>
- </p><p>
- The expression <code>jwcid="WeightColumnValue@Block"</code> tells Tapestry to
- suspend normal processing when rendering values for the <code>Weight</code> column.
- Instead of normal rendering, the <code>editableWeight</code> component
- (a <code>TextField</code>) will be displayed.
- </p><p>
- The <code>editableWeight</code> gets its values by evaluating the expression
- <code>ognl:components.table.tableRow.Weight</code>. In a nutshell, the
- <code>getWeight()</code> is being called on the <code>DataItem</code> object
- that represents the current row of the table.
- </p><p>
- To process form submissions we had to change the <code>BasePage</code> derivative
- that underlies this page. This change is accomplished by making the following change to
- <code>FifthPass.page</code>:
- </p><p>
- <code class="snippet">
- <page-specification
- <code class="highlight">class="tapestrytables.EditableColumnPage"</code>>
- </code>
- </p><p>
- With the additional requirement to process form submissions, we need to add a bit of code to our underlying <code>Page</code> object.
- <code>EditableColumnPage.java</code> is the result.
- </p><p>
- Below is the code added to <code>EditableColumnPage.java</code> that handles
- form submissions:
- </p><pre>
- <code class="highlight">
- public void formSubmit(IRequestCycle cycle)
- {
- // Process the submitted form
- List list = getDataItems();
- // Do something to process the list changes
- int count = list.size();
- for (int i = 0; i < count; i++)
- {
- DataItem item = (DataItem) list.get(i);
- System.out.println(item.getWeight());
- }
- // Always important to set peristent properties; otherwise changes
- // made in this request cycle will be lost. The framework
- // makes a copy of the list.
- setDataItems(list);
- }
- </code>
- </pre>
- As you can see, it isn't very difficult make a column editable,
- but this example is unsatisfying because the user will lose changes
- unless the <code>Update</code> button is pressed prior to paging or sorting.
- A further problem concerns validating user input prior to updating the
- source data.
- <p>
- </p><p>
- <a href="#" jwcid="@PageLink" page="SixthPass">Editable Column with Implicit Submit...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
FifthPass.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.EditableColumnPage">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- </page-specification>
FifthPass.properties
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
FirstPass.html
- <html jwcid="@Shell" title="Tapestry Table Examples" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Paging and Sortable Table</h1>
- <div class="note">
- This page demonstrates how to implement a multi-page table that is sortable
- per column.
- </div>
- <p>
- This is our first pass at implementing the desired table using Tapestry components.
- As mentioned before, the data that populates the table is coming from a Java
- Bean.
- </p><p>
- <table class="mytable" jwcid="table@contrib:Table"
- source="ognl:dataItems"
- columns="SSN, FirstName, LastName, BirthDate, Height, Weight">
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- </p><p>
- If you take a look at the files <code>TapestryTables.application</code>, <code>FirstPass.html</code> and <code>FirstPass.page</code>,
- you will see that we
- have accomplished a great deal of functionality with very little work.
- The table on this page displays data from our <code>DataSource</code> Java Bean
- on multiple pages,
- a navigation component helps the user page through the table, and the table
- is sortable on any column (Observant folks may notice that sorting on the
- <code>BirthDate</code> column isn't quite right. We will address that
- <a href="#" jwcid="@PageLink" page="FourthPass">later</a>).
- </p><p>
- Here is the relevent HTML snippet from <code>FirstPass.html</code>
- that sets up this component:
- </p><p>
- <code class="highlight">
- <table class="mytable" jwcid="table@contrib:Table"
- <br>
- source="ognl:dataItems"
- <br>
- columns="SSN, FirstName, LastName, BirthDate, Height, Weight">
- </code>
- </p><p>
- The <code>source</code> is set up by adding the following lines to
- <code>FirstPass.page</code>:
- </p><p>
- <code clas="snippet">
- <page-specification
- <code class="highlight">
- class="tapestrytables.FirstPass"</code>>
- <br>
- <property-specification
- <code class="highlight">name="dataItems"</code>
- type="java.util.List" persistent="yes"/>
- </page-specification>
- </code>
- </p><p>
- In a nutshell, this page specification tells Tapestry to instantiate and maintain a persitent
- <code>List</code> by invoking the method
- <code>tapestrytables.FirstPass.getDataItems()</code>.
- </p><p>
- Functionally, this page is pretty awesome, but the table doesn't look right.
- We'll have to do some more work to match the vision of our HTML designer.
- </p><p>
- <a href="#" jwcid="@PageLink" page="SecondPass">Column Headings...</a>
- </p>
- <p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/
- * October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
FirstPass.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <page-specification class="tapestrytables.FirstPass">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- </page-specification>
FourthPass.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Custom Column Sorting</h1>
- <div class="note">
- This page demonstrates how to implement custom sorting on a column, how
- to set the initial sort column, and how to disable sorting on a column.
- </div>
- <p>
- This is our fourth pass at implementing the table using Tapestry components.
- Our third pass got the "look" of the page right, but we need to go back and
- address the <code>Birth Date</code> column sorting problem we noticed earlier.
- </p><p>
- <div class="note">
- <b>Note:</b> We could avoid implementing a custom sort by simply returning a
- <code>Date</code> object from the underlying <code>DataItem.getBirthDate()</code>,
- but I wanted to demonstrate custom column sorting.
- </div>
- </p><p>
- By default, the sorting is based on the "type" of the data item rendered
- for each column. Our <code>Birth Date</code> column contains <code>Strings</code> in MM/DD/YYYY format,
- so a simple string compare won't suffice. The following table correctly sorts on the
- <code>BirthDate</code> column:
- </p><p>
- <table class="mytable" jwcid="table@contrib:Table"
- source="ognl:dataItems"
- columns="SSN, !FirstName, LastName,
- =birthDateColumn, Height, Weight"
- rowsClass="ognl:beans.evenOdd.next"
- pageSize="6"
- initialSortColumn="BirthDate">
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- </p><p>
- If you take a look at the files <code>FouthPass.html</code>, <code>FourthPass.page</code>
- and <code>CustomSortColumnPage.java</code>,
- you will see the changes made to get the <code>Birth Date</code> column to sort properly.
- </p><p>
- Here is the relevent HTML snippet from <code>FourthPass.html</code>
- that sets up this component:
- <pre><code class="snippet">
- <table class="mytable" jwcid="table@contrib:Table"
- source="ognl:dataItems"
- columns="SSN, <code class="highlight">!FirstName</code>, LastName, <code class="highlight">=birthDateColumn</code>, Height, Weight"
- rowsClass="ognl:beans.evenOdd.next"
- pageSize="6"
- <code class="highlight">initialSortColumn="BirthDate"</code>>
- </code>
- </pre>
- </p><p>
- To demonstrate that you can disable sorting on a column I simply preceded the column ID <code>FirstName</code> with a '!'.
- </p><p>
- To make it more obvious that sorting is working for this example, I set the
- initial sort column to the birth date column by setting the following <code>Table</code> attribute:
- <code>initialSortColumn="BirthDate"</code> ("BirthDate" is the ID of the column).
- </p><p>
- Custom sorting is a bit more involved.
- The expression <code>=birthDateColumn</code> tells Tapestry to get an ITableColumn
- object for this column from a method named
- <code>getBirthDateColumn()</code>.
- </p><p>
- To define this object, we'll have to change the <code>BasePage</code> derivative
- that underlies our page. This is accomplished by making the following change to
- <code>FourthPass.page</code>:
- </p><p>
- <code class="snippet">
- <page-specification
- <code class="highlight">class="tapestrytables.CustomSortColumnPage"</code>>
- </code>
- </p><p>
- Up until this example, all of our pages have been using the same
- <code>BasePage</code> derivative. With the additional requirement to implement
- custom sorting for one of the columns, we need to add a bit of code.
- <code>CustomSortColumnPage.java</code> is the result.
- </p><p>
- Below is the code added to <code>CustomSortColumnPage.java</code> that provides custom
- sorting on the <code>BirthDate</code> column:
- </p><p>
- <pre><code class="highlight">
- public ITableColumn getBirthDateColumn()
- {
- // The column value is extracted in a custom evaluator class
- SimpleTableColumn birthDateColumn =
- new SimpleTableColumn("Birth Date", new BirthDateColumnEvaluator(), true);
- birthDateColumn.setColumnComparator(new BirthDateComparator());
- return birthDateColumn;
- }
- /**
- * A class defining the logic for getting the BirthDate from a DataItem
- */
- private static class BirthDateColumnEvaluator implements ITableColumnEvaluator
- {
- /**
- * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn, Object)
- */
- public Object getColumnValue(ITableColumn objColumn, Object objRow)
- {
- DataItem dataItem = (DataItem) objRow;
- return dataItem.getBirthDate();
- }
- }
- </code></pre>
- </p><p>
- Not shown here is the custom comparator that I created to compare two
- <code>BirthDate</code> strings. My <code>BirthDateComparator.java</code> is an
- embarrassing hack, but it's sufficient to make this example work.
- </p><p>
- At this point, our read-only table is pretty much complete. There are a few more
- tweaks we could perform, but it's probably more interesting to move on to embedding
- components for individual fields in the table.
- </p><p>
- <a href="#" jwcid="@PageLink" page="FifthPass">Simple Editable Column...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.CustomSortColumnPage">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- </page-specification>
FourthPass.properties
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
Home.html
- <html jwcid="@Shell" title="Using The Tapestry Table Control" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Using The Tapestry Table Control</h1>
- <div class="note">
- by John Reynolds: Updated on October 26th 2004
- </div>
- <p>
- This application demonstrates some common ways to use the Tapestry Table components.
- Thanks to
- Howard Lewis Ship and the many subscribers of the Tapestry Users List who offered
- suggestions and guidance.
- </p><p>
- The Table component and its supporting cast of components are very powerful
- and very flexible. This is a double-edged sword that can result in confusion
- when first learning how to use these components.
- </p><p>
- This application provides a series of pages that demonstrate one way of configuring
- the Table to produce desired behaviors. The chosen techniques may not be optimal,
- but hopefully they will be understandable and will help you figure out how to reach
- your own objectives.
- </p><p>
- Below is a standard HTML table that will serve as the basis for all of the
- examples.
- A guiding principal of Tapestry is to preserve the ability to view the HTML
- templates in a standard browser. In the spirit of this principal, I will use
- the following HTML table as the starting point for all that follows:
- </p><p>
- <table class="mytable">
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>06/02/1960</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>06/02/1960</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>06/02/1960"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>06/02/1960</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- </p><p>
- The previous table is representative of the input that a Tapestry developer might
- receive from an HTML designer. The table reflects the desired layout of the
- columns and demonstrates the desired "look
- and feel" by using a css style sheet to dictate the appearance of the
- table.
- </p><p>
- The data displayed by the table on this page is hard-coded. The "real" data will be supplied
- by a Java Bean, and the data set will contain many more rows then conveniently fit
- on a single page. The final application will split the data into multiple pages and
- allow sorting on any column of the table... but we're getting ahead of ourselves...
- </p><p>
- <a href="#" jwcid="@PageLink" page="FirstPass">Basic Paging and Sortable Table...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="SecondPass">Column Headings...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="ThirdPass">Alternating Row Colors...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="FourthPass">Custom Column Sorting...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="FifthPass">Simple Editable Column...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="SixthPass">Editable Column with Implicit Submit...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="SeventhPass">Editable Columns using Formal Parameter Coding Style...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="EighthPass">Validating Editable Columns...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="NinthPass">Combining Validation and Sorting...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="DirectLinkColumn">Direct Link Columns...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="ColumnChooser">Choosing and Ordering Columns...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="TenthPass">Using TableView, TableColumns, and TableFormRows..</a>
- <a href="#" jwcid="@PageLink" page="Test">.</a>
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/
- * October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
Home.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="org.apache.tapestry.html.BasePage">
- <description><![CDATA[ This is the home page ]]></description>
- <context-asset name="stylesheet" path="css/style.css"/>
- </page-specification>
NinthPass.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Combining Validation and Sorting</h1>
- <div class="note">
- This page demonstrates how to implement an editable column that must be validated
- and has custom sorting.
- </div>
- <p>
- It's sometimes necessary to combine validation and custom sorting. This is actually
- very easy to do, and it's demonstrated below by making the Birth Date column editable
- while preserving the earlier custom sorting:
- </p><p>
- <form jwcid="form">
- <table class="mytable" jwcid="table">
- <span jwcid="BirthDateColumnValue@Block">
- <span jwcid="editableBirthDate"/>
- </span>
- <span jwcid="WeightColumnValue@Block">
- <span jwcid="editableWeight"/>
- </span>
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- <input type="submit" value="Update"/>
- <span class="inputerror"><span jwcid="errors"/></span>
- </form>
- </p><p>
- </p><p>
- If you take a look at the files <code>NinthPass.page</code>
- and <code>ValidateEditableColumnPage2.page</code>
- you will see the changes necessary to validate the user's input.
- </p><p>
- Here are the relevent snippets from <code>NinthPass.page</code>
- that sets up validation for the <code>BirthDate</code> using the
- bundled <code>PatternValidator</code> class:
- <pre>
- <code class="highlight">
- <bean name="birthDateValidator" class="org.apache.tapestry.valid.PatternValidator" lifecycle="page">
- <set-property name="required" expression="true"/>
- <set-property name="clientScriptingEnabled" expression="true"/>
- <set-property name="patternString">"//d//d///d//d///d//d//d//d$"</set-property> <
- <set-property name="patternNotMatchedMessage">
- "Error: Date improperly formatted. Should be like: MM/DD/YYYY"</set-property>
- </bean>
- <component id="editableBirthDate" type="ValidField">
- <static-binding name="displayName">Weight</static-binding>
- <binding name="value" expression="components.table.tableRow.BirthDate"/>
- <binding name="size" expression="4"/>
- <binding name="validator" expression='beans.birthDateValidator'/>
- </component>
- </code>
- </pre>
- </p><p>
- Here is the relevent snippet from <code>NinthPass.html</code>
- that sets up validation for the <code>BirthDate</code>:
- <pre>
- <code class="snippet">
- <table class="mytable" jwcid="table">
- <code class="highlight"> <span jwcid="BirthDateColumnValue@Block">
- <span jwcid="editableBirthDate"/>
- </span>
- </code> <span jwcid="WeightColumnValue@Block">
- <span jwcid="editableWeight"/>
- </span>
- </code>
- </pre>
- </p><p>
- Finally, here is the relevent snippet from <code>ValidateEditableColumnPage2.java</code>
- that picks up the <code>ValidField</code> component for the <code>BirthDate</code>:
- <pre>
- <code class="snippet">
- public ITableColumn getBirthDateColumn()
- {
- // The column value is extracted in a custom evaluator class
- SimpleTableColumn birthDateColumn = new SimpleTableColumn("BirthDate", new BirthDateColumnEvaluator(), true);
- birthDateColumn.setColumnComparator(new BirthDateComparator());
- <code class="highlight"> // Pick up any settings from the template and page
- birthDateColumn.loadSettings(this);
- </code>
- return birthDateColumn;
- }
- </code>
- </pre>
- </p><p>
- The method <code>birthDateColumn.loadSettings(this)</code> picks up any relevent
- Blocks defined for <code>BirthDate</code> in the template of this page, exactly as if
- the column was defined in the standard way.
- </p><p>
- <a href="#" jwcid="@PageLink" page="DirectLinkColumn">Direct Link Columns...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
NinthPass.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.ValidateEditableColumnPage2">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
- <bean name="numberValidator" class="org.apache.tapestry.valid.NumberValidator" lifecycle="page">
- <set-property name="required" expression="true"/>
- <set-property name="clientScriptingEnabled" expression="false"/>
- </bean>
- <bean name="birthDateValidator" class="org.apache.tapestry.valid.PatternValidator" lifecycle="page">
- <set-property name="required" expression="true"/>
- <set-property name="clientScriptingEnabled" expression="false"/>
- <set-property name="patternString">"//d//d///d//d///d//d//d//d$"</set-property>
- <set-property name="patternNotMatchedMessage">
- "Error: Date improperly formatted. Should be like: MM/DD/YYYY"</set-property>
- </bean>
- <component id="form" type="Form">
- <binding name="listener" expression="listeners.formSubmit"/>
- <binding name="delegate" expression="beans.delegate"/>
- </component>
- <component id="table" type="contrib:FormTable">
- <binding name="source" expression="dataItems"/>
- <binding name="convertor" expression="dataItemConvertor"/>
- <static-binding name="columns"
- value="
- SSN,
- FirstName,
- LastName,
- =birthDateColumn,
- Height,
- Weight"/>
- <binding name="rowsClass" expression="beans.evenOdd.next"/>
- <binding name="pageSize" expression="6"/>
- <static-binding name="initialSortColumn" value="BirthDate"/>
- </component>
- <component id="editableBirthDate" type="ValidField">
- <static-binding name="displayName">Weight</static-binding>
- <binding name="value" expression="components.table.tableRow.BirthDate"/>
- <binding name="size" expression="10"/>
- <binding name="validator" expression='beans.birthDateValidator'/>
- </component>
- <component id="editableWeight" type="ValidField">
- <static-binding name="displayName">Weight</static-binding>
- <binding name="value" expression="components.table.tableRow.Weight"/>
- <binding name="size" expression="4"/>
- <binding name="validator" expression='beans.numberValidator'/>
- </component>
- <component id="errors" type="Delegator">
- <binding name="delegate" expression="beans.delegate.firstError"/>
- </component>
- </page-specification>
NinthPass.properties
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
SecondPass.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Column Headings</h1>
- <div class="note">
- This page demonstrates how to get column names from a property file.
- </div>
- <p>
- This is our second attempt to implement the table using Tapestry components.
- Our first pass was functionally awesome, but the "look" of the page left
- much to be desired. In the table below, you will see that we've cleaned
- up the column names:
- </p><p>
- <table class="mytable" jwcid="table@contrib:Table"
- source="ognl:dataItems"
- columns="SSN, FirstName, LastName,
- BirthDate, Height, Weight">
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>06/02/1960</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>06/02/1960</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>06/02/1960"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>06/02/1960</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>06/02/1960</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>06/02/1960</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- </p><p>
- If you take a look at the file <code>SecondPass.properties</code>
- you will see what we had to do to improve the "look" of this page.
- The files <code>SecondPass.html</code> and <code>SecondPass.page</code>
- are just renamed copies of the files from the previous example.
- </p><p>
- When you create a properties file,
- the properties defined in the file will override any column names defined in
- the "page" or html "template".
- For example, the title for the <code>BirthDate</code> column on this page is coming from
- <code>SecondPass.properties</code>.
- The string '<code>BirthBirthDate = Birth Date</code>' overrides any setting in
- <code>SecondPass.html</code>. This is a very
- valuable technique, especially when you want to internationalize your applications.
- </p><p>
- Here are the property definitions from <code>SecondPass.properties</code>:
- <pre><code class="highlight">
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
- </code></pre>
- </p><p>
- We still haven't achieved the "look" that we want, but we are getting closer.
- </p><p>
- <a href="#" jwcid="@PageLink" page="ThirdPass">Alternating Row Colors...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
SecondPass.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.FirstPass">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- </page-specification>
SecondPass.properties
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
SeventhPass.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Editable Columns using Formal Parameter Coding Style</h1>
- <div class="note">
- This page demonstrates how to use Tapestry's "formal" parameter style to
- more cleanly divide the HTML from the component specifications.
- </div>
- <p>
- This page has the same functionality as the
- <a href="#" jwcid="@PageLink" page="SixthPass">Editable Column with Implicit Submit</a>
- example, but I have
- switched from specifying details in the <code>html</code> file to specifying
- details in the <code>page</code> file. This is referred to as using <code>formal</code>
- parameters.
- </p><p>
- <form jwcid="form">
- <table class="mytable" jwcid="table">
- <span jwcid="WeightColumnValue">
- <span jwcid="editableWeight"/>
- </span>
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- <input type="submit" value="Update"/>
- </form>
- </p><p>
- </p><p>
- If you take a look at the files <code>SeventhPass.html</code>
- and <code>SeventhPass.page</code>,
- you will notice significant changes from the earlier <code>html</code> and
- <code>page</code> files. This is more a matter of style rather then substance,
- switching from the use of informal parameters to formal parameters. Generally,
- more sophisticated pages benefit from formal parameters by reducing the "clutter"
- in the <code>html</code> file.
- </p><p>
- Here are the relevent HTML snippets from <code>SeventhPass.html</code>
- that sets up this component:
- </p><p>
- <code class="highlight">
- <form jwcid="form">
- <br> <table class="mytable" jwcid="table">
- <br> <span jwcid="WeightColumnValue">
- <br> <span jwcid="editableWeight"/>
- <br> </span>
- </code>
- </p><p>
- As you can see, this is much less invasive.
- </p><p>
- Here is the relevent snippets from <code>SeventhPass.page</code>
- that sets up this component:
- </p><p>
- <code class="highlight">
- <pre>
- <component id="form" type="Form">
- <binding name="listener" expression="listeners.formSubmit">
- </component>
- <component id="table" type="contrib:FormTable">
- <binding name="source" expression="dataItems"/>
- <binding name="convertor" expression="dataItemConvertor"/>
- <static-binding name="columns"
- value="
- SSN,
- FirstName,
- LastName,
- =birthDateColumn,
- Height,
- Weight"/>
- <binding name="rowsClass" expression="beans.evenOdd.next"/>
- <binding name="pageSize" expression="6"/>
- <static-binding name="initialSortColumn" value="BirthDate"/>
- </component>
- <component id="WeightColumnValue" type="Block"/>
- <component id="editableWeight" type="TextField">
- <binding name="value" expression="components.table.tableRow.Weight"/>
- <binding name="size" expression="4"/>
- </component>
- </pre>
- </code>
- </p><p>
- As you can see, the world isn't quite perfect. You must indicate on the
- <code>html</code> template whenever you wish to override the rendering of
- a column in a table even though the component is specified in the
- <code>page</code> file. Judging from the Tapestry Users List, this seems
- to trip up newbies quite often.
- </p><p>
- Now that we've changed coding styles, it's time to get back to adding
- functionality.
- </p><p>
- <a href="#" jwcid="@PageLink" page="EighthPass">Validating Editable Columns...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
SeventhPass.page
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.EditableColumnPage2">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- <component id="form" type="Form">
- <binding name="listener" expression="listeners.formSubmit"/>
- </component>
- <component id="table" type="contrib:FormTable">
- <binding name="source" expression="dataItems"/>
- <binding name="convertor" expression="dataItemConvertor"/>
- <static-binding name="columns"
- value="
- SSN,
- FirstName,
- LastName,
- =birthDateColumn,
- Height,
- Weight"/>
- <binding name="rowsClass" expression="beans.evenOdd.next"/>
- <binding name="pageSize" expression="6"/>
- <static-binding name="initialSortColumn" value="BirthDate"/>
- </component>
- <component id="WeightColumnValue" type="Block"/>
- <component id="editableWeight" type="TextField">
- <binding name="value" expression="components.table.tableRow.Weight"/>
- <binding name="size" expression="4"/>
- </component>
- </page-specification>
SeventhPass.properties
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Editable Column with Implicit Submit</h1>
- <div class="note">
- This page demonstrates how to implement a table with an editable column
- that saves changes when "paging" or "sorting" the table.
- </div>
- <p>
- The first implementation of an editable column had a few drawbacks, one
- of which was the requirement to press the <code>Update</code> button
- to submit changes.
- </p><p>
- The table below captures changes before changing the sort order or moving
- to another page:
- </p><p>
- <form jwcid="@Form" listener="ognl:listeners.formSubmit" >
- <table class="mytable" jwcid="table@contrib:FormTable"
- source="ognl:dataItems"
- convertor="ognl:dataItemConvertor"
- columns="SSN, FirstName, LastName,
- =birthDateColumn, Height, Weight"
- rowsClass="ognl:beans.evenOdd.next"
- pageSize="6"
- initialSortColumn="BirthDate" >
- <span jwcid="WeightColumnValue@Block">
- <span jwcid="editableWeight@TextField" value="ognl:components.table.tableRow.Weight" size="4"/>
- </span>
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- <input type="submit" value="Update"/>
- </form>
- </p><p>
- </p><p>
- If you take a look at the files <code>SixthPass.html</code>, <code>SixthPass.page</code>
- and <code>EditableColumnPage2.java</code>,
- you will see the changes made to submit the form before changing the sort order
- or paging.
- </p><p>
- Here are the relevent HTML snippets from <code>SixthPass.html</code>
- that sets up this component:
- </p><p>
- <code class="snippet"><pre>
- <table class="mytable" <code class="highlight">jwcid="table@contrib:FormTable"</code>
- source="ognl:dataItems"
- <code class="highlight">convertor="ognl:dataItemConvertor"</code>
- columns="SSN, FirstName, LastName,
- =birthDateColumn, Height, Weight"
- rowsClass="ognl:beans.evenOdd.next"
- pageSize="6"
- initialSortColumn="BirthDate" >
- <span jwcid="WeightColumnValue@Block">
- <span jwcid="editableWeight@TextField" value="ognl:components.table.tableRow.Weight" size="4"/>
- </span>
- </pre></code>
- </p><p>
- There are some big changes here, the table is now based on <code>contrib:FormTable</code>
- rather then <code>contrib:Table</code>. <code>FormTable</code> does many things for us,
- including making sure that the form is submitted whenever the table is paged or the sort
- order is changed.
- </p><p>
- <code>FormTable</code> also stores data into the form itself
- using hidden fields to avoid a <code>StaleLinkException</code> if the data changes on
- the server before the form is submitted.
- A side effect of this is that the default behavior of the <code>FormTable</code> is to modify
- copies of the data rather then the source data itself. Eventually we will need this behavior,
- but for this page we will force the <code>FormTable</code> to use the source objects directly.
- To do this
- we must implement an <code>IPrimaryKeyConvertor</code> and pass it to the <code>FormTable</code>.
- </p><p>
- The line:<code>convertor="ognl:dataItemConvertor"</code> configures the <code>FormTable</code>
- to get each <code>DataItem</code> by calling <code>getDataItemConvertor().getValue(Object objPrimaryKey)</code>.
- To create an <code>IPrimaryKeyConvertor</code> to return the original source objects, we added
- the following to <code>EditableColumnPage2.java</code>.
- </p><p>
- <code class="highlight">
- <pre>
- private IPrimaryKeyConvertor m_dataItemConvertor;
- public EditableColumnPage2()
- {
- super();
- // define a IPrimaryKeyConvertor that gets DataItems from the original list
- m_dataItemConvertor = new IPrimaryKeyConvertor()
- {
- public Object getPrimaryKey(Object objValue)
- {
- DataItem dataItem = (DataItem) objValue;
- return dataItem.getSSN();
- }
- public Object getValue(Object objPrimaryKey)
- {
- String SSN = (String)objPrimaryKey;
- List list = getDataItems();
- // find the item
- int count = list.size();
- for (int i = 0; i < count; i++)
- {
- DataItem item = (DataItem) list.get(i);
- if (item.getSSN().equals(SSN)){
- return item;
- }
- }
- return new DataItem(); //Handle data item not found
- }
- };
- }
- public IPrimaryKeyConvertor getDataItemConvertor()
- {
- return m_dataItemConvertor;
- }
- </pre></code>
- </p><p>
- This looks like an aweful lot of work just to get the <code>FormTable</code> to
- update the original source objects rather then copies, but you would seldomly
- do things this way. Generally, when users are updating values, you will want
- to validate the input. We'll get to that soon.
- </p><p>
- <a href="#" jwcid="@PageLink" page="SeventhPass">Using Formal Parameter Coding Style...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.EditableColumnPage2">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- </page-specification>
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE application
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <application name="TapestryTables" engine-class="org.apache.tapestry.engine.BaseEngine" >
- <description><![CDATA[ This application demonstrates the Tapestry Table components ]]></description>
- <property name="org.apache.tapestry.visit-class">tapestrytables.TapestryTablesVisit</property>
- <library id="contrib" specification-path="/org/apache/tapestry/contrib/Contrib.library"/>
- <page name="Home" specification-path="Home.page"/>
- </application>
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Using TableView, TableColumns, and TableFormRows</h1>
- <div class="note">
- This page demonstrates how to implement a table using TableView, TableColumns, and TableFormRows.
- </div>
- <p>
- The <code>Table</code> and <code>FormTable</code> components wrap several underlying components
- to simplify common usage scenarios. If you need to exert more control over the look of your table
- you can use these building blocks directly. For example, you can control where the
- "paging" component is displayed:
- </p><p>
- <form jwcid="form">
- <table class="mytable" jwcid="tableView">
- <span jwcid="tableColumns"/>
- <span jwcid="tableRows">
- <span jwcid="BirthDateColumnValue@Block">
- <span jwcid="editableBirthDate"/>
- </span>
- <span jwcid="WeightColumnValue@Block">
- <span jwcid="editableWeight"/>
- </span>
- <span jwcid="tableValues@contrib:TableValues"/>
- </span>
- <tr>
- <td colspan="7" class="tablepager">
- <span jwcid="tablePages@contrib:TableFormPages"/>
- </td>
- </tr>
- <span jwcid="$remove$">
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </span>
- </table>
- <input type="submit" value="Update"/>
- <span class="inputerror"><span jwcid="errors"/></span>
- </form>
- </p><p>
- </p><p>
- If you take a look at the files <code>TenthPass.page</code>
- and <code>TenthPass.html</code>
- you will see the changes necessary to implement this table.
- </p><p>
- Here are the relevent snippets from <code>TenthPass.page</code>
- :
- <pre>
- <code class="highlight">
- <component id="tableView" type="contrib:TableView">
- <binding name="source" expression="dataItems"/>
- <static-binding name="columns"
- value="
- SSN,
- FirstName,
- LastName,
- =birthDateColumn,
- Height,
- Weight"/>
- <binding name="pageSize" expression="6"/>
- <static-binding name="initialSortColumn" value="BirthDate"/>
- <static-binding name="cellpadding" value="2"/>
- <static-binding name="cellspacing" value="0"/>
- </component>
- <component id="tableColumns" type="contrib:TableColumns">
- <static-binding name="class" value="columnheader"/>
- </component>
- <component id="tableRows" type="contrib:TableFormRows">
- <binding name="convertor" expression="dataItemConvertor"/>
- <binding name="class" expression="beans.evenOdd.next"/>
- </component>
- </code><code class="snippet">
- <component id="editableBirthDate" type="ValidField">
- <static-binding name="displayName">Weight</static-binding>
- <binding name="value" <code class="highlight">expression="components.tableRows.tableRow.BirthDate"</code>/>
- <binding name="size" expression="10"/>
- <binding name="validator" expression='beans.birthDateValidator'/>
- </component>
- <component id="editableWeight" type="ValidField">
- <static-binding name="displayName">Weight</static-binding>
- <binding name="value" <code class="highlight">expression="components.tableRows.tableRow.Weight"</code>/>
- <binding name="size" expression="4"/>
- <binding name="validator" expression='beans.numberValidator'/>
- </component>
- </code>
- </pre>
- </p><p>
- Here is the relevent snippet from <code>TenthPass.html</code>
- that sets up the layout:
- <pre>
- <code class="highlight">
- <table class="mytable" jwcid="tableView">
- <span jwcid="tableColumns"/>
- <span jwcid="tableRows">
- <span jwcid="BirthDateColumnValue@Block">
- <span jwcid="editableBirthDate"/>
- </span>
- <span jwcid="WeightColumnValue@Block">
- <span jwcid="editableWeight"/>
- </span>
- <span jwcid="tableValues@contrib:TableValues"/>
- </span>
- <tr>
- <td colspan="7" class="tablepager">
- <span jwcid="tablePages@contrib:TableFormPages"/>
- </td>
- </tr>
- </code>
- </pre>
- </p><p>
- <!--
- </p><p>
- <a href="#" jwcid="@PageLink" page="FourthPass">Fourth Pass...</a>
- -->
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/ - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.ValidateEditableColumnPage2">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
- <bean name="numberValidator" class="org.apache.tapestry.valid.NumberValidator" lifecycle="page">
- <set-property name="required" expression="true"/>
- <set-property name="clientScriptingEnabled" expression="false"/>
- </bean>
- <bean name="birthDateValidator" class="org.apache.tapestry.valid.PatternValidator" lifecycle="page">
- <set-property name="required" expression="true"/>
- <set-property name="clientScriptingEnabled" expression="false"/>
- <set-property name="patternString">"//d//d///d//d///d//d//d//d$"</set-property>
- <set-property name="patternNotMatchedMessage">
- "Error: Date improperly formatted. Should be like: MM/DD/YYYY"</set-property>
- </bean>
- <component id="form" type="Form">
- <binding name="listener" expression="listeners.formSubmit"/>
- <binding name="delegate" expression="beans.delegate"/>
- </component>
- <component id="tableView" type="contrib:TableView">
- <binding name="source" expression="dataItems"/>
- <static-binding name="columns"
- value="
- SSN,
- FirstName,
- LastName,
- =birthDateColumn,
- Height,
- Weight"/>
- <binding name="pageSize" expression="6"/>
- <static-binding name="initialSortColumn" value="BirthDate"/>
- <static-binding name="cellpadding" value="2"/>
- <static-binding name="cellspacing" value="0"/>
- </component>
- <component id="tableColumns" type="contrib:TableColumns">
- <static-binding name="class" value="columnheader"/>
- </component>
- <component id="tableRows" type="contrib:TableFormRows">
- <binding name="convertor" expression="dataItemConvertor"/>
- <binding name="class" expression="beans.evenOdd.next"/>
- </component>
- <component id="editableBirthDate" type="ValidField">
- <static-binding name="displayName">Weight</static-binding>
- <binding name="value" expression="components.tableRows.tableRow.BirthDate"/>
- <binding name="size" expression="10"/>
- <binding name="validator" expression='beans.birthDateValidator'/>
- </component>
- <component id="editableWeight" type="ValidField">
- <static-binding name="displayName">Weight</static-binding>
- <binding name="value" expression="components.tableRows.tableRow.Weight"/>
- <binding name="size" expression="4"/>
- <binding name="validator" expression='beans.numberValidator'/>
- </component>
- <component id="errors" type="Delegator">
- <binding name="delegate" expression="beans.delegate.firstError"/>
- </component>
- </page-specification>
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
- <html jwcid="@Shell" title="Test" stylesheet="ognl:assets.stylesheet">
- <!--
- Released in the Public Domain by John Reynolds
- -->
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Test</h1> This page is a work in progress
- <p>
- <form jwcid="form">
- <table class="mytable" jwcid="tableView">
- <span jwcid="tablePages@contrib:TableFormPages" class="tablepager"/>
- <span jwcid="tableColumns"/>
- <span jwcid="tableRows">
- <span jwcid="SelectRowColumnValue@Block">
- <span jwcid="selectRow"/>
- </span>
- <span jwcid="SSNColumnValue@Block">
- <span jwcid="editableSSN"/>
- </span>
- <span jwcid="tableValues@contrib:TableValues"/>
- </span>
- </table>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- <input type="submit" value="Update"/>
- <span class="inputerror"><span jwcid="errors"/></span>
- Columns: <span jwcid="@PropertySelection" model="ognl:@tapestrytables.TestPage@COLUMNS_MODEL" value="ognl:columnsString" submitOnChange="true" />
- </form>
- </p><p>
- Here's a list of examples to add:
- <ul>
- <li>Create a checkbox per row, and a "select all" checkbox</li>
- <li>Demonstrate a custom TableModel for handling a huge number of rows</li>
- </ul>
- </p>
- </body>
- </html>
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <page-specification class="tapestrytables.TestPage">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <property-specification name="columnsString" type="java.lang.String" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>
- <bean name="ssnValidator" class="org.apache.tapestry.valid.PatternValidator" lifecycle="page">
- <set-property name="required" expression="true"/>
- <set-property name="clientScriptingEnabled" expression="false"/>
- <set-property name="patternString">"//d//d//d-//d//d-//d//d//d//d$"</set-property>
- <set-property name="patternNotMatchedMessage">
- "Error: SSN improperly formatted."</set-property>
- </bean>
- <component id="form" type="Form">
- <binding name="listener" expression="listeners.formSubmit"/>
- <binding name="delegate" expression="beans.delegate"/>
- </component>
- <component id="tableView" type="contrib:TableView">
- <binding name="source" expression="dataItems"/>
- <binding name="columns" expression="ColumnsString" />
- <!--
- <static-binding name="columns"
- value="
- !SelectRow,
- SSN,
- FirstName,
- LastName" />
- -->
- <binding name="pageSize" expression="12"/>
- <static-binding name="cellpadding" value="2"/>
- <static-binding name="cellspacing" value="0"/>
- <static-binding name="initialSortColumn" value="LastName"/>
- </component>
- <component id="tableColumns" type="contrib:TableColumns">
- <static-binding name="class" value="columnheader"/>
- </component>
- <component id="tableRows" type="contrib:TableFormRows">
- <binding name="convertor" expression="dataItemConvertor"/>
- <binding name="class" expression="beans.evenOdd.next"/>
- </component>
- <component id="editableSSN" type="ValidField">
- <static-binding name="displayName">SSN</static-binding>
- <binding name="value" expression="components.tableRows.tableRow.SSN"/>
- <binding name="size" expression="9"/>
- <binding name="validator" expression="beans.ssnValidator"/>
- </component>
- <component id="selectRow" type="Checkbox">
- <binding name="selected" expression="components.tableRows.tableRow.Selected"/>
- </component>
- <component id="errors" type="Delegator">
- <binding name="delegate" expression="beans.delegate.firstError"/>
- </component>
- </page-specification>
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
- ColumnsString = FirstName, LastName, SSN
ThirdPass.html
- <html jwcid="@Shell" title="Tapestry Table Controls Example" stylesheet="ognl:assets.stylesheet">
- <head jwcid="@Block">
- <link rel="stylesheet" type="text/css" href="../css/style.css"/>
- </head>
- <body jwcid="@Body">
- <h1>Alternating Row Colors</h1>
- <div class="note">
- This page demonstrates how to implement a table with alternating row colors and
- set the number of rows displayed on a page.
- </div>
- <p>
- This is our third pass at implementing the table using Tapestry components.
- Our second pass looked better, but the "look" of the page still wasn't right.
- We weren't picking up the "styles" that our HTML designer specified.
- </p><p>
- <table class="mytable" jwcid="table@contrib:Table"
- source="ognl:dataItems"
- columns="SSN, FirstName, LastName,
- BirthDate, Height, Weight"
- rowsClass="ognl:beans.evenOdd.next"
- pageSize="6" >
- <th>SSN</th>
- <th>First Name</th>
- <th>Last Name</th>
- <th>Birth Date</th>
- <th>Height</th>
- <th>Weight</th>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004"</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="even">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- <tr class="odd">
- <td>123-44-5555</td>
- <td>John</td>
- <td>Reynolds</td>
- <td>10/01/2004</td>
- <td>5' 11"</td>
- <td>185</td>
- </tr>
- </table>
- </p><p>
- If you take a look at the files <code>ThirdPass.html</code> and <code>ThirdPass.page</code>,
- you will see the changes made to improve the "look" of this page. Tapestry includes
- a bean called <code>EvenOdd</code> that produces the alternating strings
- "even" and "odd".
- By binding the <code>rowsClass</code> attribute of the <code>Table</code> to the
- <code>EvenOdd</code> Java Bean, we are able to specify alternating <code>class</code>
- attributes on each row of the table. Coupled with the CSS style sheet, this gives
- us the altenating row colors that our HTML designer specified (Note: the CSS styles
- must be "even" and "odd" for this to work).
- </p><p>
- Here is the relevent HTML snippet from <code>ThirdPass.html</code>
- that sets up this component:
- </p><p>
- <code class="snippet">
- <table class="mytable" jwcid="table@contrib:Table"
- <br>
- source="ognl:dataItems"
- <br>
- columns="SSN, FirstName, LastName, BirthDate, Height, Weight"
- <br>
- <code class="highlight">rowsClass="ognl:beans.evenOdd.next"</code>
- <br>
- <code class="highlight">pageSize="6"</code> >
- </code>
- </p><p>
- The <code>evenOdd</code> bean was added to this page's context in
- <code>ThirdPass.page</code> by adding the following line:
- </p><p>
- <code class="highlight">
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- </code>
- </p><p>
- To really understand what's going on you will have to delve deeper into the
- Tapestry documentation, but I think this illustrates that the effort is worthwhile.
- </p><p>
- You may have also noticed that the table is now displaying a maximum of 6 rows
- per page.
- This was accomplished by setting the <code>pageSize</code> attribute of the Table.
- </p><p>
- We're very close to being done.
- </p><p>
- <a href="#" jwcid="@PageLink" page="FourthPass">Custom Column Sorting...</a>
- </p><p>
- <a href="#" jwcid="@PageLink" page="Home">Return to Home page</a>.
- </p>
- </body>
- </html>
- <!--
- * Released in the Public Domain by John Reynolds: http://weblogs.java.net/blog/johnreynolds/
- * October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE page-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <page-specification class="tapestrytables.FirstPass">
- <context-asset name="stylesheet" path="css/style.css"/>
- <property-specification name="dataItems" type="java.util.List" persistent="yes"/>
- <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
- </page-specification>
- SSNSSN = SSN
- FirstFirstName = First Name
- LastLastName = Last Name
- BirthBirthDate = Birth Date
- HeightHeight = Height
- WeightWeight = Weight
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE web-app
- PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
- "http://java.sun.com/dtd/web-app_2_3.dtd">
- <!-- generated by Spindle, http://spindle.sourceforge.net -->
- <!--
- * Contributed by John Reynolds - October 2004
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication, visit
- * http://creativecommons.org/licenses/publicdomain/
- * or send a letter to Creative Commons, 559 Nathan Abbott Way,
- * Stanford, California 94305, USA.
- -->
- <web-app>
- <display-name>TapestryTables</display-name>
- <filter>
- <filter-name>redirect</filter-name>
- <filter-class>org.apache.tapestry.RedirectFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>redirect</filter-name>
- <url-pattern>/</url-pattern>
- </filter-mapping>
- <servlet>
- <servlet-name>TapestryTables</servlet-name>
- <servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>TapestryTables</servlet-name>
- <url-pattern>/app</url-pattern>
- </servlet-mapping>
- </web-app>
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)