Forms

Forms are an integral part of almost every web application. Because of this, there is a tremendous amount of functionality available for creating, managing, and manipulating forms and form data. This chapter will walk you through each step involved with creating a form, validating it both on the server side and the client side, and storing/processing any submitted data. Each step can be as simple or complex as is needed, and Bedrock is easily extended to support custom form elements, validation rules, etc.

Form Creation

Creating a form is extremely easy and can be done using a few different approaches. The recommended method is to create a form definition file (as XML) and then load it when initializing the Form object. This way the form content and validation rules can be easily maintained with a single file.

Alternatively you can also create an empty Form object and programatically add any desired fields. This allows for the dynamic creation of forms where needed. Adding fields can be done by specifying an array or Bedrock::Common::Config object with the relevant data, or by adding fields individually (one at a time).

Creating a Form with XML

A form definition file consists of a number of tags that describe both its structure and any relevant validation rules. To better understand how a form definition file might look, consider this example:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2.  
  3. <form name="new_user" method="post" action="">
  4. <group name="account_info" label="Account Info">
  5. <field name="username" label="Username" type="std:text" value="" />
  6. <field name="password" label="Password" type="std:password" value="" />
  7. </group>
  8. <group name="personal_info" label="Personal Info">
  9. <field name="firstname" label="First Name" type="std:text" value="" />
  10. <field name="lastname" label="Last Name" type="std:text" value="" />
  11. </group>
  12. <group name="location" label="Location">
  13. <field name="city" label="City" type="std:text" value="" />
  14. <field name="state" label="State" type="std:state" value="" />
  15. <field name="zip" label="Zip Code" type="std:text" value="" />
  16. </group>

See the Form XML Reference for a complete description of all allowed tags and their attributes.

Once an XML file is created, loading up a form is a single line of code away. Make note of where you saved the XMl file, and initialize a new Form object, specifying the location of the XML file as a parameter. At this point you have an object containing all properties and settings for the form:

  1. // Load Form
  2. $form = new Bedrock_Common_Form('/path/to/form/definition.xml');
  3.  
  4. // Display Form

FIXME

Creating a Form Programmatically

Generating forms on-the-fly is equally as straightforward, though of course requires a few more lines of code. A form is initialized in the same was as when loading an XML file (omitting the parameter specifying the path to an XML file of course). Once initialized, a form can be built by

FIXME

Form Validation

Form validation is so simple that it only takes a single line of code. Because validation rules are tied to individual fields when they are defined, all validation information is already stored and prepared before validation is even performed.

Calling the Bedrock::Common::Form::validate() method on an instance will apply any stored rules on each field and return whether or not the form passed validation. If the form fails validation, the errors and corresponding messages can be accessed by calling Form::errors().

Consider this example:

  1. // Initialize the type of form we are expecting.
  2. $testForm = new Bedrock_Common_Form('testform.xml');
  3.  
  4. // Check for a submitted form of this type.
  5. if($testForm->submitted()) {
  6. // Validate the form.
  7. if($testForm->validate()) {
  8. // Validation passed, do something with the form data...
  9.  
  10. }
  11. else {
  12. // Validation failed, display the errors.
  13. echo 'Form validation failed:' . "n";
  14.  
  15. foreach($testForm->errors() as $error) {
  16. echo $error . "n";
  17. }
  18. }
  19. }
  20. else {
  21. echo 'No form of type "testform" has been submitted.';
  22. }

Also note that errors can be accessed within the context of a specific form field as well. Calling Bedrock::Common::Form::Field::errors() on a Field instance will return errors specific to that field. This can be extremely useful if you are looping through a form's fields to display them on a page, and wish to highlight or denote fields that did not pass validation.

Accessing Form Data

Forms are quite useless without the ability to access the data they receive. While you can still access submitted form data through the standard $_GET and $_POST superglobals, it is recommended that you instead access values directly from Field objects. By doing so you will know every value retrieved has passed all validation rules and also makes your code much more readable.

Whenever a form is first initialized, any defined default values will first be associated with each field. When validating a submitted form, each Field object's value is only changed if it passes validation and a value has been specified. Otherwise the default value remains set. This approach is particularly useful for forms that are updating existing data.

To access validated values from a submitted form, you either treat a Form object as an array, where keys represent the names of the fields and point to their corresponding values. You may also access them by using field names as member variable names on the Form object (this is simply an implementation of the magic __get() and __set() methods).

FIXME