Understanding Forms in Drupal

Share this article

Web applications today are being used in all kinds of industries. They need to take in and process a lot of user data. The capturing of the data happens through HTML forms which let you create different types of input fields like textboxes, radio buttons etc. using HTML tags. These forms get difficult to maintain or update if they are written directly in the HTML code. Drupal provides a very good way of defining forms directly in your PHP code, while the form generation is done by Drupal itself. This makes it easy for you to create and maintain forms. In this article we are going to see how we can create forms in Drupal. The final code can be cloned from Github.

The drupal_get_form function – Form generation in Drupal

The whole magic of form creation in Drupal is performed by the function drupal_get_form. This function returns a renderable form array to the Drupal system. It takes an argument as the form_id: a unique identifier to identify the form, and if a function with the same name exits then that function is called to build it. You can read more about drupal_get_form at the link https://api.drupal.org/api/drupal/includes!form.inc/function/drupal_get_form/7

Creating a basic form in Drupal

Let’s start by creating a small module which will create a menu callback and then on that menu callback create a form using the drupal_get_form function. To create a module add a folder to your Drupal installation sites\all\modules\drupalform and add two files to it: drupalform.info and drupalform.module with the following code:

drupalform.info

name = drupalform
description = This module creates a form using Drupal.
core = 7.x

drupalform.module

<?php
/**
 * @file
 * This is the main module file.
 */

 /**
 * Implements hook_help().
 */
function drupalform_help($path, $arg) {

  if ($path == 'admin/help#rupalform') {
    $output = '<h3>' . t('About') . '</h3>';
    $output .= '<p>' . t('The drupalform module shows how to create forms using Drupal.') . '</p>';
    return $output;
  }
}

With the above code you should be able to see your module in the available module list and should be able to enable it as shown below. If these steps seem mysterious or complicated, please see my last tutorial for a good Drupal Module introduction.

Once we have done this we will add a menu callback using hook_menu and create a form on the page. The code for that is as follows

/**
* Implementation of hook_menu().
*/
function drupalform_menu() {
  $items['drupalform/form1'] = array(
        'type' => MENU_CALLBACK,
        'access arguments' => array('access content'),
        'page callback' => 'drupal_get_form',
        'page arguments'=>array('drupalform_form1'));

  return $items;
}

function drupalform_form1() {
    $form = array();


    $form['name']=array(
        '#type'=>'textfield',
        '#title'=>t('Enter your name'),
        '#description'=>t('Your first name goes here')
      );
    $form['last_name']=array(
        '#type'=>'textfield',
        '#title'=>t('Enter your Last name'),
        '#description'=>t('Your Last name goes here')
      );

     $form['email']=array(
        '#type'=>'textfield',
        '#title'=>t('Enter your email'),
        '#description'=>t('Your email goes here')
      );

    $form['country']=array(
        '#type'=>'select',
        '#title'=>t('Select your country'),
        '#options'=>array('USA','UK','France','Japan')
      );

    $form['submit']=array(
        '#type'=>'submit',
        '#value'=>t('Submit')
      );

      return $form;
}

In the above code in the implementation of hook_menu we create a menu item whose page_callback is drupal_get_form and the argument to that is the form_id “drupalform_form1”. The function drupalform_form1 returns the form array which we want to create.

In the function drupalform_form1 we create three text fields: name, last_name, email, and one select box for the country. In the select box we specify the options of the country with an array. We have also added a Submit button, so the user can actually submit the form. Now you should be able to go to your menu url: <your drupal base url>/drupalform/form1 and see the form as follows

Validating a Drupal form

Drupal uses naming conventions heavily to identify which functions to call on which events. The complete Drupal hook system is based on naming conventions. Similarly, the function called to validate your form data has to follow the naming convention <form_id>_validate and it will be passed the form_state as a variable.

Hence, for our form the function name will be: drupalform_form1_validate($form, $form_state).

The values which the user has entered will be present in an array $form_state['values'] with the same id as you specified in the form. So if we have to do the validations for our form the function will be:

function drupalform_form1_validate($form, $form_state) {

  if(empty($form_state['values']['name']))
     form_set_error('name','Name cannot be empty');
  else if(empty($form_state['values']['last_name']))
     form_set_error('last_name','Last name cannot be empty');
  else if(filter_var($form_state['values']['email'], FILTER_VALIDATE_EMAIL) == false)
    form_set_error('email','Email is not valid');
}

In the above function we check if the name and last_name are not empty and that the email is valid. If that is not the case we set a form error using the Drupal function form_set_error. This will display the error to the user and the form will not be submitted.

If you submit the form by entering an empty name you should see the following error on the screen:

Submitting a Drupal form

Similar to the validation function the submit function is also called based on the naming convention and the function name should be <form_id>_submit. Again, the variable $form_state will be passed to it. Our submit function will thus be defined as:

function drupalform_form1_submit($form, $form_state) {
   //Depending on the type of form you can add the logic
   //to store the details of the form 
   //by adding it in a Drupal table.
   //or sending a mail to the admin
   //Storing in a file
   //or pass it to some other service
   drupal_set_message("Form has been submitted");
}

Now if we pass all the valid fields you will get the following message on screen.

Using Field sets in Drupal Forms to separate elements.

Sometimes when the form is bigger and has many fields you might want to break it into small sections so that the form seems more logical to the user. To do this you can create fieldsets in Drupal to create groups of fields.

To create a fieldset called basicdetails to hold the fields we defined above we will have to update the drupalform_form1 as follows

function drupalform_form1() {
    $form = array();


     $form['basicdetails']=array(
        '#type'=>'fieldset',
        '#title'=>t('Enter your Basic details below'),
        '#description'=>t('These are all madatory')
      );

        $form['basicdetails']['name']=array(
            '#type'=>'textfield',
            '#title'=>t('Enter your name'),
            '#description'=>t('Your first name goes here')
          );
        $form['basicdetails']['last_name']=array(
            '#type'=>'textfield',
            '#title'=>t('Enter your Last name'),
            '#description'=>t('Your Last name goes here')
          );

         $form['basicdetails']['email']=array(
            '#type'=>'textfield',
            '#title'=>t('Enter your email'),
            '#description'=>t('Your email goes here')
          );


    $form['submit']=array(
        '#type'=>'submit',
        '#value'=>t('Submit')
      );

      return $form;
}

This will create a separate fieldset as shown below

The different form elements that can be used in Drupal forms

Drupal provides a great number of different types of fields which we can use in our forms. I will update our form to use some of these by creating two more field sets for address details and additional details. The updated code is below:

function drupalform_form1() {
    $form = array();


     $form['basicdetails']=array(
        '#type'=>'fieldset',
        '#title'=>t('Enter your Basic details below'),
        '#description'=>t('These are all madatory')
      );

        $form['basicdetails']['name']=array(
            '#type'=>'textfield',
            '#title'=>t('Enter your name'),
            '#description'=>t('Your first name goes here')
          );
        $form['basicdetails']['last_name']=array(
            '#type'=>'textfield',
            '#title'=>t('Enter your Last name'),
            '#description'=>t('Your Last name goes here')
          );

         $form['basicdetails']['email']=array(
            '#type'=>'textfield',
            '#title'=>t('Enter your email'),
            '#description'=>t('Your email goes here')
          );

  $form['addressdetails']=array(
        '#type'=>'fieldset',
        '#title'=>t('Enter your Address details below'),
        '#description'=>t('These are all madatory')
      );

        $form['addressdetails']['country']=array(
            '#type'=>'select',
            '#title'=>t('Select your country'),
            '#options'=>array('USA','UK','France','Japan')
          );
        $form['addressdetails']['city']=array(
            '#type'=>'textfield',
            '#title'=>t('Enter your city'),
            '#description'=>t('Your city name goes here')
          );
        $form['addressdetails']['localaddress']=array(
            '#type'=>'textarea',
            '#title'=>t('Enter address'),
            '#description'=>t('Your Address name goes here')
          );

     $form['additionaldetails']=array(
        '#type'=>'fieldset',
        '#title'=>t('Enter your other details below'),
        '#description'=>t('These are all optional')
      );

        $form['additionaldetails']['gender']=array(
            '#type'=>'radios',
            '#title'=>t('Gender'),
            '#options'=>array('Male','Female')
          );

        $form['additionaldetails']['suscribtion']=array(
            '#type'=>'checkboxes',
            '#title'=>t('I want to subscribe for'),
            '#options'=>array('Email newsletter','Offer vouchers')
          );

        $form['additionaldetails']['birthdate']=array(
            '#type'=>'date',
            '#title'=>t('Birthdate'),
          );

        $form['#attributes']['enctype'] = 'multipart/form-data';

         $form['additionaldetails']['picture']=array(
            '#type'=>'file',
            '#title'=>t('Upload your picture'),
          );



    $form['submit']=array(
        '#type'=>'submit',
        '#value'=>t('Submit')
      );

      return $form;
}

This is what the new fieldsets look like:

Conclusion

Drupal helps you create and process forms right inside your module. The APIs Drupal offers make it very simple to make an addition or modification of your form as the forms are arrays and even the validation and submission happens in a different function. This modular approach keeps the form code in your module clean and easy to maintain. You also do not need to bother with the HTML details of the form if you use the Drupal form API – all the HTML is auto-generated. Have fun creating your next form in your Drupal module!

If you’d like us to cover a more specific use case or go into more details, or just have feedback, let us know in the comments below!

Frequently Asked Questions about Understanding Forms in Drupal

How do I create a basic form in Drupal?

Creating a basic form in Drupal involves using the Form API. First, you need to define a form in a module by creating a function that returns a form array. This function should have a unique name, typically following the pattern ‘modulename_form’. The form array should define the structure and data of the form. After defining the form, you can display it in a page callback function using the ‘drupal_get_form’ function.

What is the purpose of the ‘drupal_get_form’ function in Drupal?

The ‘drupal_get_form’ function in Drupal is used to retrieve a form. It takes the form ID as an argument and returns the form rendered as a string. This function is essential in displaying the form on a page.

How can I customize the appearance of my form in Drupal?

You can customize the appearance of your form in Drupal by using the ‘#theme’ property in your form array. This property allows you to specify a theme function that will be used to render the form. You can also use CSS to style your form.

How do I handle form submission in Drupal?

Form submission in Drupal is handled by defining a submit handler function in your form array. This function is called when the form is submitted. It should take the form and form state as arguments and perform any necessary actions, such as saving data to the database.

What is the Form API in Drupal?

The Form API in Drupal is a powerful tool for creating and managing forms. It provides a structured way to define forms, handle form submission, and perform form validation. The Form API also includes many built-in form elements and properties for customizing the appearance and behavior of forms.

How do I validate form data in Drupal?

Form data in Drupal can be validated by defining a validation handler function in your form array. This function is called before the submit handler function and can be used to check the submitted form data for any errors. If any errors are found, they can be set with the ‘form_set_error’ function, which will prevent the form from being submitted.

What is the ‘webform’ module in Drupal?

The ‘webform’ module in Drupal is a popular module for creating and managing forms. It provides a user-friendly interface for creating forms, and includes many advanced features such as conditional fields, multi-page forms, and email notifications.

How do I create a multi-page form in Drupal?

Multi-page forms in Drupal can be created by using the ‘#multistep’ property in your form array. This property allows you to define a sequence of form pages, each with its own set of form elements.

How do I add AJAX functionality to my form in Drupal?

AJAX functionality can be added to a form in Drupal by using the ‘#ajax’ property in your form array. This property allows you to specify a callback function that will be called when the form is submitted via AJAX.

How do I create a custom form element in Drupal?

Custom form elements in Drupal can be created by defining a theme function that returns the HTML for the element. This function can then be used in your form array with the ‘#theme’ property.

Abbas SuterwalaAbbas Suterwala
View Author

Abbas is a software engineer by profession and a passionate coder who lives every moment to the fullest. He loves open source projects and WordPress. When not chilling around with friends he's occupied with one of the following open source projects he's built: Choomantar, The Browser Counter WordPress plugin, and Google Buzz From Admin.

drupaldrupal-planetFormsforms tutorialhtml formshtml forms drupalhtml forms tutorialPHPphp5tutorial
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week