22

I have a custom module that displays a form.

Upon submitting the form, I want to redirect the user to a different page.

How can I do that?

29

In the submit handler you do

Drupal 7:

$form_state['redirect'] = 'url';

Drupal 8:

$form_state->setRedirect('route', $args, $options);
$form_state->setRedirectUrl(\Drupal\Core\Url);
  • is there an alternative way of doing this? the forms I need to redirect are built with its own #submit handler (the submit handlers are not placed in my custom module), so I don't have access to the code. – Carlos Muñiz Jun 26 '11 at 14:16
  • @Charlie use form_alter to add your own. – googletorp Jun 26 '11 at 21:53
  • @Charlie if your for is mainly accessible by a link, put a destination parameter in the URL: /my-form?destination=node/123. – tostinni Sep 4 '11 at 4:25
  • Not working on D7, but I found something that does. Check my message below. – Ignacio Segura Postigo Sep 1 '14 at 16:41
  • I just want to say thanks for answering for D7, then coming back 5 years later to update the answer for D8. <3 – ant Feb 15 '18 at 21:37
16

It should be noted there are several triggers that may prevent a redirection:

  • $form_state['redirect'] === FALSE: If set, the form builder function or form validation/submit handler does not want a user to be redirected, which means that drupal_goto() is not invoked. For most forms, the redirection logic will be the same regardless of whether $form_state['redirect'] is undefined or FALSE. However, in case it was not defined and the current request contains a 'destination' query string, drupal_goto() will redirect to that given destination instead. Only setting $form_state['redirect'] to FALSE will prevent any redirection.
  • $form_state['no_redirect'] === TRUE: When set, the callback that originally built the form explicitly disallows any redirection, regardless of the redirection value in $form_state['redirect']. For example, ajax_get_form() defines $form_state['no_redirect'] when building a form in an AJAX callback to prevent any redirection. $form_state['no_redirect'] should NOT be altered by form builder functions or form validation/submit handlers.
  • $form_state['programmed'] === TRUE: means the form submission was usually invoked via drupal_form_submit(), so any redirection would break the script that invoked drupal_form_submit().
  • $form_state['rebuild'] === TRUE: means the form needs to be rebuilt without redirection.
6

For Drupal 7, I tried this on a custom module and it works. It can also be used in a theme:

function my_theme_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'contact_site_form') {
$form['#submit'][] = 'contact_form_submit_handler';
}
}

function contact_form_submit_handler(&$form, &$form_state) {
$form_state['redirect'] = 'thank-you-page-alias';
}

BTW, I found this snippet here: https://gist.github.com/postrational/5768796

3

To redirect to an external URL in Drupal 8, use the TrustedRedirectResponse class, as in the following code.

$response = new TrustedRedirectResponse('http://google.co.in');
$form_state->setResponse($response);
2

On D8 i did like this (but this won't work... see below):

/**
* Implements hook_form_FORM_ID_alter().
*/
function MYMODULE_form_FORM_ID_form_alter( array &$form, FormStateInterface $form_state, $form_id ) {

   // Force redirect to "/thankyou" page
   $url = "/thankyou";
   $path = \Drupal::service('path.alias_manager')->getPathByAlias($url);
   if(preg_match('/node\/(\d+)/', $path, $matches)) {
     $form_state->setRedirect('entity.node.canonical',
       array('node' => $matches[1])
     );    
   }

}

Edit/

I was missing that setRedirect/setRedirectUrl works AFTER the module is submitted, so this is my working solution on D8:

/**
 * Implements hook_form_FORM_ID_alter().
 */
function MYMODULE_form_FORM_ID_form_alter( array &$form, FormStateInterface $form_state, $form_id ) {
  $form['actions']['submit']['#submit'][] = 'MYFORM_redirect_handler';
}

function MYFORM_redirect_handler($form, FormStateInterface $form_state) {
  // Force redirect to "/sent"
  $dest_url = "/sent";
  $url = Url::fromUri('internal:' . $dest_url);
  $form_state->setRedirectUrl( $url );
}

Hope this could help

1

For drupal 7 if you want to redirect to url with params like someurl?param1=1&param2=2

$query = array(
  'param1' => '1',
   'param2' => '2',
 );
$form_state['redirect'] = array(
    'someurl',
    array(
      'query'    => $query,
      'fragment' => 'hash_fragment',
    ),
  );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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