Drupal 7 Custom Module Development
Illustration by John Hersey

Using the Form API (FAPI) to create a form quickly


Drupal 7 Custom Module Development

with Jon Peck

Start your free trial now, and begin learning software, business and creative skills—anytime, anywhere—with video instruction from recognized industry experts.

Start Your Free Trial Now

Video: Using the Form API (FAPI) to create a form quickly

For web application developers, the act of building forms and processing form submissions is a common occurrence. Numerous coding frameworks contain standardized mechanisms that can be leveraged to create forms, including support for common form elements, prevention of cross-site request forgeries, and so forth. Drupal is no exception, containing a comprehensive system known as the form API or FAPI. The Drupal form API provides a sophisticated network for building, validating, and executing forms.
please wait ...
Watch the Online Video Course Drupal 7 Custom Module Development
2h 57m Advanced Oct 16, 2012

Viewers: in countries Watching now:

Extend your Drupal 7 sites with custom modules, which allow you to create everything from admin interfaces to forms. Author Jon Peck describes how modules extend your base Drupal installation, then walks through how to write your own module with a practical example featuring geo-positioned alternative energy centers. The course also describes how to control access to site features, create new content types, build forms, understand data persistence, embrace coding standards, and much more.

Topics include:
  • Creating your first module
  • Interacting with hooks
  • Working with permissions and roles
  • Controlling access
  • Adding a menu item to an admin interface
  • Using the Form API (FAPI) to quickly create a form
  • Creating custom form validation
  • Manually creating a custom content type
  • Validating user input
  • Importing content using feeds
  • Creating a block
  • Understanding best practices and coding standards
Developer Web
Jon Peck

Using the Form API (FAPI) to create a form quickly

For web application developers, the act of building forms and processing form submissions is a common occurrence. Numerous coding frameworks contain standardized mechanisms that can be leveraged to create forms, including support for common form elements, prevention of cross-site request forgeries, and so forth. Drupal is no exception, containing a comprehensive system known as the form API or FAPI. The Drupal form API provides a sophisticated network for building, validating, and executing forms.

Using hooks, modules can cleanly manipulate any form within Drupal including those within core, by extending and overriding functionality, instead of needing to rewrite or hack it in. Drupal forms have four distinct steps; creation where the form elements and hierarchal structure are defined using a standardized array, theming which refers to the manipulation of the design. There are multiple levels of theming from individual form elements all the way up to the structural layout of the entire page.

In general, theming is mostly out of scope of this course, but it's helpful to know that the step exists. Validation immediately following form submission, Drupal form system performs generalized built-in validation. The validation step allows a developer to add more specific requirements for validation. And finally submission; once the user input has passed validation custom behavior can be outlined. Otherwise no functional changes occur. In the Wind Farms module, I'm going to specify three settings for an administrative interface: A toggle for enabling Google maps, a default map center latitude and longitude, and a default zoom level of the map.

I will cover seven common form elements: markup, checkbox, fieldset, text, select, and submit. Drupal Core contains additional form elements including date, file, password, radio, and more. The interactions and definitions of these additional form elements are very similar to the elements I will be demonstrating. To create a form, an implementation off hook_form is needed. Similar to hook menu, form elements are declared within an array.

Form elements can be nested allowing for complex hierarchies to be defined. By default, form elements are displayed in the order that they are defined in which enhances code readability. Let's create the form for the administrative settings for the Wind Farms module. Return to the IDE, navigate to the end of the wind farms module and add a dockblock for the form definition; Implements, hook_form, then same as the function name I discussed in the previous segment, create a new function named function windfarms_admin_settings_form.

Looking at the hook form API, I can see the hook_form takes two parameters. The first, the node that is being added or edited. In this context, it won't be used as I'm not actually editing a node. The second, pass by reference, is form_state. Form state passes data about the processed form between steps. Form state is passed by reference to allow its contents to be manipulated and passed between the form creation, validation, and submission.

Next, add a variable named form and set its value to an empty array. The name of the variable is technically unimportant, but it's best practice to name variables based on what their contents are. Add a return statement for the form variable at the end. As it's easy to forget to return the form definition after adding a number of form elements, return form. The first form element I will add is the Drupal form APIs default type markup.

Markup elements generate HTML to display inside a form. As they are default, there is no need to explicitly set a form element as markup. I will use a markup form element to give an administrative user an overview of the purpose of this form. Form elements are added to the form array using the unique name for data to be processed. Think of it as the name attribute in an HTML input and follow the same naming conventions, the value will be an empty array; form overview = array.

The form API uses hash tag names for the parameters to allow Drupal to differentiate between a nested form element and interactions with the API. The only parameter needed for a markup element is hash tag markup. The value should be wrapped in a t function; markup t 'This interface allows administrators to manage general Wind Farm Settings'. There is no restriction on the content that can be added to the markup element.

So HTML can be added as well. By default, the contents of the markup are not wrapped in any tags. To wrap an entire form element in an HTML tag there are additional parameters that can be defined; the prefix and suffix. I'm going to wrap the page overview in a paragraph tag. Prefix and suffix can be defined independently and do not depend on one another meaning a prefix can be defined in the suffix can be emitted. This can be useful when manipulating markup to facilitate JavaScript operations, for example.

Prefix is the paragraph tag and suffix is the closing paragraph tag. Typically HTML tags should be avoided in the form definition to allow a separation of logic and design. Instead it should be done in the theme. As theming really isn't covered in this course, and theming does interact with the form API, I feel it's worth demonstrating. Now that the purpose of the page has been given I will add the first functional element; a check box for toggling a Google map that will be created later.

I will use the key wind farms g map for the name of the element to be consistent with how it will be saved in the database. The first parameter will be the title. This will be displayed on the form typically before the element itself. The value of the title should be wrapped in the t function, Enable Google Maps. Next a description, I like to think of this as context and help to the user. Again, the value will be wrapped in the t function, description t, 'When enabled, Google Maps will be rendered if latitude and longitude are known'.

As this form element needs to be a check box, I will need to set the type to specify how this element is handled and rendered; type checkbox. Finally, I will specify a default value. The default value is initially set the first time the form is accessed. If the form fails validation, then the user specified value is used in its place. As the check box is binary, meaning it's on or off, the default value should be set as the integer zero or one.

In a later segment, the value for these settings will be loaded from the database. So for the time being I will just default the element to being on; default_value 1. I'm going to enclose the next form elements in the field set. Field sets are used to give context and group form elements which improves usability and accessibility. The end result will be a nested array, with a field set definition at the head with the individual form elements as children.

The form elements I'm going to put in this field set are the default map center location, so I will name this field set default_center. Form 'default_center' is an array with the title Map Center, a description ('Location of the center of the map of wind farms.') then the type is fieldset.

Field sets have an additional property, the ability to collapse the display. This is optional but can be especially useful when working with a large form. By default, the collapsible property is disabled. To enable it, set it to Boolean true; collapsible set to TRUE. The next property is the default collapse state. I will set it to Boolean false to have it open by default, collapsed set to FALSE.

Now that the fieldset has been defined, I can add the individual form elements within it using nesting. I'm going to use the text field form element for the latitude and longitude of the map center. For the default value, I will use the coordinates of a wind farm in upstate New York, which is close to my office. Form 'default_center' 'windfarms_default_center_lat' = array and the title of (Latitude) and the description.

I'll describe the expected format, Signed degrees format DDD.dddd. Close the parenthesis. The type is textfield and the default value is 42.91455 as it's important to know where the center of the map is, I'm going to make these form elements required; required TRUE.

Next, I'll do the longitude. I am going to paste to save some time, call it default_center_long, for the title Longitude, and for the default_value -75.569851. The last setting I will capture is the default zoom of the Google Maps map. The Google maps API zoom level is between 0 and 20.

As this is a closed domain of options, I will use a select list as the form element. Select list take an additional parameter, the options, which is an array where the keys is the value which in turn maps to the label to be shown to the user. While the option array can be defined in line with the form element, sometimes it's necessary to build the options outside of the form element and pass a variable containing the array of options. I'm going to build the options rate using range to define the elements 0 through 20 then overwrite some individual keys with specific values to give context to the user.

Options = range, the range of 0 to 20 in one step increments, options 0, it's going to be 0 Furthest for some context, and options 20 t 20 Closest. Now that the values are defined, I can specify the form element. Form windfarms_default_gmap_zoom = array, the title of Google Map zoom, and a description default level of zoom between 0 and 20.

For type I will specify select. Options will be set to the options array. The default_value, I will set at 8 and required is TRUE. I'm almost done with the form. One final element is necessary, a submit button. No special name is required for the name, so I will just name it submit; form submit = array, it'll be type.

Only one additional key is required, the value, which will be what is shown as the label to the user, Save. Save the module then return to the browser and navigate to the Wind Farms Settings page. Instead of the error, the newly created form will be shown. If any of the form elements are missing go back and check the types first. The Drupal form API is much more likely to do nothing than to throw a visible error. While I've not specified either form validation or submission handling it, the use of the required fields has been automatically implemented.

Remove the value for latitude and longitude then click Save. You will see a generic error message for each form element that was required. Latitude fields required is required, and so forth, and the elements that is errored is highlighted in red. In the next segment, I will describe how to customize these error messages and provide more granular validation, then how to handle a validated submission.

Find answers to the most frequently asked questions about Drupal 7 Custom Module Development .

Expand all | Collapse all
please wait ...
Q: gmap3_tools is not working the way I expected it to. What version of gmap3_tools should I be using?
A: Use the free exercise file containing the version of gmap3_tools used for recording; the published version of the module on drupal.org has changed since recording and is not backwards compatible.
Q: I attempted to run the Drupal site root from the project files, but the site isn't loading. Why not?
A: The Drupal configuration file in sites/default/settings.php contains database configuration specific to the environment used to record the movie. This may be different than your environment. Edit the file and search for "windfarms" - you may need to change the database host, username, password, db name and port to match your specific environment.
Share a link to this course

What are exercise files?

Exercise files are the same files the author uses in the course. Save time by downloading the author's files instead of setting up your own files, and learn by following along with the instructor.

Can I take this course without the exercise files?

Yes! If you decide you would like the exercise files later, you can upgrade to a premium account any time.

Become a member Download sample files See plans and pricing

Please wait... please wait ...
Upgrade to get access to exercise files.

Exercise files video

How to use exercise files.

Learn by watching, listening, and doing, Exercise files are the same files the author uses in the course, so you can download them and follow along Premium memberships include access to all exercise files in the library.

Exercise files

Exercise files video

How to use exercise files.

For additional information on downloading and using exercise files, watch our instructional video or read the instructions in the FAQ .

This course includes free exercise files, so you can practice while you watch the course. To access all the exercise files in our library, become a Premium Member.

* Estimated file size

Are you sure you want to mark all the videos in this course as unwatched?

This will not affect your course history, your reports, or your certificates of completion for this course.

Mark all as unwatched Cancel


You have completed Drupal 7 Custom Module Development.

Return to your organization's learning portal to continue training, or close this page.

Become a member to add this course to a playlist

Join today and get unlimited access to the entire library of video courses—and create as many playlists as you like.

Get started

Already a member ?

Exercise files

Learn by watching, listening, and doing! Exercise files are the same files the author uses in the course, so you can download them and follow along. Exercise files are available with all Premium memberships. Learn more

Get started

Already a Premium member?

Exercise files video

How to use exercise files.

Ask a question

Thanks for contacting us.
You’ll hear from our Customer Service team within 24 hours.

Please enter the text shown below:

The classic layout automatically defaults to the latest Flash Player.

To choose a different player, hold the cursor over your name at the top right of any lynda.com page and choose Site preferences from the dropdown menu.

Continue to classic layout Stay on new layout
Exercise files

Access exercise files from a button right under the course name.

Mark videos as unwatched

Remove icons showing you already watched videos if you want to start over.

Control your viewing experience

Make the video wide, narrow, full-screen, or pop the player out of the page into its own window.

Interactive transcripts

Click on text in the transcript to jump to that spot in the video. As the video plays, the relevant spot in the transcript will be highlighted.

Learn more, save more. Upgrade today!

Get our Annual Premium Membership at our best savings yet.

Upgrade to our Annual Premium Membership today and get even more value from your lynda.com subscription:

“In a way, I feel like you are rooting for me. Like you are really invested in my experience, and want me to get as much out of these courses as possible this is the best place to start on your journey to learning new material.”— Nadine H.

Thanks for signing up.

We’ll send you a confirmation email shortly.

Sign up and receive emails about lynda.com and our online training library:

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

Sign up and receive emails about lynda.com and our online training library:

Here’s our privacy policy with more details about how we handle your information.

submit Lightbox submit clicked
Terms and conditions of use

We've updated our terms and conditions (now called terms of service).Go
Review and accept our updated terms of service.