net.sf.click.extras.control
Class FormTable

java.lang.Object
  extended bynet.sf.click.control.AbstractControl
      extended bynet.sf.click.control.Table
          extended bynet.sf.click.extras.control.FormTable
All Implemented Interfaces:
Control, Serializable

public class FormTable
extends Table

Provides a FormTable data grid control.

The FormTable is a composite control which includes a form object and an array of FieldColumn objects.

Please note it is possible to associate FormTable with an external Form through this constructor.

FieldColumn extends the Column class and includes a Field object which is uses to render its column value. Each table data cell ≶td> contains a uniquely named form field, which is rendered by the columns field.

When the tables form field data is posted the submitted values are processed by the column field objects using a flyweight style visitor pattern, i.e. the column field instance is reused and processes all the posted values for its column.

After FormTable changes have been submitted their values will be applied to the objects contained in the Tables rows list. If the posted values are invalid for the given field constraints, the field error will be highlighted in the table. Field error messages will be rendered as 'title' attribute tooltip values.

IMPORTANT NOTE

Do not populate the FormTable rowList in the Page's onRender() method.

When using the FormTable control its rowList property must be populated before the control is processed so that any submitted data values can be applied to the rowList objects. This generally means that the FormTable rowList should be populated in the page onInit() method. Note this is different from the Table control where the rowlist is generally populated in the page onRender() method.

FormTable Example

An code example usage of the FormTable is provided below. This example will render the FormTable illustrated in the image above.
 public class FormTablePage extends BorderPage {

     private static final int NUM_ROWS = 5;

     public FormTable table = new FormTable();

     public FormTablePage() {
         // Setup customers table
         table.addStyleClass("simple");
         table.setAttribute("width", "550px");
         table.getForm().setButtonAlign(Form.ALIGN_RIGHT);

         table.addColumn(new Column("id"));

         FieldColumn column = new FieldColumn("name", new TextField());
         column.getField().setRequired(true);
         table.addColumn(column);

         column = new FieldColumn("investments", new InvestmentSelect());
         column.getField().setRequired(true);
         table.addColumn(column);

         column = new FieldColumn("holdings", new NumberField());
         column.setAttribute("style", "{text-align:right;}");
         table.addColumn(column);

         column = new FieldColumn("active", new Checkbox());
         column.setAttribute("style", "{text-align:center;}");
         table.addColumn(column);

         table.getForm().add(new Submit("ok", "   OK   ", this, "onOkClick"));
         table.getForm().add(new Submit("cancel", this, "onCancelClick"));
     }

     public void onInit() {
         // Populate table before it is processed
         List customers = getCustomerService().getCustomersSortedByName(NUM_ROWS);
         table.setRowList(customers);
     }

     public boolean onOkClick() {
         if (table.getForm().isValid()) {
             getDataContext().commitChanges();
         }
         return true;
     }

     public boolean onCancelClick() {
         getDataContext().rollbackChanges();

         List customers = getCustomerService().getCustomersSortedByName(NUM_ROWS);

         table.setRowList(customers);
         table.setRenderSubmittedValues(false);

         return true;
     }
 } 
Note in this example the onCancelClick() button rolls back the changes made to the rowList objects, by reloading their values from the database and having the FormTable not render the submitted values.

Combining Form and FormTable

By default FormTable will create an internal Form to submit its values.

If you would like to integrate FormTable with an externally defined Form, use the constructor which accepts a Form.

Example usage:

 private Form form;
 private FormTable formTable;

 public void onInit() {

     // LIMITATION: Form only processes its children when the Form is submitted.
     // Since FormTable sorting and paging is done via GET requests,
     // the Form onProcess method won't process the FormTable.
     // To fix this we override the default Form#onProcess behavior and check
     // if Form was submitted. If it was not we explicitly process the FormTable.
     form = new Form("form") {
         public boolean onProcess() {
             if (isFormSubmission()) {
                 // Delegate to super implementation
                 return super.onProcess();
             } else {
                 // If form is not submitted, explicitly process the table
                 return formTable.onProcess();
             }
         }
     };

     formTable = new FormTable("formTable", form);
     formTable.setPageSize(10);
     form.add(formTable);
     ...
 } 

See Also:
FieldColumn, Form, Table, Serialized Form

Field Summary
protected  Form form
          The table form.
protected  boolean renderSubmittedValues
          The render the posted form values flag, default value is true.
protected  boolean useInternalForm
          Indicates whether an internal Form should be created, true by default.
 
Fields inherited from class net.sf.click.control.Table
ASCENDING, bannerPosition, CLASS_BLUE1, CLASS_BLUE2, CLASS_COMPLEX, CLASS_ISI, CLASS_ITS, CLASS_MARS, CLASS_NOCOL, CLASS_ORANGE1, CLASS_ORANGE2, CLASS_REPORT, CLASS_SIMPLE, CLASS_STYLES, COLUMN, columnList, columns, controlLink, controlList, height, hoverRows, nullifyRowListOnDestroy, PAGE, pageNumber, pageSize, paginator, PAGINATOR_ATTACHED, PAGINATOR_DETACHED, PAGINATOR_INLINE, paginatorAttachment, POSITION_BOTH, POSITION_BOTTOM, POSITION_TOP, renderId, rowList, showBanner, SORT, sortable, sorted, sortedAscending, sortedColumn, TABLE_IMPORTS_DARK, TABLE_IMPORTS_LIGHT, width
 
Fields inherited from class net.sf.click.control.AbstractControl
actionListener, attributes, listener, listenerMethod, messages, name, parent, styles
 
Fields inherited from interface net.sf.click.Control
CONTROL_MESSAGES
 
Constructor Summary
FormTable()
          Create a FormTable with no name defined.
FormTable(String name)
          Create a FormTable for the given name.
FormTable(String name, Form form)
          Create an FormTable for the given name and Form.
 
Method Summary
 Column addColumn(Column column)
          Add the column to the table.
 String getButtonsHtml()
          Return the form buttons HTML string representation.
 int getControlSizeEst()
           
 Form getForm()
          Return the form object associated with this FormTable.
 String getHtmlImports()
          Return the HTML head element import string.
 boolean getRenderSubmittedValues()
          Return true if the table will render the submitted form values.
 boolean onProcess()
          Process the FormTable control.
 void render(HtmlStringBuffer buffer)
          Render the HTML representation of the FormTable.
protected  void renderButtons(HtmlStringBuffer buffer)
          Render the Form Buttons to the string buffer.
 void setName(String name)
           
 void setPageNumber(int pageNumber)
           
 void setRenderSubmittedValues(boolean render)
          Set whether the table should render the submitted form values.
 void setSortedAscending(boolean ascending)
           
 void setSortedColumn(String columnName)
           
 
Methods inherited from class net.sf.click.control.Table
add, addControl, addRowAttributes, getBannerPosition, getColumn, getColumnList, getColumns, getControlLink, getControls, getFirstRow, getHeight, getHoverRows, getLastRow, getNullifyRowListOnDestroy, getNumberPages, getPageNumber, getPageSize, getPaginator, getPaginatorAttachment, getRenderId, getRowList, getShowBanner, getSortable, getSortedColumn, getTag, getWidth, hasControls, isSorted, isSortedAscending, onDeploy, onDestroy, onInit, onRender, removeColumn, removeColumn, removeColumns, renderBodyNoRows, renderBodyRowColumns, renderBodyRows, renderFooterRow, renderHeaderRow, renderPaginator, renderPagingControls, renderTableBanner, setBannerPosition, setClass, setHeight, setHoverRows, setListener, setNullifyRowListOnDestroy, setPageSize, setPaginator, setPaginatorAttachment, setParent, setRenderId, setRowList, setShowBanner, setSortable, setSorted, setWidth, sortRowList
 
Methods inherited from class net.sf.click.control.AbstractControl
addStyleClass, appendAttributes, getActionListener, getAttribute, getAttributes, getContext, getId, getMessage, getMessage, getMessage, getMessages, getName, getPage, getParent, getStyle, getStyles, hasAttribute, hasAttributes, hasStyles, registerActionEvent, removeStyleClass, renderTagBegin, renderTagEnd, setActionListener, setAttribute, setId, setStyle, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

form

protected Form form
The table form.


useInternalForm

protected boolean useInternalForm
Indicates whether an internal Form should be created, true by default.


renderSubmittedValues

protected boolean renderSubmittedValues
The render the posted form values flag, default value is true.

Constructor Detail

FormTable

public FormTable(String name,
                 Form form)
Create an FormTable for the given name and Form.

If you want to add the FormTable to an externally defined Form, this is the constructor to use.

Please note: if you want to use FormTable with an external Form, see this example which demonstrates a workaround of the form submit limitation.

Parameters:
name - the table name
form - the table form
Throws:
IllegalArgumentException - if the name is null

FormTable

public FormTable(String name)
Create a FormTable for the given name.

Note that an internal Form control will automatically be created by FormTable.

Parameters:
name - the table name
Throws:
IllegalArgumentException - if the name is null

FormTable

public FormTable()
Create a FormTable with no name defined.

Note that an internal Form control will automatically be created by FormTable.

Please note the control's name must be defined before it is valid.

Method Detail

getButtonsHtml

public String getButtonsHtml()
Return the form buttons HTML string representation.

Returns:
the form buttons HTML string representation

addColumn

public Column addColumn(Column column)
Add the column to the table. The column will be added to the Table.columns Map using its name.

Parameters:
column - the column to add to the table
Returns:
the added column
Throws:
IllegalArgumentException - if the table already contains a column with the same name
See Also:
Table.addColumn(Column)

getForm

public Form getForm()
Return the form object associated with this FormTable.

The returned Form control will either be an internally created Form instance, or an external instance specified through this contructor.

Returns:
the form object

getHtmlImports

public String getHtmlImports()
Return the HTML head element import string. This method will also include the imports of the form and the contained fields.

Returns:
the HTML head element import string
See Also:
Control.getHtmlImports()

setName

public void setName(String name)
Parameters:
name - of the control
Throws:
IllegalArgumentException - if the name is null
See Also:
Control.setName(String)

getRenderSubmittedValues

public boolean getRenderSubmittedValues()
Return true if the table will render the submitted form values. By default FormTable renders submitted values.

Returns:
true if the table will render the submitted form values

setRenderSubmittedValues

public void setRenderSubmittedValues(boolean render)
Set whether the table should render the submitted form values.

Parameters:
render - set whether the table should render the submitted form values

setSortedColumn

public void setSortedColumn(String columnName)
Parameters:
columnName - the the name of the sorted column
See Also:
Table.setSortedColumn(java.lang.String)

setSortedAscending

public void setSortedAscending(boolean ascending)
Parameters:
ascending - the ascending sort order status
See Also:
Table.setSortedAscending(boolean)

setPageNumber

public void setPageNumber(int pageNumber)
Parameters:
pageNumber - set the currently displayed page number
See Also:
Table.setPageNumber(int)

onProcess

public boolean onProcess()
Process the FormTable control. This method will process the submitted form data applying its values to the objects contained in the Tables rowList.

Returns:
true if further processing should continue or false otherwise
See Also:
Table.onProcess()

getControlSizeEst

public int getControlSizeEst()
Returns:
the estimated rendered control size in characters
See Also:
AbstractControl.getControlSizeEst()

render

public void render(HtmlStringBuffer buffer)
Render the HTML representation of the FormTable.

Parameters:
buffer - the specified buffer to render the control's output to
See Also:
AbstractControl.toString()

renderButtons

protected void renderButtons(HtmlStringBuffer buffer)
Render the Form Buttons to the string buffer.

This method is only invoked if the Form is created by the FormTable, and not when the Form is defined externally.

Parameters:
buffer - the StringBuffer to render to