Source: Trellon Blog

Trellon Blog Creating Custom Forms in Drupal 8

Drupal 8 is not far off from being released, and you may have heard some chatter about the differences in how you create custom modules. The reality is that, while there are some differences, it's not really that hard to wrap your head around them. This article provides a gentle introduction to creating forms in Drupal 8, and highlights the differences and similarities to how you would do this in previous versions of the platform.Step 1: Create the Info FileLet's start by creating a new custom module called Amazing Forms. Under modules, let's create a folder called amazing_forms, and within it let's create a yml file. A yml file (or YAML, which stands for "YAML Ain't Markup Language") is a file that specifies the configuration for a file.Let's create a yml file called amazing_forms.info.yml. For all practical purposes, it's very similar to the .info files we used in Drupal 7. Let's put some basic information into the file, to describe the module and tell Drupal what it is supposed to do.amazing_forms.info.yml:name: Amazing formstype: moduledescription: 'Demo for creating Drupal 8 forms.'package: Customcore: 8.xhidden: falseThe basic settings we are providing in this file should be recognizable to anyone who has created a custom module in Drupal 7. While there are a lot of other settings that could go into a yml file, we are really only concerned with the basics for this demonstration.Step 2: Create the Files for the Module and the ControllerThis step is where things start to get a little more interesting. In Drupal 7, we would simply create a module file and start coding. In Drupal 8, we do things a little differently.Start off by creating a file called amazing_forms.module, and leave it empty for now. This is the module file we all know and love, and it's where most of our code will live.The next thing we are going to do is create our forms. Instead of defining the forms in the custom module, we are going to create a custom controller to handle how the form works in our site. While the word controller may sound unfamiliar, it's not something to be afraid of. In PHP, controllers are really just elaborate functions with some special properties that make them easier to work with. When you use a controller class, you are technically creating an object, which has it's own functions (called methods) attached that you can use to manipulate through code.To create our controller, we are going to create some subdirectories to store the code in a way Drupal can recognize. Create a directory called src, and within there, create another directory called Form (and mind the capitalization). This is where our controllers are going to live, and it's where we will be doing most of the work to create this module.Step 3: Create the ControllerSo, finally, we get to write some code. Within the src/Forms directory, create a new file called ContributeForm.php. This file is going to store the controller for our form. The controller is going to include some unique properties, as well as some methods that are very familiar to experienced Drupalists. Here's the basic skeleton for our controller.<?php/** * @file * Contains \Drupal\amazing_forms\Form\ContributeForm. */namespace Drupal\amazing_forms\Form;use Drupal\Core\Form\FormBase;use Drupal\Core\Form\FormStateInterface;use Drupal\Component\Utility\UrlHelper;/** * Contribute form. */class ContributeForm extends FormBase { /** * {@inheritdoc} */ public function getFormId() { } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { } /** * {@inheritdoc} */ public function validateForm(array &$form, FormStateInterface $form_state) { } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { }}?>So, you will notice our controller is going to include a namespace, which is a unique name assigned to our module. Namespaces have a lot of uses, but the basic one everyone needs to understand is that they ensure code works together within a website. Next, you are going to notice some use statements. These statements are there to tell Drupal to include some other controllers before this one is called, to ensure they are available inside our controller.Any time you are creating a form in your site, you can write a use statement for Drupal\Core\Form\FormBase. Any time you are creating a configuration form (aka an admin form) you also need to include a use statement for Drupal\Core\Form\ConfigFormBase.While these conventions may seem new, there's a few familiar things in there as well. Our controller also includes 4 methods. Look at the names - getFormId, buildForm, validateForm and submitForm. These methods are going to be familiar to anyone who already knows Drupal's Form API, they are very similar to the handlers we used to develop around forms in Drupal 7. Even the variables are similar (array &$form, FormStateInterface $form_state).Let's look at how each of these methods can work. getFormId is where we assign a unique id to the form being created, and it might look like this:<?php public function getFormId() { return 'amazing_forms_contribute_form'; }?>buildForm would be used to actually create the form, and it could be filled out like this:<?php public function buildForm(array $form, FormStateInterface $form_state) { $form['title'] = array( '#type' => 'textfield', '#title' => t('Title'), '#required' => TRUE, ); $form['video'] = array( '#type' => 'textfield', '#title' => t('Youtube video'), ); $form['video'] = array( '#type' => 'textfield', '#title' => t('Youtube video'), ); $form['develop'] = array( '#type' => 'checkbox', '#title' => t('I would like to be involved in developing this material'), ); $form['description'] = array( '#type' => 'textarea', '#title' => t('Description'), ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Submit'), ); return $form; }?>validateForm would be used to check the values in the form before they are saved and throw errors, similar to how you see here:<?php public function validateForm(array &$form, FormStateInterface $form_state) { // Validate video URL. if (!UrlHelper::isValid($form_state->getValue('video'), TRUE)) { $form_state->setErrorByName('video', $this->t("The video url '%url' is invalid.", array('%url' => $form_state->getValue('video')))); } }?>And, finally, submitForm would be used to actually carry out the form submission process:<?php public function submitForm(array &$form, FormStateInterface $form_state) { // Display result. foreach ($form_state->getValues() as $key => $value) { drupal_set_message($key . ': ' . $value); } }?>So, as you can see, the process for creating a form is actually conceptually similar to what we have been doing in Drupal with the Form API in previous versions. Controllers are really just a way of packaging the hooks we would have used in a form where they are more readable and easier to work with. Instead of writing a bunch of functions with names like amazing_forms_contribution_form_submit, we are using shorter, more declarative names that exist in their own namespace.Step 4: Add a Router and Call it a DayNow that you have added a controller to your custom module, you are almost done. The last thing to do is create a router file.A router file is something that tells Drupal how to find controllers in your site. It's another yml file, and it contains information about the path and location of files. You can use these files to specify permissions and variables to be passed to the theming engine. Create a file called amazing_forms.routing.yml in the amazing_forms module directory, and include the following content:amazing_forms.routing.ymlamazing_forms_contribute: path: 'amazing-forms/contribute' defaults: _form: '\Drupal\amazing_forms\Form\ContributeForm' _title: 'Conribute page' requirements: _permission: 'access content'This code defines the path you use to access the form through a browser, the page title, the path for your controller and the necessary permissions for accessing the form.Final thoughtsCreating custom modules in Drupal 8 may seem hard, but there's more there that's similar than what's new. Yes, object oriented programming is a complex subject, and this article only skims the surface. Practically, in most situations, a basic understanding of controllers, paths and yml file structures will allow you to get started working with the newest version of the platform. In exchange, you gain more power and flexibility around the architecture of your sites.

Read full article »
Est. Annual Revenue
$5.0-25M
Est. Employees
25-100
CEO Avatar

CEO

Update CEO

CEO Approval Rating

- -/100



Trellon is headquartered in Washington, District of Columbia. Trellon has a revenue of $13M, and 49 employees. Trellon has 3 followers on Owler.