Views allows handlers to output form elements, wrapping them automatically in a form, and handling validation / submission. The form is multistep by default, allowing other modules to add additional steps, such as confirmation screens.
function render($values) {
return '<!--form-item-' . $this->options['id'] . '--' . $this->view->row_index . '-->';
}
function views_form(&$form, &$form_state) {
// The view is empty, abort.
if (empty($this->view->result)) {
return;
}
$field_name = $this->options['id'];
$form[$field_name] = array(
'#tree' => TRUE,
);
// At this point, the query has already been run, so we can access the results
foreach ($this->view->result as $row_id => $row) {
$form[$field_name][$row_id] = array(
'#type' => 'textfield',
'#title' => t('Your name'),
'#default_value' => '',
);
}
}
// Optional validate function.
function views_form_validate($form, &$form_state) {
$field_name = $this->options['id'];
foreach ($form_state['values'][$field_name] as $row_id => $value) {
if ($value == 'Drupal') {
form_set_error($field_name . '][' . $row_id, "You can't be named Drupal. That's my name.");
}
}
}
// Optional submit function.
function views_form_submit($form, &$form_state) {
// Do something here
}
Modules can implement hook_views_form_validate($form, &$form_state) and hook_views_form_submit($form, &$form_state).
The form is multistep by default, with one step: 'views_form_views_form'.
A "form_example" module could add a confirmation step by setting:
$form_state['storage']['step'] = 'form_example_confirmation';in form_example_views_form_submit(). Then, views_form would call form_example_confirmation($form, $form_state, $view, $output) to get that step. Important: You can fetch the Views object in form_alter and validate / submit hooks from $form['#parameters']:
$view = $form['#parameters'][2];