|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectnet.sf.click.control.AbstractControl
net.sf.click.control.AbstractContainer
net.sf.click.control.BasicForm
net.sf.click.control.Form
Provides a Form control: <form method='post'>.
|
Field controls
in the order they were added to the form, and then it will process the
Button controls in the added order. Once all the Fields have been
processed the form will invoke its action listener if defined.
public class Login extends Page { public Form form = new Form(); public Login() { form.add(new TextField("username", true)); form.add(new PasswordField("password", true)); form.add(new Submit("ok", " OK ", this, "onOkClick")); form.add(new Submit("cancel", this, "onCancelClick")); } public boolean onOkClick() { if (form.isValid()) { User user = new User(); form.copyTo(user); if (getUserService().isAuthenticatedUser(user)) { getContext().setSessionAttribute("user", user); setRedirect(HomePage.class); } else { form.setError(getMessage("authentication-error")); } } return true; } public boolean onCancelClick() { setRedirect(WelcomePage.class); return false; } }The forms corresponding template code is below. Note the form automatically renders itself when Velocity invokes its
AbstractContainer.toString() method.
$form
If a Form has been posted and processed, if it has an BasicForm.error defined or
any of its Fields have validation errors they will be automatically
rendered, and the BasicForm.isValid() method will return false.
copyFrom(Object)copyTo(Object)// The customer.address.state field TextField stateField = new TextField("address.state"); form.add(stateField); .. // Loads the customer address state into the form stateField Customer customer = getCustomer(); form.copyFrom(customer); .. // Copies form stateField value into the customer address state Customer customer = new Customer(); form.copyTo(customer);When populating an object from a form post Click will automatically create any null nested objects so their properties can be set. To do this Click uses the no-args constructor of the nested objects class.
copyTo(Object) and copyFrom(Object) also supports
java.util.Map as an argument. Examples of using
java.util.Map are shown in the respective method descriptions.
BasicForm.setValidate(boolean) to false.
JavaScript Validation
The Form control also supports client side JavaScript validation. By default
JavaScript validation is not enabled. To enable JavaScript validation set
setJavaScriptValidation(boolean) to true. For example:
Form form = new Form("form"); form.setJavaScriptValidation(true); // Add form fields .. form.add(new Submit("ok", " OK ", this, "onOkClicked"); Submit cancel = new Submit("cancel", "Cancel", this, "onCancelClicked"); cancel.setCancelJavaScriptValidation(true); addControl(form);Please note in that is this example the cancel submit button has
Submit.setCancelJavaScriptValidation(boolean) set to true. This
prevents JavaScript form validation being performed the cancel button is clicked.
<html> <head> $cssImports </head> <body> $form </body> </html> $jsImports
buttonAlign | button alignment: ["left", "center", "right"] |
buttonStyle | button <td> "style" attribute value |
columns | number of form table columns, the default value number is 1 |
errorsAlign | validation error messages alignment: ["left", "center", "right"] |
errorsPosition | validation error messages position: ["top", "middle", "bottom"] |
errorsStyle | errors <td> "style" attribute value |
fieldStyle | field <td> "style" attribute value |
labelAlign | field label alignment: ["left", "center", "right"] |
labelsPosition | label position relative to field: ["left", "top"] |
labelStyle | label <td> "style" attribute value |
| click/control.css | control CSS styles, automatically deployed to the click web directory |
| /click-control.properties | form and field messages and HTML, located under classpath |
$form.fields.usernameField
Whenever including your own Form markup in a page template or Velocity macro
always specify:
AbstractControl.name of the Form startTag() and endTag()
methods to render this information.
An example of a manually layed out Login form is provided below:
$form.startTag() <table style="margin: 1em;"> #if ($form.error) <tr> <td colspan="2" style="color: red;"> $form.error </td> </tr> #end #if ($form.fields.usernameField.error) <tr> <td colspan="2" style="color: red;"> $form.fields.usernameField.error </td> </tr> #end #if ($form.fields.passwordField.error) <tr> <td colspan="2" style="color: red;"> $form.fields.passwordField.error </td> </tr> #end <tr> <td> Username: </td> <td> $form.fields.usernameField </td> </tr> <tr> <td> Password: </td> <td> $form.fields.passwordField </td> </tr> <tr> <td> $form.fields.okSubmit $form.fields.cancelSubmit </td> </tr> </table> $form.endTag()As you can see in this example most of the code and markup is generic and could be reused. This is where Velocity Macros come in.
getFieldList() and
getButtonList() properties within a Velocity macro.
The example below provides a generic writeForm()
macro which you could use through out an application. This Velocity macro code
would be contained in a macro file, e.g. macro.vm.
#* Custom Form Macro Code *# #macro( writeForm[$form] ) $form.startTag() <table width="100%"> #if ($form.error) <tr> <td colspan="2" style="color: red;"> $form.error </td> </tr> #end #foreach ($field in $form.fieldList) #if (!$field.hidden) #if (!$field.valid) <tr> <td colspan="2"> $field.error </td> </tr> #end <tr> <td> $field.label: </td><td> $field </td> </tr> #end #end <tr> <td colspan="2"> #foreach ($button in $form.buttonList) $button #end </td> </tr> </table> $form.endTag() #endYou would then call this macro in your Page template passing it your form object:
#writeForm($form)At render time Velocity will execute the macro using the given form and render the results to the response output stream.
BasicForm.onSubmitCheck(net.sf.click.Page, String) methods. For example:
public class Purchase extends Page { .. public boolean onSecurityCheck() { return form.onSubmitCheck(this, "/invalid-submit.html"); } }The form submit check methods store a special token in the users session and in a hidden field in the form to ensure a form post isn't replayed.
See also the W3C HTML reference: FORM
Field,
Submit,
Serialized Form| Field Summary | |
static String |
ALIGN_CENTER
The align center, form layout constant: "center". |
static String |
ALIGN_LEFT
The align left, form layout constant: "left". |
static String |
ALIGN_RIGHT
The align right, form layout constant: "right". |
protected String |
buttonAlign
The button align, default value is "left". |
protected List |
buttonList
The ordered list of button values. |
protected String |
buttonStyle
The button <td> "style" attribute value. |
protected int |
columns
The number of form layout table columns, default value: 1. |
protected int |
defaultFieldSize
The default field size, default value: 0. |
protected String |
errorsAlign
The errors block align, default value is "left". |
protected String |
errorsPosition
The form errors position ["top", "middle", "bottom"] default value: "top". |
protected String |
errorsStyle
The error <td> "style" attribute value. |
protected String |
fieldStyle
The field <td> "style" attribute value. |
protected Map |
fieldWidths
The map of field width values. |
protected static String |
FOCUS_JAVASCRIPT
The Form set field focus JavaScript. |
protected boolean |
javaScriptValidation
The JavaScript client side form fields validation flag. |
protected String |
labelAlign
The label align, default value is "left". |
protected String |
labelNotRequiredPrefix
The field not required label labelprefix. |
protected String |
labelNotRequiredSuffix
The field not required label suffix. |
protected String |
labelRequiredPrefix
The field required label labelprefix. |
protected String |
labelRequiredSuffix
The field required label suffix. |
protected String |
labelsPosition
The form labels position ["left", "top"] default value: "left". |
protected String |
labelStyle
The label <td> "style" attribute value. |
static String |
POSITION_BOTTOM
The position bottom, errors on bottom form layout constant: "top". |
static String |
POSITION_LEFT
The position left, labels of left form layout constant: "left". |
static String |
POSITION_MIDDLE
The position middle, errors in middle form layout constant: "middle". |
static String |
POSITION_TOP
The position top, errors and labels form layout constant: "top". |
| Fields inherited from class net.sf.click.control.BasicForm |
actionURL, disabled, enctype, error, FORM_NAME, HTML_IMPORTS, method, MULTIPART_FORM_DATA, readonly, SUBMIT_CHECK, validate |
| Fields inherited from class net.sf.click.control.AbstractContainer |
controlMap, controls |
| 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 | |
Form()
Create a form with no name. |
|
Form(String name)
Create a form with the given name. |
|
| Method Summary | |
Control |
add(Control control)
Add a Field or FieldSet to the container and return the added instance. |
Field |
add(Field field)
Add the field to the form, and set the fields form property. |
Field |
add(Field field,
int width)
Add the field to the form and specify the field's width in columns. |
FieldSet |
add(FieldSet fieldSet,
int width)
Add the fieldSet to the form and specify the fieldSet's width in columns. |
void |
copyFrom(Object object)
Copy the given object's attributes into the BasicForm's field values. |
void |
copyFrom(Object object,
boolean debug)
Copy the given object's attributes into the Form's field values. |
void |
copyTo(Object object)
Copy the BasicForm's field values into the given object's attributes. |
void |
copyTo(Object object,
boolean debug)
Copy the Form's field values into the given object's attributes. |
String |
endTag()
Return the rendered form end tag and JavaScript for field focus and validation. |
String |
getButtonAlign()
Return the buttons <td> HTML horizontal alignment: "left", "center", "right". |
List |
getButtonList()
Return the ordered list of Buttons. |
String |
getButtonStyle()
Return the button <td> "style" attribute value. |
int |
getColumns()
Return the number of form layout table columns. |
int |
getDefaultFieldSize()
Return the form default field size. |
String |
getErrorsAlign()
Return the errors block HTML horizontal alignment: "left", "center", "right". |
String |
getErrorsPosition()
Return the form errors position ["top", "middle", "bottom"]. |
String |
getErrorsStyle()
Return the error <td> "style" attribute value. |
Field |
getField(String name)
Return the named field if contained in the form or one of the form's fieldsets, or null if not found. |
List |
getFieldList()
Return the ordered list of form Fields as well as any
FieldSet containers. |
Map |
getFields()
Return a Map of form fields and fieldsets, keyed on field name. |
String |
getFieldStyle()
Return the field <td> "style" attribute value. |
Map |
getFieldWidths()
Return the map of field width values, keyed on field name. |
protected int |
getFormSizeEst(List formFields)
Return the estimated rendered form size in characters. |
boolean |
getJavaScriptValidation()
Return true if JavaScript client side form validation is enabled. |
String |
getLabelAlign()
Return the field label HTML horizontal alignment: "left", "center", "right". |
String |
getLabelsPosition()
Return the form labels position ["left", "top"]. |
String |
getLabelStyle()
Return the label <td> "style" attribute value. |
Control |
insert(Control control,
int index)
Add the control to the container at the specified index, and return the added instance. |
void |
onDeploy(ServletContext servletContext)
This method does nothing. |
void |
onDestroy()
Destroy the fields and buttons contained in the Form and clear any form error message. |
void |
onInit()
Initialize the fields, fieldSet and buttons contained in the Form. |
boolean |
onProcess()
Process the Form when the request method is the same as the Form's method. |
void |
onRender()
Perform any pre rendering logic. |
boolean |
remove(Control control)
Remove the given control from the container, returning true if the control was found in the container and removed, or false if the control was not found. |
boolean |
removeField(String name)
Remove the named field from the form, returning true if removed or false if not found. |
void |
removeFields(List fieldNames)
Remove the list of named fields from the form. |
void |
render(HtmlStringBuffer buffer)
Render the HTML representation of the Form. |
protected void |
renderButtons(HtmlStringBuffer buffer)
Render the given list of Buttons to the string buffer. |
protected void |
renderControls(HtmlStringBuffer buffer,
AbstractContainer container,
List controls,
Map fieldWidths,
int columns)
Render the specified controls of the container to the string buffer. |
protected void |
renderErrors(HtmlStringBuffer buffer,
boolean processed)
Render the form errors to the given buffer is form processed. |
protected void |
renderFields(HtmlStringBuffer buffer)
Render the non hidden Form Fields to the string buffer. |
void |
renderFieldSet(HtmlStringBuffer buffer,
FieldSet fieldSet)
Convenience method that allows the form to render the specified fieldSet, and layout its fields. |
protected void |
renderFieldSetButtons(HtmlStringBuffer buffer,
List buttons)
Render the given list of Buttons to the string buffer. |
protected void |
renderFieldSetFields(HtmlStringBuffer buffer,
FieldSet fieldSet)
Render the fieldsets form fields to the string buffer. |
protected void |
renderFocusJavaScript(HtmlStringBuffer buffer,
List formFields)
Render the Form field focus JavaScript to the string buffer. |
protected void |
renderHeader(HtmlStringBuffer buffer,
List formFields)
Render the given form start tag and the form hidden fields to the given buffer. |
protected void |
renderTagEnd(List formFields,
HtmlStringBuffer buffer)
Close the form tag and render any additional content after the Form. |
protected void |
renderValidationJavaScript(HtmlStringBuffer buffer,
List formFields)
Render the Form validation JavaScript to the string buffer. |
void |
setButtonAlign(String align)
Set the button <td> HTML horizontal alignment: "left", "center", "right". |
void |
setButtonStyle(String value)
Set the button <td> "style" attribute value. |
void |
setColumns(int columns)
Set the number of form layout table columns. |
void |
setDefaultFieldSize(int size)
Return the form default field size. |
void |
setErrorsAlign(String align)
Set the errors block HTML horizontal alignment: "left", "center", "right". |
void |
setErrorsPosition(String position)
Set the form errors position ["top", "middle", "bottom"]. |
void |
setErrorsStyle(String value)
Set the errors <td> "style" attribute value. |
void |
setFieldStyle(String value)
Set the field <td> "style" attribute value. |
void |
setJavaScriptValidation(boolean validate)
Set the JavaScript client side form validation flag. |
void |
setLabelAlign(String align)
Set the field label HTML horizontal alignment: "left", "center", "right". |
void |
setLabelsPosition(String position)
Set the form labels position ["left", "top"]. |
void |
setLabelStyle(String value)
Set the label <td> "style" attribute value. |
void |
setListener(Object listener,
String method)
The callback listener will only be called during processing if the field value is valid. |
String |
startTag()
Return the rendered opening form tag and all the forms hidden fields. |
| Methods inherited from class net.sf.click.control.BasicForm |
clearErrors, clearValues, getActionURL, getControlSizeEst, getEnctype, getError, getErrorFields, getFieldValue, getHtmlImports, getMethod, getTag, getValidate, hasPostError, isDisabled, isFormSubmission, isReadonly, isValid, onSubmitCheck, onSubmitCheck, onSubmitCheck, performSubmitCheck, renderChildren, renderContent, renderTagBegin, setActionURL, setDisabled, setEnctype, setError, setMethod, setName, setReadonly, setValidate, validate |
| Methods inherited from class net.sf.click.control.AbstractContainer |
contains, getControl, getControlMap, getControls, hasControls, renderTagEnd, toString |
| 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, setActionListener, setAttribute, setId, setParent, setStyle |
| Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
| Methods inherited from interface net.sf.click.Control |
getContext, getId, getMessages, getName, getParent, setParent |
| Field Detail |
public static final String ALIGN_LEFT
public static final String ALIGN_CENTER
public static final String ALIGN_RIGHT
public static final String POSITION_TOP
public static final String POSITION_MIDDLE
public static final String POSITION_BOTTOM
public static final String POSITION_LEFT
protected static final String FOCUS_JAVASCRIPT
protected String buttonAlign
protected final List buttonList
protected String buttonStyle
protected int columns
protected int defaultFieldSize
protected String errorsAlign
protected String errorsPosition
protected String errorsStyle
protected String fieldStyle
protected Map fieldWidths
protected boolean javaScriptValidation
protected String labelAlign
protected String labelsPosition
protected String labelRequiredPrefix
protected String labelRequiredSuffix
protected String labelNotRequiredPrefix
protected String labelNotRequiredSuffix
protected String labelStyle
| Constructor Detail |
public Form(String name)
name - the name of the form
IllegalArgumentException - if the form name is nullpublic Form()
| Method Detail |
public Control add(Control control)
Field and FieldSet instances can
be added to a Form. Trying to add any other control will throw an
exception. This restriction allows Form to automatically layout its
controls. If you want to add other controls such as tables,
rather use BasicForm.
The Fields inside a FieldSet will be laid out by the Form.
Fields will be added to fields using their name.
Buttons will be added to buttonList while
all others field types will be added to fieldList.
add in interface Containeradd in class AbstractContainercontrol - the control to add to the container and return
IllegalArgumentException - if the control is null, the Field's name
is not defined, the container already contains a control with the same
name, if the control's parent is a Page or if the control is neither a
Field nor FieldSetContainer.add(net.sf.click.Control)
public Control insert(Control control,
int index)
Container
insert in interface Containerinsert in class AbstractContainercontrol - the control to add to the containerindex - the index at which the control is to be inserted
IllegalArgumentException - if the control is null, the container
already contains a control with the same name, or if the control's parent
is a Page
IndexOutOfBoundsException - if index is out of range
(index < 0 || index > getControls().size())Container.insert(net.sf.click.Control, int)public Field add(Field field)
fields using its name.
Button instances will be add to buttonList while
all others field types will be added to the
fieldList.
field - the field to add to the form
IllegalArgumentException - if the field is null, the field name
is not defined, the form already contains a control with the same name
or if the field's parent is a Pageadd(net.sf.click.Control)
public Field add(Field field,
int width)
fields using its name.
Note Button or HiddenFields types are not valid arguments for this method.
field - the field to add to the formwidth - the width of the field in table columns
IllegalArgumentException - if the field is null, field's name is
not defined, field is a Button or HiddenField, the form already contains
a control with the same name, if the field's parent is a Page or the
width < 1
public FieldSet add(FieldSet fieldSet,
int width)
fieldSet - the fieldSet to add to the formwidth - the width of the fieldSet in table columns
IllegalArgumentException - if the fieldSet is null, the form
already contains a control with the same name, if the fieldSet's parent
is a Page or the width < 1public boolean remove(Control control)
Container
remove in interface Containerremove in class AbstractContainercontrol - the control to remove from the container
IllegalArgumentException - if the control is nullContainer.remove(net.sf.click.Control)public boolean removeField(String name)
name - the name of the field to remove from the form
public void removeFields(List fieldNames)
fieldNames - the list of field names to remove from the form
IllegalArgumentException - if any of the fields is nullpublic String getButtonAlign()
public void setButtonAlign(String align)
align - the field label HTML horizontal alignmentpublic List getButtonList()
Buttons.
The order of the buttons is the same order they were added to the form.
Buttons.public String getButtonStyle()
public void setButtonStyle(String value)
value - the button <td> "style" attribute valuepublic int getColumns()
public void setColumns(int columns)
columns - the number of form layout table columnspublic int getDefaultFieldSize()
public void setDefaultFieldSize(int size)
size - the default field sizepublic String getErrorsAlign()
public void setErrorsAlign(String align)
align - the errors block HTML horizontal alignmentpublic String getErrorsPosition()
public void setErrorsPosition(String position)
position - the form errors positionpublic String getErrorsStyle()
public void setErrorsStyle(String value)
value - the errors <td> "style" attribute valuepublic Field getField(String name)
getField in class BasicFormname - the name of the field
IllegalStateException - if a non-field control is found with the
specified namepublic List getFieldList()
Fields as well as any
FieldSet containers.
The order of the fields is the same order they were added to the form.
getFieldList in class BasicFormpublic Map getFields()
getFields in class BasicFormpublic String getFieldStyle()
public void setFieldStyle(String value)
value - the field <td> "style" attribute valuepublic Map getFieldWidths()
public boolean getJavaScriptValidation()
public void setJavaScriptValidation(boolean validate)
validate - the JavaScript client side validation flagpublic String getLabelAlign()
public void setLabelAlign(String align)
align - the field label HTML horizontal alignmentpublic String getLabelsPosition()
public void setLabelsPosition(String position)
position - the form labels positionpublic String getLabelStyle()
public void setLabelStyle(String value)
value - the label <td> "style" attribute value
public void setListener(Object listener,
String method)
setListener in interface ControlsetListener in class AbstractControllistener - the listener object with the named method to invokemethod - the name of the method to invokeControl.setListener(Object, String)public void copyFrom(Object object)
BasicForm
public void onGet() {
Long customerId = ..
Customer customer = CustomerDAO.findByPK(customerId);
form.copyFrom(customer);
}
copyForm also supports java.util.Map as an argument.
By specifying a map, the BasicForm's field values will be populated by
matching key/value pairs. A match occurs when the map's key is equal to
a field's name.
The following example populates the BasicForm fields with a map's
key/value pairs:
public void onInit() { form = new BasicForm("form"); form.add(new TextField("name")); form.add(new TextField("address.street")); } public void onGet() { Map map = new HashMap(); map.put("name", "Steve"); map.put("address.street", "12 Long street"); form.copyFrom(map); }
copyFrom in class BasicFormobject - the object to obtain attribute values from
IllegalArgumentException - if the object parameter is nullBasicForm.copyFrom(java.lang.Object)
public void copyFrom(Object object,
boolean debug)
object - the object to obtain attribute values fromdebug - log debug statements when populating the form
IllegalArgumentException - if the object parame