ALEX REISNER / BASEBALL / DRUPAL / CONTACT

Formproc

Formproc provides an API for rendering and processing forms. It allows programmers to define both the appearance and behavior of a form in one place and provides modularity by maintaining field, validator, and filter autonomy within a form. (Skip to the bottom for examples.)

Please note that Formproc was designed for Drupal 4.6. The Forms API introduced in Drupal 4.7 makes Formproc unnecessary.

Problem

Drupal's built-in form handling provides for unified rendering of fields but requires appearance to be defined separately from behavior (in the functions hook_form() and hook_validate(), respectively). This makes code difficult to read and very difficult to maintain (a drawback which in the context of forms should be considered a security problem). Additionally, the parameter order is different for each of Drupal's field-rendering functions, making them quite tedious to use.

There is also no modularity in the out-of-the-box Drupal system so that once a field is added to a form it cannot be removed or modified. In a system where forms are assembled with components from a variety of modules this is far from satisfactory.

Solution

To address the problem of modularity, we define fields by associative arrays with certain properties (e.g., type, name, length, label). A form, then, is an array of such field-arrays. Managing fields in a form is now as simple as modifying values in an associative array, and you don't need to remember the order of parameters to a function.

We solve the readibility/maintenance problem by defining field behavior in the same arrays with properties like 'rules' and 'filters'. How does all of this come to life? Typically your Drupal module will provide a function that returns a form definition and you rewrite hook_form() and hook_validate() as 2-liners that simply get the form definition and call the appropriate formproc function (e.g., formproc_render_form()) to perform the required task.

Other Benefits

Formproc comes packaged with some useful validators (called "rules"), filters, and custom field types to get you started. Since formproc uses Drupal's form_x() functions for rendering your theme functions will continue to work as expected. Control over the display of error messages is also increased. See the documentation in the readme file for details.

Examples

Below are some fields and the complete PHP arrays required to create them. We start with the basics...


1. Simple Required Text Field

Will automatically post an error if left blank.


Your full name (required).
'type'     => 'text',
'name'     => 'name',
'help'     => 'Your full name.',
'required' => true,
2. Simple Radio Set

The submitted value of any multiple-choice field is automatically checked against the 'choices' property for validity.






'type'    => 'radios',
'name'    => 'fruit',
'label'   => 'Your favorite fruit',
'choices' => array('Apple', 'Banana',
             'Pear', 'Kumquat'),
3. Frozen Checkbox

Any type of field, along with its value, can be rendered in plain text by setting the 'editable' property to false.

'type'     => 'checkbox',
'name'     => 'registered_user',
'default'  => 1,
'editable' => false,
4. Select Field From Enum DB Column

Just name the table and column (here 'level' is an enum or set column in the 'sponsors' table).


'type'    => 'select',
'name'    => 'sponsor_level',
'choices' => formproc_choices_enum_field(
             'sponsors','level'),
5. Select Field From Custom DB Query

Any query returning one or two columns can be used to quickly get choices.


'type'    => 'select',
'name'    => 'country',
'choices' => formproc_choices_query(
             "SELECT id,name FROM {countries}
             ORDER BY name"),
'default' => 205, // Togo
6. Textarea With Character Counter

Four lines of code and you have a real-time character counter. (Try going over the limit.) You can just as easily choose to just count up from zero.


Real-time character counter.
20 characters remaining
'type'    => 'textarea',
'name'    => 'description',
'special' => array('formproc_charcount' => 20),
'label'   => 'Real-time character counter.',
7. Password Confirm Field

Will automatically report an error if passwords don't match.



'type'     => 'custom',
'name'     => 'password',
'callback' => 'formproc_password_confirm_field',
8. Date Field

Note the familiar format string, which mimicks PHP's built-in date() function, and the ability to set the default to 'now'.


'type'       => 'custom',
'name'       => 'date',
'callback'   => 'formproc_date_field',
'format'     => 'MjY',
'first_year' => 1978,
'default'    => 'now',
9. Time Field

Just seven lines of code for a pretty complex field.


:
:
'type'        => 'custom',
'name'        => 'time',
'callback'    => 'formproc_date_field',
'format'      => 'g:i:s a',
'minute_step' => 5,
'second_step' => 10,
'default'     => array('g' => 11, 'i' => 25),

More features and complex field types are in the works so stay tuned.


Everything on this web site copyright © 2004-2008 Alex Reisner, unless specifically noted.