4

In the first page I have the following code:

$form['message1'] = array(
  '#markup' => $this->t('Check Your Details once again !!'),
);

$form['candidate_name'] = array(
  '#type' => 'textfield',
  '#title' => t('Candidate Name:'),
  '#required' => TRUE,
);

$form['Back'] = array(
  '#type' => 'submit',
  '#value' => t('Back'),
);


$form['submit']= array(
  '#type' => 'submit',
  '#value' => t('Proceed To Pay'),
);

return $form;


function submitForm(array &$form, FormStateInterface $form_state){
  drupal_set_message($this->t('@candidate_name! Wow! Nice choice! Thanks for telling us!', array('@candidate_name' => $form_state->getValue('candidate_name'))));
  $form_state->setRedirect('second_page');
}

In the second page I have the following code:

public function buildForm(array $form, FormStateInterface $form_state) {

  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Candidate Name:'),
    '#required' => TRUE,
  );

  $form['Back'] = array(
    '#type' => 'submit',
    '#value' => t('Back'),
  );

  return $form;
}

How can I get the first page candidate name into the second page candidate textfield?

3
  • I'm, starting to think that is not possible to send the form using the POST method in Drupal. Nobody talk about this in the answers :-( Apr 24, 2017 at 1:40
  • 1
    You want to build a multistep form, so may have a look on How to Build Multi-step Forms in Drupal 8 There will be values from the first form used in the second form.
    – RWAM
    Apr 24, 2017 at 7:47
  • Check my second edit that have the answer to your question. Nov 29, 2017 at 19:18

5 Answers 5

2
+100

Quite a pickle! Here are some suggestions:

Solution 1: Session to the rescue!

  • After the first form is submitted, validated and processed, store the relevant values (the ones you want to pass to the second form) in the session.
  • While building the second form, use the values stored in session as default values to pre-populate it.

Solution 2: Multi-step form

  • Merge the 2 forms into one giant form. Put the elements of the first form in one container and the elements of the second form in another container. Set #access to FALSE for the second container to hide the second container.
  • After the user submits the info in the first part of the form, hide the first container and show the second one!

Reference: See the form examples provided in the examples module.

Solution 3: Form states?

Depending on situation, you can also consider using form states. If you use form states, the hiding and showing can be done in the client-side. So the form will make one request to the server once it has all the data.

Solution 4: Change form action!

Depending on situation, you may even consider changing the action attribute of the form so that the values are submitted to the URL you specify in the form's action attribute.

10
  • I'm giving you the bounty because I think that you have the most complete answer but, I'm continuous figuring out how to send through POST a form to another page. This is very simple using HTML and PHP but in Drupal 8 I can't find how to do this! Apr 25, 2017 at 18:56
  • Since you say it is simple in HTML, I wonder if you mean to do something as simple as changing the form's action attribute? Do you want to do something like that?
    – Jigarius
    Apr 25, 2017 at 19:04
  • Send from a drupal form (in page1) with method=post the information to another page (page2) through POST. In my answer I show how to do this but using a redirect so at the end in page2 you need to use GET and see the values in the url. I don't know if this is posible with the new use of the FORMS in Drupal 8. I don't know if you get the point? Apr 25, 2017 at 20:14
  • do you know how to do this? Apr 28, 2017 at 19:54
  • Did you try any of the solutions I suggested in the answer?
    – Jigarius
    Apr 30, 2017 at 5:10
3

This is how I send information from one form to another.

In the first page:

use \Drupal\Core\Url;

function submitForm(array &$form, FormStateInterface $form_state){
  drupal_set_message($this->t('@candidate_name! Wow! Nice choice! Thanks for telling us!', array('@candidate_name' => $form_state->getValue('candidate_name'))));

  $params['query'] = [
    'candidate_name' => $form_state->getValue('candidate_name'),
  ];

  $form_state->setRedirectUrl(Url::fromUri('internal:' . 'second_page', $params));
}

In the second page:

public function buildForm(array $form, FormStateInterface $form_state) {   
  $candidate_name = \Drupal::request()->query->get('candidate_name');

  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Candidate Name:'),
    '#required' => TRUE,
    '#value' => $candidate_name,
  );

  return $form;
}

EDIT: For POST method I never see it before, but you can create in the first page a session var and use this var in the second var after the redirection. Take a look in Storing Session Data with Drupal 8.

SECOND EDIT: It seems that the correct way todo this is with PrivateTempStore, if you go to see the CommentAdminOverview in Core you will see this:

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
      ...
      $info = [];
      /** @var \Drupal\comment\CommentInterface $comment */
      foreach ($comments as $comment) {
        $langcode = $comment->language()->getId();
        $info[$comment->id()][$langcode] = $langcode;
      }
      $this->tempStoreFactory
        ->get('comment_multiple_delete_confirm')
        ->set($this->currentUser()->id(), $info);
      $form_state->setRedirect('comment.multiple_delete_confirm');
    }
  }

In this page you collect the comment id that you want to delete and made a redirect, and the comment deletion happens in comment.multiple_delete_confirm (ConfirmDeleteMultiple) that have the following code:

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $this->commentInfo = $this->tempStoreFactory->get('comment_multiple_delete_confirm')->get($this->currentUser()->id());
    if (empty($this->commentInfo)) {
      return $this->redirect('comment.admin');
    }
    /** @var \Drupal\comment\CommentInterface[] $comments */
    $comments = $this->commentStorage->loadMultiple(array_keys($this->commentInfo));
  ...
  }

So, we don't have a POST method from one form to another in Drupal 8 but this can be solved in this way.

8
  • This is pretty much what I posted above, no?
    – Kevin
    Apr 10, 2017 at 18:56
  • @Kevin Yes I see now that is very similar. Do you consider that I should delete my answer? I don't have problems doing this. Apr 10, 2017 at 19:01
  • @AdrianCidAlmaguer Thanks Its work well ,!! I need to send the variable as POST method ,How can i achieve this ?
    – vijoy
    Apr 11, 2017 at 6:10
  • @AdrianCidAlmaguer We have to use /path in Url $form_state->setRedirectUrl(Url::fromUri('internal:' . '/second_page', $params));
    – vijoy
    Apr 11, 2017 at 6:13
  • @vijoy I come from update my answer. Apr 11, 2017 at 17:12
2

One way you can do this is to add a query string with the value on it with setRedirect.

$form_state->setRedirect('second_page', ['name' => $form_state->getValue('name')]);

Then, read it in the next form:

// top of file
use Drupal\Core\Component\Utility\Xss;

$name = Xss::filter(\Drupal::request()->get('name'));

$form['name'] = array(
  '#type' => 'textfield',
  '#title' => t('Candidate Name:'),
  '#default_value' => isset($name) ? $name : '',
  '#required' => TRUE,
);

Note, I wouldn't do this for more sensitive information like credit card numbers or anything like that.

10
  • For sensitive info you could use config, which is the the equivalent of D7's variable_get and variable_set. Here is a nice tutorial and make sure mysettingname is unique for each user, like a session ID.
    – No Sssweat
    Apr 9, 2017 at 23:08
  • Yeah it really depends, especially if you're talking PCI complicate for cards, you really can't store that stuff anywhere, only in the transaction service.
    – Kevin
    Apr 9, 2017 at 23:11
  • that's very true.
    – No Sssweat
    Apr 9, 2017 at 23:13
  • thank you NO Sssweat, i want to get some arguments from one page and post those values in payment gateway (Worldline), how i can do this..?
    – vijoy
    Apr 10, 2017 at 5:07
  • 4
    @NoSssweat But every time variable_set() is used, the cache of the variables is cleared, causing the successive calls to variable_get() to read from the database. That is why is suggested not to use those functions for values that are only for a single user.
    – apaderno
    Apr 10, 2017 at 9:35
0

From 8.2 you can use hook_ENTITY_TYPE_prepare_form()

E.G.

function hook_ENTITY_TYPE_prepare_form(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Form\FormStateInterface $form_state) {
  if ($operation == 'edit') {
    $entity->label->value = 'Altered label';
  }
}

So assuming your second form is a node, you could do:

function submitForm(array &$form, FormStateInterface $form_state){
  drupal_set_message($this->t('@candidate_name! Wow! Nice choice! Thanks for telling us!', array('@candidate_name' => $form_state->getValue('candidate_name'))));

  $params['query'] = [
'candidate_name' => $form_state->getValue('candidate_name'),
  ];

  $form_state->setRedirectUrl(Url::fromUri('internal:' . 'second_page', $params));
}

function my_modules_node_prepare_form(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Form\FormStateInterface $form_state) {
  $candidate_name = \Drupal::request()->query()->get('candidate_name');
  if($candidate_name) {
    $entity->set('name', $candidate_name);
  }
}
-1

You can set the information in session if it is related to single user. Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.