First off - awesome module, we use it on nearly every site we build. Great job, and thanks for keeping it current!

I have a Webform enabled as a block, and assigned to the sidebar_left region in the blocks system. I am actually using the region within the content area of a node as opposed to the page template, so have the following code in my theme_preprocess_node function:

$vars['sidebar_left'] = theme('blocks', 'sidebar_left');

The Webform is showing up and submits fine under normal circumstances, but if you have validation errors it redirects to the main Webform page instead of staying on the page it was a block on.

Am I missing a setting somewhere, or is there some context that is not getting set in Webforms at the theme_preprocess_node level that is screwing up the validation redirect? Any help would be greatly appreciated!

CommentFileSizeAuthor
#21 webform.png123.27 KBLiaz

Comments

arpieb’s picture

OK, just discovered that after changing the Webform's Redirection location to No redirect (reload current page) at the request of QA that it's also redirecting to the form page on from submission...

johnxer’s picture

I have the same problem.

3cwebdev’s picture

Same issue.

arpieb’s picture

Here's a fix that we came up with, placed in a hook_form_alter() callback for our forms:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  switch ($form_id) {
    case XXX:
      if (!empty($form['#parameters'][1]['post'][REDIRECT_OVERRIDE])) {
        $redirect_override = $form['#parameters'][1]['post'][REDIRECT_OVERRIDE]; 
      } 
      else {
        // Note we're tacking on a query arg for GA trackability - not required
        $redirect_override = serialize(array(('node/' . arg(1)), 'form=' . $form_id));
      }
      
      // Set a hidden field for the parent node and add submit handler to handle redirect
      if (empty($form_state['values'][REDIRECT_OVERRIDE])) {
        $form[REDIRECT_OVERRIDE] = array(
          '#type' => 'hidden',
          '#value' => $redirect_override,
        );
      }

      // Add our custom submit handler LAST so that Webforms doesn't overwrite it with its redirect behaviors
      array_push($form['#submit'], 'mymodule_webform_redirect_override');
      break;
  }
}

The registered submit handler from above is:

function mymodule_webform_redirect_override($form, &$form_state) {
  if (!empty($form_state['values'][REDIRECT_OVERRIDE])) {
    $form_state['redirect'] = unserialize($form_state['values'][REDIRECT_OVERRIDE]);
  }
}

So far it looks like it works great for our specific cases, but your mileage might vary...

3cwebdev’s picture

Thanks for the code. I have tried it but it doesn't seem to work for me. I have verified that the custom submit handler is getting added to end end of the '#submit' array but it is not being called for some reason. It appears that the submit handler is simply being ignored and the webform page gets loaded instead of the block the same as before. Any idea what could be wrong?

// Add our custom submit handler LAST so that Webforms doesn't overwrite it with its redirect behaviors
      array_push($form['#submit'], 'ccc_custom_code_webform_redirect_override');
wolfmarter’s picture

I have the same problem and also for the confirmation page

arpieb’s picture

@setfree - mind posting your code (the hook_form_alter and submit handler) so we can see if maybe there is something in it that might not be getting picked up properly by the FAPI processing code? If you don't feel comfortable posting publicly, feel free to shoot it to me via PM and I would be more than happy to check it out...

3cwebdev’s picture

Sure, thanks for offering to assist.

The complete code is below. I have tested and verified that the form ID is correct and that the new submit handler is being added to #submit as expected but the submit handler function is not being called.


function ccc_custom_code_form_alter(&$form, &$form_state, $form_id) {
  
  switch ($form_id) {
    case 'webform_client_form_8':
      
      if (!empty($form['#parameters'][1]['post'][REDIRECT_OVERRIDE])) {
        $redirect_override = $form['#parameters'][1]['post'][REDIRECT_OVERRIDE]; 
      } 
      else {
        // Note we're tacking on a query arg for GA trackability - not required
        $redirect_override = serialize(array(('node/' . arg(1)), 'form=' . $form_id));
      }
      
      // Set a hidden field for the parent node and add submit handler to handle redirect
      if (empty($form_state['values'][REDIRECT_OVERRIDE])) {
        $form[REDIRECT_OVERRIDE] = array(
          '#type' => 'hidden',
          '#value' => $redirect_override,
        );
      }

      // Add our custom submit handler LAST so that Webforms doesn't overwrite it with its redirect behaviors
      array_push($form['#submit'], 'ccc_custom_code_webform_redirect_override');
      
      break;
  }
} 


function ccc_custom_code_webform_redirect_override($form, &$form_state) {
  
  if (!empty($form_state['values'][REDIRECT_OVERRIDE])) {
    $form_state['redirect'] = unserialize($form_state['values'][REDIRECT_OVERRIDE]);
  }
}
arpieb’s picture

@setfree, your code looks fine to me... Only thing I can think of - and please don't take this as being condescending as it's not meant as such - did you define the constant REDIRECT_OVERRIDE in your code?

I'm looking at the snippets and just realized I was using a defined PHP constant from my module (I tend to do that for strings as well as numeric values in an attempt to reduce typo errors - blame it on my C/C++ roots). If that value is not defined, all the $form and $form_state array assignments using that as a key will fail. In fact, if you have strict PHP error reporting set, it should fail spectacularly. ;) Alternatively, you could just replace that constant with a string key instead of using a constant like I did - all up to your coding style.

If you had that covered already, then I'd say drop a drupal_set_message call at the top of the submit callback to dump out the $form_state array and we can see if something is arranged differently from what I was getting. Note I am running Webforms 6.x-3.14 on a D6.22 installation, no idea how this code might work on a different release of Webforms OR Drupal.

Let me know what you find out and maybe we can figure out how to get that workaround to, well, work for you!

3cwebdev’s picture

Thanks for your help with this. I really appreciate it! You were correct in pointing out the constants, I had not defined them. I replace the constant with the string, "redirect_override", but am still having the same issue. The submit handler is not being called even though the callback appears to get added to submit correctly. See snippet:

  [#submit] => Array
        (
            [0] => webform_client_form_pages
            [1] => webform_client_form_submit
            [2] => ccc_custom_code_webform_redirect_override
        )

However, when I place a watchdog() function at the top of the submit callback, I see that it is never called. I have looked over the code and flushed the caches and have no idea why ccc_custom_code_webform_redirect_override() never gets called.

Any ideas what would cause this?

Complete Module


function ccc_custom_code_form_alter(&$form, &$form_state, $form_id) {
  
  switch ($form_id) {
    case 'webform_client_form_8':
      
      if (!empty($form['#parameters'][1]['post']['redirect_override'])) {
        $redirect_override = $form['#parameters'][1]['post']['redirect_override']; 
      } 
      else {
        // Note we're tacking on a query arg for GA trackability - not required
        $redirect_override = serialize(array(('node/' . arg(1)), 'form=' . $form_id));
      }
      
      // Set a hidden field for the parent node and add submit handler to handle redirect
      if (empty($form_state['values']['redirect_override'])) {
        $form['redirect_override'] = array(
          '#type' => 'hidden',
          '#value' => $redirect_override,
        );
      }

      // Add our custom submit handler LAST so that Webforms doesn't overwrite it with its redirect behaviors
      array_push($form['#submit'], 'ccc_custom_code_webform_redirect_override');      
      
      break;
  }
} 


function ccc_custom_code_webform_redirect_override($form, &$form_state) {
   watchdog('test','okay');
  if (!empty($form_state['values']['redirect_override'])) {
    $form_state['redirect'] = unserialize($form_state['values']['redirect_override']);
  }
}
BillyMG’s picture

Thanks for that code. I've managed to get a working custom module for my code, but mine is Drupal 7. It's very similar to your code, but with the D7 changes. I don't know if it would work in a subdirectory, but that should be a very easy fix. If we could just get these changes built into the module, setfree might not have to worry about it. I took a look at his code and nothing seemed immediately wrong.

Drupal 7 Module:
CUSTOM_MODULE: Name of your custom module
WEBFORM_FORM_ID: id of the Webform

function CUSTOM_MODULE_form_alter(&$form, &$form_state, $form_id) {
  switch ($form_id) {
    // Custom redirection for any webforms you choose
    case 'WEBFORM_FORM_ID':
      // Set a hidden field for the parent node and add submit handler to handle redirect
      if (empty($form_state['values']['redirect_override'])) {
        // The redirect needs a normal path
        $form['redirect_override'] = array(
          '#type' => 'hidden',
          '#value' => serialize($_GET['q']),
        );
        // But the action needs a url() path if errors happen
        $form['#action'] = _CUSTOM_MODULE_get_current_path();
      }
      // Add our custom submit handler LAST so that Webforms doesn't overwrite it with its redirect behaviors
      array_push($form['#submit'], '_CUSTOM_MODULE_webform_redirect_override');
     
      break;
  }
}

// Custom redirect submission for Webforms
function _CUSTOM_MODULE_webform_redirect_override($form, &$form_state) {
  if (!empty($form_state['values']['redirect_override'])) {
    $form_state['redirect'] = array(unserialize($form_state['values']['redirect_override']));
  }
}

// Get the proper path for the current page
function _CUSTOM_MODULE_get_current_path() {
  $url = drupal_lookup_path('alias', $_GET['q']);
  if (empty($url)) {
    $url = $_GET['q'];
  }
  // Front-page url should be empty
  if ($url == "front") {
    $url = "";
  }
  $url = url($url);
  return $url;
}
favrik’s picture

@BillyMG Just FYI, your code works fine on D6. Thanks! :)

3cwebdev’s picture

@BillyMG, worked perfect on my D6 install too! Thanks :)

quicksketch’s picture

This is actually a bug in Webform. Separately reported over here: #1337784: Selecting "No redirect" does not reload current page..

quicksketch’s picture

Status: Active » Closed (duplicate)
finex’s picture

@BillyMG: works fine on D7... thanks :-)

fbreckx’s picture

@BillyMG: can u tell me where to implement this code? I'm relatively new to Drupal (and most definitely to php).

arpieb’s picture

@fbreckx - The code is intended to be placed in a custom module as it leverages several Drupal callbacks related to forms. If you are not familiar with building modules, I would strongly recommend reading the docs here - Module developer's guide.

joecanti’s picture

I couldn't get this to work on D7 - probably through my own mistake.

A nice little fix for this is to use the clientside validation module - keeps the validation errors on the same page even if in a block, in a panel or wherever, and puts them next to the form.

Joe

fbreckx’s picture

Okay, thanks! I'll certainly read that information.
In the meanwhile I solved the problem using client side validation.

Liaz’s picture

Version: 6.x-3.14 » 6.x-3.17
StatusFileSize
new123.27 KB

For drupal 6 and webform 3.17 the #11 works indeed perfectly - Thanks a lot @BillyMG !

Little modification for my personnal case: I wanted that the error page reloads on the current page where I have my form in a block, but I wanted the confirmation page to follow the redirection I set in the webform redirection location. For that, I just had to not call the redirect_override in the form submit but only the get_current_path in the form action.
So for my purpose the module is then :

<?php
function tmc_patch_webform_form_alter(&$form, &$form_state, $form_id) {

  switch ($form_id) {
    // Custom redirection for any webforms you choose
    case 'webform_client_form_164':
      // Set a hidden field for the parent node and add submit handler to handle redirect
      if (empty($form_state['values']['redirect_override'])) {
        // The redirect needs a normal path
        $form['redirect_override'] = array(
          '#type' => 'hidden',
          '#value' => serialize($_GET['q']),
        );
        // But the action needs a url() path if errors happen
        $form['#action'] = _tmc_patch_webform_get_current_path();
      }
     
      break;
  }
}

// Get the proper path for the current page
function _tmc_patch_webform_get_current_path() {
  $url = drupal_lookup_path('alias', $_GET['q']);
  if (empty($url)) {
    $url = $_GET['q'];
  }
  // Front-page url should be empty
  if ($url == "front") {
    $url = "";
  }
  $url = url($url);
  return $url;
}

?>

Hope it will help some :)
Liaz

banense’s picture

Very simple,
go to admin/block edit your webform block and check "Show all webform pages in block" and all errors display in block not in node.
Regards

sozonov’s picture

Cool!

quirogapj’s picture

@banense nice and simple way to fix this! Thanks for share. Regards.

robriley78’s picture

There it is!! Thanks.

dco’s picture

Nice trick banense, also works in D7 !

This checkbox description should be more explicit I think...

espurnes’s picture

#11 works for me in D7.18 and webform 7.x-3.18.

Thank you!

But the same functionality is achieved with #22. No need to create a custom block.

justindodge’s picture

#22 works great for me as well.

For a code solution that does this for all webform blocks, we used this snippet (D7) inside a hook_form_alter, it's a little simpler than #11. The redirect for success will inherit the settings setup in the webform.

//inside hook_form_alter...

//If we have a webform block, make it submit on the page we're on
if (!empty($form['#node']->webform_block)) {
  //Set the action to blank string so form API fills in default of the current page
  $form['#action'] = '';
}
vergil’s picture

hey everyone i am a newbie to drupal i am from Jamaica and i am having the same problem here but so for in my studies i only know Html and Css so this PHP stuff i am kinda clue less... wish i had a tooter

hockey2112’s picture

#22 did it for me. Thanks!

julescone’s picture

Legend banese! (#22) I thought it might be nice to know that a little answer you posted a year ago is still of use to someone!

I had overlooked that checkbox in my webform block configuration.

Solved the 'redirects to the webform node' on validation error, along with another issue I was having with passing info about the node with the webform embedded in it.

On that note, it must be time for lunch. :)

Cheers, Jules

nitesh sethia’s picture

Assigned: Unassigned » nitesh sethia

#22 is working fine and was able to fix this issue up.

aniket.mohite88’s picture

Banense you are a legend.
That was a really great solution, exactly what i was looking for.

skribbz14’s picture

Client Side Validation worked great to fix this problem for me.

madanzes’s picture

#22 works for me too. thanks

batandwa’s picture

#22 thumbs up.

dagomar’s picture

Related issue on 7.x-4 with patch:
#2158261: Webform block redirects to page by default

truyenle’s picture

#22 work for me also.

shahidbscs’s picture

Issue summary: View changes

#22 @banense, Just Awesome

timme77’s picture

#22 is just perfect!

peterx’s picture

Added #22 to the following documentation on Webform in a block.
https://www.drupal.org/node/1447436

谢艳’s picture

Here is my code, VERSION: 7.x-3.20
Webform as block staying on page after validation errors and allow no redirect

function mymodule_form_alter (&$form, &$form_state, $form_id){
  switch ($form_id) {
      case 'webform_client_form_27':
      $form['#action'] = url(drupal_get_path_alias($_GET["q"]));
  }
}
m1n0’s picture

#22 Solves the issue, thanks!

aiphes’s picture

#22 save me after finding the checkbox on /admin/build/block/configure/webform/client-block-ID#block_settings