This is in progress.
The pivotal FAPI function is drupal_get_form(); it retrieves a form from a builder function, passes it on for processing, and renders the form or redirects to its destination as appropriate.
One can distinguish three stages in the life of a form:
The building stage starts when you call drupal_get_form('form_id'), with the function scurrying away to find the builder function of the appropriate form. To keep it simple for now; drupal_get_form checks if the function form_id() exists, then calls it, expecting a proper FAPI array in return. Alternatives to this approach will be discussed in future chapters.
In the code below, we fetch a form with the identifier myform, build by the function myform(), specifying a select box, a textfield and a button.
/**
* Builder function for the form with the form_id myform.
* Returns a form array.
*/
function myform() {
$form = array();
// A combo box with three options.
$form['gender'] = array(
'#type' => 'select',
'#title' => t('Gender'),
'#options' => array('male' => t('Male'), 'female' => t('Female'), 'unknown' => t('Not sure')),
);
// A textfield to provide the number of siblings. We have to ensure numeric input.
$form['siblings'] = array(
'#type' => 'textfield',
'#title' => t('How many siblings do you have?'),
);
// Submission button with the text 'Save'.
$form['save'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
This builder function supplies a number of fields defined by keys of the nested forms array. The '#key' => 'value' pairs are properties of the field. We'll deal with those later, but you can take a look at the FAPI reference to get a feel for the available properties.
When the user clicks a button on the form, data is send back to the server. Drupal reruns the form builder function and then starts the validation stage. A few properties are automatically validated. Required fields, maximum input length (textfields), whether selected options are valid options and the internal form token (to protect against cross site request forgeries).
There are multiple ways to do some validation yourself, but the easiest is to provide a [form_id]_validate function. This takes two arguments: the form id and an array of values. In the example we use a custom validation function to make sure that the number of siblings is numeric. By setting an error on the field 'siblings' we ensure that the form is redisplayed to the user with the error message "Please enter a number".
When the form validation is successful, the next stage starts: submission.