Create custom forms in custom module - Drupal 8 Example

In this example we will build a custom form  inside custom module to collect information from  the site visitors.

Before starting this example, assuming you have read our previous example  Create A Custom Module In Drupal 8.

Our first step is to create a new sub directory in the ” hello ” module’s src directory named as ” form “.

Create custom form folder inside custom module directory

Under form create a new file name as follows :

Create custom form php file

Create a new file named as ” HelloForm.php ” and add the following content in this file.


<?php

	//include helloform
	namespace Drupal\hello\Form;
	
	//include FormBase class
	use Drupal\Core\Form\FormBase;
	
	//include FormStateInterface class	
	use Drupal\Core\Form\FormStateInterface;
	
	class HelloForm extends FormBase {
				 
		public function buildForm(array $form, FormStateInterface $form_state) {
						 
				   $form['job_title'] = [
			
						  '#type' => 'textfield',
						  '#title' => $this->t('Job Title'),
						  '#description' => $this->t('Enter your Job Title. 
													 It must be at least 5 characters in length.'),
									 
						  '#required' => TRUE,
					];
					
					$form['actions'] = [
					
						  '#type' => 'actions',
						  
					];
					
					$form['actions']['submit'] = [
					
						'#type' => 'submit',
						'#value' => $this->t('Submit'),
						
					 ];
					 
				return $form;
			}
							
			// returns hello_form				
			public function getFormId() {
				
				 return 'hello_form';
			}
				
			// validateForm used for validation to fields	
			public function validateForm(array &$form, FormStateInterface $form_state) {
				
				$job_title = $form_state->getValue('job_title');
				
				// if job_title <5 then set a title for job_title
			    if (strlen($job_title) < 5) {
					
					// Set an error for the form element with a key of "title".
					$form_state->setErrorByName('job_title', $this->t('Your job title must be at least 5
					characters long.'));
				}
			}
			
			// submitForm function accepts no of arguments
			public function submitForm(array &$form, FormStateInterface $form_state) {
				
				/*
				* This would normally be replaced by code that actually does something
				* with the title.
				*/
				
				//returns the job title
				$job_title = $form_state->getValue('job_title');
				drupal_set_message(t('You specified a job title of %job_title.', ['%job_title' =>
				$job_title
			
			}
	}
						
?>

In this code we have defined many elements which is as follows :

$form[‘job_title] element describes a text field on the form, which will  display a job title, description,  and it is also set as a required field.

$form[‘actions’] are used as grouping elements describes all of the submit handlers into an actions elements with key of actions.

$form[‘actions’][‘submit’] elements add a submit button that are used as submission of the form.

The next step is to upadate the ” hello.routing.yml” file to provide a path.

update the routing file with additional code.

hello.form       //name of the new route
    path : 'hello/form'    //path, access to the form
    defaults :
         _form : '\Drupal\hello\Form\HelloForm'
         _title: 'Hello Form'         //displays the title
    requirements :
          _permission : 'access content'     // permissions granted

First line “ hello.form ” describes the name of the new route.

Save this routing file.

Create custom form php file

For checking validation enter a job title which is  less than five characters and click  on submit button.

Form validation message on page

After filling up right information in the form with valid validation it will display right appropriate message.

Show form success message

Now our form is accessible through the URL.

In our next step we will provide a menu item to make it easier for our site visitors.

To add a menu item we will edit our “hello.links.menu.yml” file and add the following code at  end of the file.


hello.form :             // name of the link
  title : Hello Form     // title text appears on page
  menu_name : main       // consider as main menu link
  route_name : hello.form       // route name
  expanded : TRUE
  weight: 120

Display form in navigation menu

you can also add multiple entry fields to your form .There are several other    form elements which provide a good looking user interface.

Here I have added many elements in our form that are available in drupal8.

The code is given below :


    namespace Drupal\hello\Form;

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

   class HelloForm extends FormBase {
		
		public function buildForm(array $form, FormStateInterface $form_state) {
		
		$form['job_title'] = [
		
				'#type' => 'textfield',
				'#title' => $this->t('Job Title'),
				'#description' => $this->t('Enter your Job Title. 
											  It must be at least 5 characters in length.'),
				'#required' => TRUE,
		];
		
		// CheckBoxes.
		$form['tests_taken'] = [
		
				'#type' => 'checkboxes',
				'#options' => ['SAT' => t('SAT'), 'ACT' => t('ACT')],
				'#title' => $this->t('What standardized tests did you take?'),
				'#description' => 'If you did not take any of the tests, leave unchecked',
		];
		
		// Color.
		$form['color'] = [
		
				'#type' => 'color',
				'#title' => $this->t('Color'),
				'#default_value' => '#ffffff',
				'#description' => 'Pick a color by clicking on the color above',
		];
		
		// Date.
		$form['expiration'] = [
		
				'#type' => 'date',
				'#title' => $this->t('Content expiration'),
				'#default_value' => ['year' => 2020, 'month' => 2, 'day' => 15],
				'#description' => 'Enter a date in the form of YYYY MM DD',
		
		];
		
		// Email.
		$form['email'] = [
		
				'#type' => 'email',
				'#title' => $this->t('Email'),
				'#description' => 'Enter your email address',
		
		];
		
		// Number.
		$form['quantity'] = [
		
				'#type' => 'number',
				'#title' => t('Quantity'),
				'#description' => $this->t('Enter a number, any number'),
		
		];
		
		// Password.
		$form['password'] = [
		
				'#type' => 'password',
				'#title' => $this->t('Password'),
				'#description' => 'Enter a password',
		
		];
		
		// Password Confirm.
		$form['password_confirm'] = [
		
				'#type' => 'password_confirm',
				'#title' => $this->t('New Password'),
				'#description' => $this->t('Confirm the password by re-entering'),
		
		];
		
		// Range.
		$form['size'] = [
		
				'#type' => 'range',
				'#title' => t('Size'),
				'#min' => 10,
				'#max' => 100,
				'#description' => $this->t('This is a slider control, pick a value between 10 and 100'),
		];
		
		// Radios.
		$form['settings']['active'] = [
		
				'#type' => 'radios',
				'#title' => t('Poll status'),
				'#options' => [0 => $this->t('Closed'), 1 => $this->t('Active')],
				'#description' => $this->t('Select either closed or active'),

		];
		
		// Search.
		$form['search'] = [
		
				'#type' => 'search',
				'#title' => $this->t('Search'),
				'#description' => $this->t('Enter a search word or phrase'),
		];
		
		// Select.
		$form['favorite'] = [
		
				'#type' => 'select',
				'#title' => $this->t('Favorite color'),
				'#options' => [
							'red' => $this->t('Red'),
							'blue' => $this->t('Blue'),
							'green' => $this->t('Green'),
					],
				'#empty_option' => $this->t('-select-'),
				'#description' => $this->t('Which color is your favorite?'),
		];
		
		// Tel.
		$form['phone'] = [
		
				'#type' => 'tel',
				'#title' => $this->t('Phone'),
				'#description' => $this->t('Enter your phone number, beginning with country code,
				e.g., 1 503 555 1212'),
		];
		
		// TableSelect.
		$options = [
		
				1 => ['first_name' => 'Indy', 'last_name' => 'Jones'],
				2 => ['first_name' => 'Darth', 'last_name' => 'Vader'],
				3 => ['first_name' => 'Super', 'last_name' => 'Man'],
		];
		
		$header = [
		
				'first_name' => t('First Name'),
				'last_name' => t('Last Name'),
		];
		
		$form['table'] = [
		
				'#type' => 'tableselect',
				'#title' => $this->t('Users'),
				'#title_display' => 'visible',
				'#header' => $header,
				'#options' => $options,
				'#empty' => t('No users found'),
		];
		
		// Textarea.
		$form['text'] = [
		
				'#type' => 'textarea',
				'#title' => $this->t('Text'),
				'#description' => $this->t('Enter a lot of text here'),
		];
		
		// Textfield.
		$form['subject'] = [
		
				'#type' => 'textfield',
				'#title' => t('Subject'),
				'#size' => 60,
				'#maxlength' => 128,
				'#description' => $this->t('Just another text field'),
		];
		
		// Weight.
		$form['weight'] = [
		
				'#type' => 'weight',
				'#title' => t('Weight'),
				'#delta' => 10,
				'#description' => $this->t('A Drupal weight filter'),
		];
		
		// Group submit handlers in an actions element with a key of "actions" so
		// that it gets styled correctly, and so that other modules may add actions
		// to the form.
		
		$form['actions'] = [
		      '#type' => 'actions',
		];
		
		// Add a submit button that handles the submission of the form.
		$form['actions']['submit'] = [
		
			'#type' => 'submit',
			'#value' => $this->t('Submit'),
			'#description' => $this->t('Submit, #type = submit'),
		];
		
		return $form;
	}
	
	public function getFormId() {
		
		return 'hello_form';
	}
				
	public function validateForm(array &$form, FormStateInterface $form_state) {
			
		$job_title = $form_state->getValue('job_title');
		
		if (strlen($job_title) < 5) {
					 
			// Set an error for the form element with a key of "title".
			$form_state->setErrorByName('job_title', $this->t('Your job title must be at least 5
			characters long.'));
		}
	}
		
	public function submitForm(array &$form, FormStateInterface $form_state) {
		
		// Find out what was submitted.
		$values = $form_state->getValues();
		
		foreach ($values as $key => $value) {
					 
			$label = isset($form[$key]['#title']) ? $form[$key]['#title'] : $key;
			
			// Many arrays return 0 for unselected values so lets filter that out.
			if (is_array($value)) {
						  
			   $value = array_filter($value);
			}
			
			// Only display for controls that have titles and values.
			if ($value && $label) {
						   
				$display_value = is_array($value) ? preg_replace('/[\n\r\s]+/', ' ', print_r($value,
				1)) : $value;
				
				$message = $this->t('Value for %title: %value', array('%title' => $label, '%value'
				 => $display_value));
			 
			   drupal_set_message($message);
		    }
	     }  // foreach closed
	 }  // function closed
	 
  }  // class closed
  
  
?>
	

page looks like this :

Form module extra fields

you can adjust your form field according to the requirement.