Code sample #8:

This creates a new button to reset the form and demonstrates how to give the button its own validation handler. Also, it places validation of the first and last name fields into the default validation function.

<?php

function my_module_menu() {
  $items = array();
  $items['my_module/form'] = array(
    'title' => t('My form'),
    'page callback' => 'my_module_form',
    'access arguments' => array('access content'),
    'description' => t('My form'),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

function my_module_form() {
  return drupal_get_form('my_module_my_form');
}

function my_module_my_form($form_state) {
  $form['name'] = array(
    '#type' => 'fieldset',
    '#title' => t('Name'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );
  
  // Removes the #required property and 
  // uses the validation function instead.
  $form['name']['first'] = array(
    '#type' => 'textfield',
    '#title' => t('First name'),
    '#default_value' => "First name",
    '#description' => "Please enter your first name.",
    '#size' => 20,
    '#maxlength' => 20,
  );
  
  // Removes the #required property and 
  // uses the validation function instead.
  $form['name']['last'] = array(
    '#type' => 'textfield',
    '#title' => t('Last name'),
  );
  $form['year_of_birth'] = array(
    '#type' => 'textfield',
    '#title' => "Year of birth",
    '#description' => 'Format is "YYYY"',
  );  
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit',
  );
  // Adds a new button to clear the form. The #validate property
  // directs the form to use a new validation handler function in place
  // of the default.
  $form['clear'] = array(
    '#type' => 'submit',
    '#value' => 'Reset form',
    '#validate' => array('my_module_my_form_clear'),
  );
  
  return $form;
}

// This is the new validation handler for our Reset button. Setting
// the $form_state['rebuild'] value to TRUE, clears the form and also
// skips the submit handler.
function my_module_my_form_clear($form, &$form_state) {
	$form_state['rebuild'] = TRUE;
}

// Provides the first and last name fields to be required by using the 
// validation function to make sure values have been entered. This 
// causes the name fields to show up in red if left blank after clearing 
// the form with the "Reset form" button.
function my_module_my_form_validate($form, &$form_state) {
	$year_of_birth = $form_state['values']['year_of_birth'];
	$first_name = $form_state['values']['first'];
	$last_name = $form_state['values']['last'];
	if (!$first_name) {
		form_set_error('first', 'Please enter your first name.');
	}
	if (!$last_name) {
		form_set_error('last', 'Please enter your last name.');
	}
	if ($year_of_birth && ($year_of_birth < 1900 || $year_of_birth > 2000)) {
		form_set_error('year_of_birth', 'Enter a year between 1900 and 2000.');
	}
}

function my_module_my_form_submit($form, &$form_state) {
	drupal_set_message(t('The form has been submitted.'));
}
?>

Comments

biosv’s picture

It needs to be changed to make sure that the year field is not empty.

if ($year_of_birth && ($year_of_birth < 1900 || $year_of_birth > 2000)) {
tax15’s picture

The example code mentions about removing #required from the First Name and Last Name fields. We can't use #required with any field as Reset Form button submits the form and Drupal would not allow a form to be submitted if all validations do not pass.

BrandonDL’s picture

I had to change my code to :

if(!$year_of_birth || ($year_of_birth < 1900 || $year_of_birth > date('Y') || strlen($year_of_birth)<1))

otherwise it won't take into account that the 'year' field is left blank.

timebinder’s picture

I copied & pasted this verbatim, saved it

went to the form, pushed the button...nothing

Any ideas?

timebinder’s picture

Hi

Shouldn't the reset button clear the fields too (aside from the default value for firstname)

When I press it nothing is cleared

zaurav’s picture

the #default_value field in both first and last names or the reset will simply recreate the form (where default_values if set, will show).

ahdeshmukh’s picture

using (int)$year_of_birth == 0 will help solve the issue of empty year in most cases, even if the users type 'abcd' in the year text field. I have not tested it throughly though for other scenarios where this can be bypassed.

hjc1710’s picture

Another way to check for an empty year is to apply the same principles to checking for an empty name:

if(!$year_of_birth) 
    {
         form_set_error('year_of_birth', 'Please enter the year of your birth.');
    }

You can then drop the $year_of_birth from it's if statement, giving you this:

    if($year_of_birth < 1900 || $year_of_birth > 2011)

This has worked so far and I tested every case (empty, field set to 0, field not between 1900 and 2011, and field as letters). I capped the $year_of_birth at six characters and, since Drupal/PHP probably works like other languages and converts numbers to letters based on their position in the ASCII table, that makes it so any string of just letters would need to be roughly 20+ characters long. And a test of 'ZZZZZZ' throws an error, meaning the number isn't between 1900 and 2011.

The bonus to this is you can set a different error for the two conditions (null field and numbers out of range) giving users more error. Just another method to keep in mind.

ehsankhfr’s picture

Reset button doesn't work!