Friday, 21 April 2017

Drupal 8 - Steps to Create a Custom Form

Drupal 8 form API is similar to Drupal 7 Form API. Only difference is, we will be having separate validation and submission forms. 
Drupal 8 even has some new (HTML 5) elements like "color, email, date, url, range, tel, time, week, month etc. 
Reference Link for HTML5 elements supported in Drupal 8: https://www.drupal.org/node/1183606
In Drupal 8 Form classes implement the \Drupal\Core\Form\FormBuilderInterface and the basic workflow of a form is defined by the buildForm, validateForm, and submitForm methods of the interface.
There are a different classes to choose depending on the type of form that we are creating.
  • ConfigFormBase : For creating system configuration forms like the one found at admin/config/system/site-information.
  • ConfirmFormBase : For providing users with a form to confirm an action such as deleting a piece of content.
  • FormBase : The most generic base class for generating forms.
Folder Structure




Create a simple Addressbook custom form in Drupal 8

  • Create a folder with the name "addressbook" in \Root\modules\custom\ folder.
  • Create addressbook.info.yml file with below code.

name: Addressbook
description: An address book form to enter addresses.
core: 8.x
package: Custom
type: module

In Drupal 8 important part of module, theme, or profile is the .info.yml file. It stores metadata about the project. This is almost similar to .info file in Drupal 7.
.info file contains name, description, core, package, dependencies, type values in it. The type key, is something new in Drupal 8. It is required and indicates the type of extension, e.g. module, theme or profile.
  • Create addressbook.routing.yml file with below code.

addressbook.form:

 path: '/addressbook/infoform'
 defaults:
   _title: 'Addressbook form'
   _form: '\Drupal\addressbook\Form\AddressbookForm'
 requirements:
   _permission: 'access content'

Drupal 7 hook_menu() got replaced with this routing system [Creating menus, tabs etc.]. 
A route is a path which return some sort of content on top of it.
For example,  '/about-us' is a route. When Drupal receives a request, it tries to match the requested path to a route it knows about. If the route is found, then the route's definition is used to return content. Otherwise, Drupal returns a 404.
  • Create AddressbookForm.php file in \Root\modules\custom\addressbook\src\Form\ folder with below code.

<?php
/**
* @file
* Contains \Drupal\addressbook\Form\AddressbookForm.
*/
namespace Drupal\addressbook\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class AddressbookForm extends FormBase {

public function getFormId() {
return 'addressbook_form';
}

public function buildForm(array $form, FormStateInterface $form_state) {
$form['full_name'] = array(
'#type' => 'textfield',
'#title' => t('Full Name:'),
'#required' => TRUE,
);
$form['email_id'] = array(
'#type' => 'email',
'#title' => t('Email ID:'),
'#required' => TRUE,
);
$form['contact_number'] = array (
'#type' => 'tel',
'#title' => t('Mobile no'),
);
$form['date_of_birth'] = array (
'#type' => 'date',
'#title' => t('Date of Birth'),
'#required' => TRUE,
);
$form['gender'] = array (
'#type' => 'select',
'#title' => ('Gender'),
'#options' => array(
'Female' => t('Female'),
'male' => t('Male'),
),
);
$form['age_confirmation'] = array (
'#type' => 'radios',
'#title' => ('Are you above 18 years old?'),
'#options' => array(
'Yes' =>t('Yes'),
'No' =>t('No')
),
);
$form['actions']['#type'] = 'actions';
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $this->t('Save'),
'#button_type' => 'primary',
);
return $form;
}

public function validateForm(array &$form, FormStateInterface $form_state) {
if (strlen($form_state->getValue('contact_number')) < 10) {
$form_state->setErrorByName('contact_number', $this->t('Contact number is too short.'));
} else if (strlen($form_state->getValue('contact_number')) > 10) {
$form_state->setErrorByName('contact_number', $this->t('Contact number is too long.'));
}
}

public function submitForm(array &$form, FormStateInterface $form_state) {
drupal_set_message($this->t('Addressbook Information is being submitted!'));
foreach ($form_state->getValues() as $key => $value) {
drupal_set_message($key . ': ' . $value);
}
}
}


In the above code,

First, we are declaring the namespace, the other classes we want to use, and extend the FormBase class.
Second we are getting code from some other classes, using the use PHP keyword and then the namespace, using the PSR-4 standard, It autoload the classes in the files that correspond to these namespaces
Third we are declaring our AddressbookForm Class which extends FormBase.
Fourth, we are building a Form using buildForm function.
Fifth, we are Validating Form values using validateForm function
Sixth, on successful entry of form data, we are submitting the form using submitForm function

  • Login to Drupal Backend.
  • Go to Extend Menu Item "/drupal8/admin/modules"
  • Enable Addressbook Module.
  • Access addressbook/infoform URL.







No comments:

Post a Comment

Thank you so much for providing your valuable feedback. I will will look into them and update my skills & technologies accordingly.