Skip to end of metadata
Go to start of metadata

Requirements

  • Must be de-coupled from Zend_Controller and Zend_View
    • Form setup and validation must be possible without Zend_Controller_*
    • Should accept data to validate, and not retrieve from environment
    • View rendering should be optional
  • Must provide separation between validation, filtering, and rendering
    • Must be flexible enough to allow non-XHTML rendering schemas
  • Must re-use components as much as possible
    • Zend_Filter_Input
    • Zend_Validate
    • Zend_View_Helper_*
  • Must be able to do both automated and manual rendering of form items
    • Automated rendering
      • Must be capable of displaying labels and form elements
      • Must re-use existing form helpers
      • Must be capable of localization
      • Must be AJAX-friendly
        • Able to define JS event handlers
        • Able to easily display individual error messages
  • Must be able to order form elements
    • Default should be order in which elements are added to form object
  • Must be able to load form and individual elements from config objects
  • Could be capable of handling multi-page forms
    Need to discuss. My first job, every form was a multi-page form, but since then it has been a relatively infrequent task. If we go this route, I like Mitchell Hashimoto's 'form flow' concept – grouping fields into a 'flow item', and then setting the order of flow items: http://framework.zend.com/wiki/display/ZFPROP/Zend_Form+-+Mitchell+Hashimoto. This would require a dependency on Zend_Session, which I'm not particularly excited about (hard to test). Mitchell's 'branches' concept, while interesting and potentially useful, may not fall into the 80/20 rule. It may be good to have a 'Zend_Form_Wizard' or 'Zend_Form_MultiPage' component that would be built on top of Zend_Form at a later date.

Existing Proposals

Automatic rendering

  • Render form elements with labels
  • When errors detected, render with error messages
    • AJAX-friendly: use hidden div for error messages
  • Use existing or new form helpers for rendering

Manual rendering

  • pass in form object
  • retrieve form elements
    • utilize element to create form item

Validation

  • attach validation rules to form elements
  • should be independent of action controller
    • action helper
  • pass in data to validate
  • accessors to retrieve:
    • validation status
    • filtered values
    • error messages
    • original values

Classes

Zend_Form_Element

  • __construct($name, $spec = null)
    • $spec would be a Zend_Config object or array; proxies to setConfig()
  • (set|get)Name()
  • (set|get)Value()
  • getRawValue()
  • (set|get)Label()
  • (set|get)Order()
  • (set|get)ViewHelper()
  • (set|get)LabelViewHelper()
  • (set|get)ErrorViewHelper()
  • (set|get)Locale()
    • for localization
  • addValidator($name, $validator)
    • validators would have error messages attached
  • getValidator($name)
  • getValidators()
  • addFilter($name, $filter)
  • getFilter($name)
  • getFilters()
  • validate($value = null)
  • isValid($value = null)
  • render()
  • __toString()
    • proxies to render()
  • getType()
    • returns class name?
  • setConfig(Zend_Config $config)
    • allow creating item and then loading from config

Zend_Form_Element concrete extensions

  • Xhtml (abstract class)
    • (set|get)Name($name)
    • (set|get)Type($type)
      • input type; likely disabled in individual item implementations
    • (set|get)Accept($mime)
    • (set|get)Align($align)
    • (set|get)Alt($alt)
    • (set|get)Checked($bool)
      • likely only in individual item implementations
    • (set|get)Disabled($bool)
    • (set|get)MaxLength($len)
      • likely only in individual item implementations
    • (set|get)ReadOnly($bool)
    • (set|get)Size($len)
      • likely only in individual item implementations
    • (set|get)Src($src)
      • likely only in individual item implementations
    • (set|get)Id($id)
    • (set|get)Title($title)
    • (set|get)Class($class)
    • (set|get)Style($style)
    • (set|get)OptGroupLabel($label)
      • likely only for options in select groups
    • (set|get)Selected($bool)
      • likely only for options in select groups
    • (set|get)Cols($len)
      • only for textarea
    • (set|get)Rows($len)
      • only for textarea
    • JS events needing accessors:
      • tabIndex
      • accessKey
      • onFocus
      • onBlur
      • onSelect
      • onChange
      • onClick
      • onDblClick
      • onMouseDown
      • onMouseUp
      • onMouseOver
      • onMouseMove
      • onMouseOut
      • onKeyPress
      • onKeyDown
      • onKeyUp
  • Button (extends Xhtml)
  • Checkbox (extends Xhtml)
  • File (extends Xhtml)
    • May wait on this for a future date
  • Hidden (extends Xhtml)
  • Image (extends Xhtml)
  • Multiselect (extends Xhtml)
  • Password (extends Xhtml)
  • Radio (extends Xhtml)
  • Reset (extends Xhtml)
  • Select (extends Xhtml)
  • Submit (extends Xhtml)
  • Text (extends Xhtml)
  • Textarea (extends Xhtml)

Zend_Form_Abstract

Abstract class from which all other form classes inherit. Will provide Xhtml concrete class implementation that has the Xhtml methods as listed below.

Extends ArrayObject in order to allow easy traversal of form elements (foreach style):

  • addField($name, $type)
    • $type could be a Zend_Form_Element or the name of an element class
  • getField($name)
  • getFields()
  • removeField($name)
  • populate(array $values)
  • addSection($label, array $fields, $page = null)
    • for formatting into sections
  • addPage($label, array $fields)
  • (set|get)View(Zend_View_Interface $view)
    • For rendering, we need a view instance
  • validate($field = null)
    • allow validating a single field at a time; useful for ajax
  • render()
  • isValid()
  • getValues()
  • getRawValues()
  • getErrors()
  • setDefaults($defaults)
    • default values
  • render()
    • render each element in form
  • renderOpenTag()
    • renders opening <form> tag; useful when doing custom rendering of form elements
  • renderCloseTag()
    • renders closing </form> tag; useful when doing custom rendering of form elements
  • __toString()
    • proxies to render()

Zend_Form_Xhtml (extends Zend_Form_Abstract)

  • (set|get)Action($action)
    • form action (URL to which to submit)
    • should likely allow different accessors for building URLs
      • see url view helper
      • see url action helper
  • (set|get)Method($method)
    • form method (get, post)
  • (set|get)Enctype($value)
  • (set|get)Charset($charset)
  • (set|get)Name($name)
  • (set|get)Target($target)
  • (set|get)Id($id)
  • (set|get)Title($title)
  • (set|get)Class($class)
  • (set|get)Style($style)
  • JS events needing accessors:
    • onSubmit
    • onReset
    • onClick
    • onDblClick
    • onMouseDown
    • onMouseUp
    • onMouseOver
    • onMouseMove
    • onMouseOut
    • onKeyPress
    • onKeyDown
    • onKeyUp

Zend_Controller_Action_Helper_Form

Action helper for retrieving a form class

Zend_View_Helper_FormRenderer

Renders a form. Basically, passes view object to form object, and asks the form object to render itself

How other frameworks do forms

Rails

Code generation.

Then creates all controllers and views you need. The views are basically view scripts with view helpers.

Symfony

Code generation.

Basically the same as Rails.

CakePHP

None. Basically, they have the developer do it themselves, only providing validators, filters, and view helpers.

Solar

Solar_Form:

  • Build elements from arrays
  • populate -> validate -> decision
  • View rendering
    • each element is associated with a view helper
    • form() view helper renders the form object using the individual helpers

ASP.NET

??? The instructions I've been able to find all use a visual IDE, and none show any code showing how to create a form, validate it, and/or
render it.

Django

  • Create form class/function
  • Creates and utilizes FormWrapper object
    • takes a model as an argument
      • model has field types
      • model pulls data from request to validate and populate model
    • returns rendered form
      • view script with no helpers – all manual

CGI::Application::Plugin::ValidateRM

  • Provide a form profile
  • Indicate what page to display for form, error, and success
  • Validates data using Data::FormValidator
    • Use hash to define form elements
      • filters
      • validations
      • messages
  • Optional renders data using HTML::FillInForm
    • Uses hash of elements
      • type
      • value
      • name
      • attributes
Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Sep 26, 2007

    Sounds good. Am I right in thinking the proposal is to add the form-field-specific getters/setters to the relevant subclasses of Xhtml? If so, it might be clearer to put them under these classes in the proposal. Also, I'd love to hear more about AJAX!