How to pass values from one form to another in Drupal 9

When we are developing multiple forms which are related , there will be a need for passing values between forms. We can achieve this with different ways. Here we are discussing below types of methods where we can pass values between form.

  • Passing values using form action
  • Passing values using session
  • Passing values using configuration

Passing values using form action

Here we are passing value from first form by specifying action url of the first form as url of second form. So values will be posted to second form with out doing anything in first form submit handler.

So here we have a custom module dn_multipleform.

SO we are going to create tow forms in below path.

YOUR_PROJECT\modules\custom\dn_multipleform\src\Form\ActionFirstForm.php

YOUR_PROJECT\modules\custom\dn_multipleform\src\Form\ActionSecondForm.php

So below route we have added in routing.yml

\modules\custom\dn_multipleform\dn_multipleform.routing.yml

dn_multipleform.actionfirstform:
  path: '/actionfirstform'
  defaults:
    _title: 'Action First Form'
    _form: '\Drupal\dn_multipleform\Form\ActionFirstForm'
  requirements:
    _access: 'TRUE'
    
dn_multipleform.actionsecondform:
  path: '/actionsecondform'
  defaults:
    _title: 'Action Second Form'
    _form: '\Drupal\dn_multipleform\Form\ActionSecondForm'
  requirements:
    _access: 'TRUE'

So in first form we have fields first name and last name.

We are providing action target as second page url as below.

$form[‘#action’] = Url::fromUri(‘internal:/’ . ‘actionsecondform’)->toString();

See complete code of ActionFirstForm.php

<?php

namespace Drupal\dn_multipleform\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Core\Routing;

/**
 * Provides the form for adding countries.
 */
class ActionFirstForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'dn_first_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    
    
    $form['fname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('First Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	 $form['sname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Second Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	
    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#default_value' => 'Next' ,
    ];
   $form['#action'] = Url::fromUri('internal:/' . 'actionsecondform')->toString();
    return $form;

  }
  
   /**
   * {@inheritdoc}
   */
  public function validateForm(array & $form, FormStateInterface $form_state) {
      
		
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array & $form, FormStateInterface $form_state) {
	
  
  
  }

}
  

So in second form, we are going to capture the values as same like $_POST[’fname’].

In Drupal you can retrieve those value as below.

$fname = \Drupal::request()->request->get('fname');

Here in second form we are just retrieving the value and displaying on the second form. Complete code of second form provided below.

\modules\custom\dn_multipleform\src\Form\ActionSecondForm.php

<?php

namespace Drupal\dn_multipleform\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Core\Routing;

/**
 * Provides the form for adding countries.
 */
class ActionSecondForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'dn_second_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
   

    
	$fname = \Drupal::request()->request->get('fname');
	$form['description'] = [
      '#type' => 'item',
      '#markup' => $fname,
    ];
    $form['fname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('First Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	 $form['sname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('pal passing values  Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	$form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#default_value' => 'Next' ,
    ];

    return $form;

  }
  
   /**
   * {@inheritdoc}
   */
  public function validateForm(array & $form, FormStateInterface $form_state) {
       
		
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array & $form, FormStateInterface $form_state) {
	  
 
  }

}
  

Passing values using session

Here we are storing values of first form in session variable and retrieving same value in second form.

We have created below forms for the same purpose.

\modules\custom\dn_multipleform\src\Form\SessionFirstForm.php

\modules\custom\dn_multipleform\src\Form\SessionSecondForm.php

Added below routes in routing.yml

\modules\custom\dn_multipleform\dn_multipleform.routing.yml
dn_multipleform.sessionfirstform:
  path: '/sessionfirstform'
  defaults:
    _title: 'Session First Form'
    _form: '\Drupal\dn_multipleform\Form\SessionFirstForm'
  requirements:
    _access: 'TRUE'
    
dn_multipleform.sessionsecondform:
  path: '/sessionsecondform'
  defaults:
    _title: 'Session Second Form'
    _form: '\Drupal\dn_multipleform\Form\SessionSecondForm'
  requirements:
    _access: 'TRUE'

So here in first form submit handler we are saving fname value in session as below.

$tempstore = \Drupal::service('tempstore.private')->get('dn_multipleform');
$tempstore->set('firstname', $form_state->getValue('fname'));

Then redirect to the second form.

$form_state->setRedirectUrl(Url::fromUri('internal:/' . 'sessionsecondform'));

Here firstname is the session variable name and dn_multipleform is the name of our module.

So complete code of first form will be as below.

<?php

namespace Drupal\dn_multipleform\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Core\Routing;

/**
 * Provides the form for adding countries.
 */
class SessionFirstForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'dn_session_first_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    
    
    $form['fname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('First Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	 $form['sname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Second Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	
    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#default_value' => 'Next' ,
    ];

    return $form;

  }
  
   /**
   * {@inheritdoc}
   */
  public function validateForm(array & $form, FormStateInterface $form_state) {
        
		
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array & $form, FormStateInterface $form_state) {
	  
  
  $tempstore = \Drupal::service('tempstore.private')->get('dn_multipleform');
  $tempstore->set('firstname', $form_state->getValue('fname'));
  
  $form_state->setRedirectUrl(Url::fromUri('internal:/' . 'sessionsecondform'));
  
  }

}
  

So in second form retrieve session variable as below.

$tempstore = \Drupal::service('tempstore.private')->get('dn_multipleform');
     $fname = $tempstore->get('firstname');

So fname will be displayed in second form.

See the complete code of second form.

\modules\custom\dn_multipleform\src\Form\SessionSecondForm.php

<?php

namespace Drupal\dn_multipleform\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Core\Routing;

/**
 * Provides the form for adding countries.
 */
class SessionSecondForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'dn_sessionsecond_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
   
     $tempstore = \Drupal::service('tempstore.private')->get('dn_multipleform');
     $fname = $tempstore->get('firstname');
    
	$form['description'] = [
      '#type' => 'item',
      '#markup' => $fname,
    ];
    $form['fname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('First Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	 $form['sname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Second Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	$form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#default_value' => 'Next' ,
    ];

    return $form;

  }
  
   /**
   * {@inheritdoc}
   */
  public function validateForm(array & $form, FormStateInterface $form_state) {
        
		
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array & $form, FormStateInterface $form_state) {
	 
 
  }

}
  

So after submitting page /sessionfirstform you can see first from value is appearing in second form.

Passing values using configuration

Here we are saving value in configuration and retrieving value in second form from configuration. This is the most secured way of passing values between forms.

We are creating below forms for this purposes.

\modules\custom\dn_multipleform\src\Form\ConfigFirstForm.php

\modules\custom\dn_multipleform\src\Form\ConfigSecondForm.php

Below routing added for the same

dn_multipleform.configfirstform:
  path: '/configfirstform'
  defaults:
    _title: 'Config First Form'
    _form: '\Drupal\dn_multipleform\Form\ConfigFirstForm'
  requirements:
    _access: 'TRUE'
    
dn_multipleform.configsecondform:
  path: '/configsecondform'
  defaults:
    _title: 'Config Second Form'
    _form: '\Drupal\dn_multipleform\Form\ConfigSecondForm'
  requirements:
    _access: 'TRUE'

In submit handler of first form , save fname value to configuration as below.

$config = \Drupal::service('config.factory')->getEditable('dn_multipleform.settings');
$config->set('fname', $form_state->getValue('fname'))->save();

Here dn_multipleform is the name of our custom form.

And then redirect to second form as below.

$form_state->setRedirectUrl(Url::fromUri('internal:/' . 'configsecondform'));

So complete source code of ConfigFirstForm is provided below.

<?php

namespace Drupal\dn_multipleform\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Core\Routing;

/**
 * Provides the form for adding countries.
 */
class ConfigFirstForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'dn_first_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    
    
    $form['fname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('First Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	 $form['sname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Second Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	
    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#default_value' => 'Next' ,
    ];

    return $form;

  }
  
   /**
   * {@inheritdoc}
   */
  public function validateForm(array & $form, FormStateInterface $form_state) {
        //print_r($form_state->getValues());exit;
		
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array & $form, FormStateInterface $form_state) {
	
	  $config = \Drupal::service('config.factory')->getEditable('dn_multipleform.settings');
		$config->set('fname', $form_state->getValue('fname'))->save();
		$form_state->setRedirectUrl(Url::fromUri('internal:/' . 'configsecondform'));
  
  }

}
  

So in second form we will be retrieving same value as below.

$fname = \Drupal::config(‘dn_multipleform.settings’)->get(‘fname’);

See below complete code of second form ConfigSecondfForm.

<?php

namespace Drupal\dn_multipleform\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Core\Routing;

/**
 * Provides the form for adding countries.
 */
class ConfigSecondForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'dn_second_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
   

    
	$fname = \Drupal::config('dn_multipleform.settings')->get('fname');
	$form['description'] = [
      '#type' => 'item',
      '#markup' => $fname,
    ];
    $form['fname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('First Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	 $form['sname'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Second Name'),
      '#required' => TRUE,
      '#maxlength' => 20,
      '#default_value' => '',
    ];
	$form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#button_type' => 'primary',
      '#default_value' => 'Next' ,
    ];

    return $form;

  }
  
   /**
   * {@inheritdoc}
   */
  public function validateForm(array & $form, FormStateInterface $form_state) {
        //print_r($form_state->getValues());exit;
		
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array & $form, FormStateInterface $form_state) {
	  //echo "reaches";exit;
 
  }

}
  

All these examples are provided in below sample module.

Download  sample module.

Get Free E-book
Get a free Ebook on Drupal 8 -theme tutorial
I agree to have my personal information transfered to MailChimp ( more information )
if you like this article Buy me a Coffee this will be an ispiration for me to write articles like this.

You may also like...