the line

1053 // Set the form action to the node ID in case this is being displayed on the
1054 // teaser, subsequent pages should be on the node page directly.
1055 if (arg(2) != 'submission') {
1056 $form['#action'] = url('node/'. $node->nid);
1057 }

redirect to webform node to show validation errors instead of show them in the node.

Members fund testing for the Drupal project. Drupal Association Learn more


quicksketch’s picture

This is largely intentional that the form should go to the main node page once the form has been started. I can see the problems that we're getting into here by using arg() checking though. Perhaps a better way would be to check $node->is_teaser (or whatever that flag is), meaning that this redirect would only occur when viewing the teaser of a webform. What do you think?

meeotch’s picture

This fix seems to work (although I haven't tested teasers, since I'm not using them - but "is_teaser" does seem to be the right flag, based on my searching)... However, it does seem to "eat" arguments, as noted in the dupe issue That is:

or, in my current case (tabbed panel)

Apparently $_SERVER["REQUEST_URI"] is only set to the base URL, without the arguments. Does anyone know a method of getting the full URL with args, so I can stuff that into the #action?

quicksketch’s picture

meeotch, did you mean to post a patch with your last comment? seems to be eating them recently.

meeotch’s picture

Sorry - I should have been more specific. I meant the fix you mentioned in #1 works, in terms of causing webform not to redirect in the non-teaser case. No patch posted.

(However, as mentioned above, the URL arguments seem to be stripped when reloading to show validation errors. For now, I've moved my webform to a page that doesn't require arguments to function.)

ariflukito’s picture

2.14 KB

hi what is the status of this one
attached is what I'm using right now

sfa’s picture


marcmerz’s picture

quicksketch, would it be a problem to change line 1464 in webform.module (v like this:

   -$form['#action'] = url('node/'. $node->nid);
   +$form['#action'] = url(substr_replace($_SERVER['REQUEST_URI'], '', 0, 1));

This way one could easily call the webform like:

$node = node_build_content(node_load($node->nid));
print drupal_render($node->content);

and when there is an error the user gets back to the same page instead of the webform url path setting.

iNade’s picture

Is the patch in #5 working ?

iNade’s picture

Version: 5.x-2.x-dev » 6.x-2.6
quicksketch’s picture

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

This is not a duplicate of that issue quicksketch. I applied your patch and it did nothing for this issue.

teamA’s picture

Version: 6.x-2.6 » 6.x-2.9
Status: Closed (duplicate) » Active

In addition, I'm getting these failures when trying to apply the patch in #5.

Hunk #1 succeeded at 1129 (offset 203 lines).
Hunk #2 FAILED at 1372.
Hunk #3 succeeded at 1464 with fuzz 2 (offset 241 lines).
Hunk #4 succeeded at 1480 (offset 243 lines).
Hunk #5 FAILED at 1862.

So- I would say this is still active.

quicksketch’s picture

Status: Active » Closed (won't fix)

I'm not sure I want to change the current behavior. Setting the #action does exactly what it is intended to do: redirect the user to the dedicated Webform page after they have started filling out the form.

As the code comment states, this is what it's intending to do:

  // Set the form action to the node ID in case this is being displayed on the
  // teaser, subsequent pages should be on the node page directly.
  if (empty($submission)) {
    $form['#action'] = url('node/' . $node->nid);

If you're somehow embedding Webform in another node or in a block, you'll have to use hook_form_alter() and remove this change. Webform itself does not support embedding of Webforms on other pages.

varr’s picture

The following worked for me.

function MODULE_form_alter(&$form, $form_state, $form_id) {

  //- Redirect webform submissions if they are placed inside a panel
  if (module_exists('webform')) {
    if (isset($form['#theme']) && is_array($form['#theme']) && in_array('webform_form', $form['#theme']) && $form['#action'] != $_GET['q']) {
      $form['#action'] = '/'. $_GET['q'];

FYI, using the #theme array seemed to be the easy, most straight forward way to verify if we're dealing with a webform (using the $form array). If you're aware of a better way reply and let us know.

Also, keep in mind that you can insert the status/error messages into the same panel pane that the webform is on using the panel UI, which can create a more cohesive experience for the user.


ndf’s picture

Nice solution. It works as a charm, thank you!

Eronarn’s picture

Just a comment on the above for anyone else who finds this with Google - $_GET['q'] didn't work for the way I have my particular Drupal install setup. For me, $_SERVER['REQUEST_URI'] was instead the correct choice.

michal.k’s picture

What about this condition: if($form_id == 'example_form_id'){...}

tustind’s picture

If you want to return your errors on the same page that the webform is embedded in through Panels, you don't need to hack anything.

  1. On your webform, click to "Make available as a block" under advanced settings.
  2. Through Panels, instead of adding the form as a node, add the block version of your form that you just enabled.
  3. That's it. When used as a block, webforms is set to return errors on the containing page.
Manuel Garcia’s picture

Version: 6.x-2.9 » 6.x-3.x-dev
Status: Closed (won't fix) » Needs review
649 bytes

Let me reopen this please, and hear me out :)

For those confused with this issue, Changing the famous line 1534 in 6.x-3.x to $form['#action'] = base_path() . $_GET['q']; would break the intended workflow of multistep webforms where the first step is taken in a teaser display.

So the way around it is to embed the webform as a block, I'm I right?

In my opinion we are damaging our possibilities, just to save that workflow of coming from a teaser display... I really feel like we are hard coding the action for webforms in nearly every case.

Let me propose a solution, which is to only hardcode the form's #action if the webform is being displayed as a teaser, and let the fapi take care of the rest of cases, find the patch attached - what do you think?

screenage’s picture

For solution #19:
Also make sure if you have a multilangual site, and you have made translations for your webform,
you set the "Available as block" option for each translated version, and you add each webform block to your panel with the necessary visibility rules for the language.

quicksketch’s picture

Status: Needs review » Needs work

@Manuel Garcia that sounds like a good change to me. However your patch and what you've described are two different things. You described:

only hardcode the form's #action if the webform is being displayed as a teaser

But what's really happening in your patch is, "only hardcode the form's #action if the webform has been configured to display the full form in the teaser". This means that the hard-coded #action would still take place if the user had checked the box for "Show complete form in teaser", even if they were showing the full version of the node. We need to check $node->is_teaser or $node->display_mode (in D7). I'm actually not sure what these variables are called, they may not be passed into webform_client_form() at all right now.

Manuel Garcia’s picture

@quicksketch, you're right the variables are not available in the $node object right now, there's no way to check wether the node is being displayed as a teaster... can you think of a way to find that out?

quicksketch’s picture

Something else to consider here also: #1033090: Multiple step form - first in block the rest in node.

can you think of a way to find that out?

You could insert into $node->webform['is_teaser'] during hook_nodeapi($op = 'view') before the call to drupal_get_form('webform_client_form').

quicksketch’s picture

The changes committed in #1033090: Multiple step form - first in block the rest in node should make this patch a little easier to implement now. There is a single variable for $pages_in_node that currently defaults to TRUE. Once we get the teaser information into the form rendering process, we can set $pages_in_node = $node->webform['is_teaser'] by default instead of just the straight-up TRUE we're using now.

doublejosh’s picture

Status: Needs review » Needs work

Directly related?
When using Form Block (upon an error, or multi-step forms) the /action keeps the user on the same page the form was on. Can imagine this *might* be the intended behavior sometimes, but in all my cases I'd want the user to proceed to the webform node to finish things up. Hence thinking this is the right thread.

Perhaps there should be an admin setting for what /action to take when the form is begun anywhere other than the webform full node page? This would cover both teaser situations and Form Block uses.

Manuel Garcia’s picture

Status: Needs work » Needs review
1.64 KB

@quicksketch those changes indeed make this patch a lot simpler

Find attached what you suggest as a patch, as far as I've tested it's working perfectly =)

quicksketch’s picture

@Manuel Garcia: Your patch will only work for D6. Could you see what's needed in D7?

Manuel Garcia’s picture

Status: Needs work » Needs review
1.34 KB

Sure thing, here it is. Pretty much the same thing.

quicksketch’s picture

The D7 patch uses is_page instead of is_teaser, looks like the two patches would have opposite effects. :\

Anyway I really just need to test them out and see what the overall effect is.

Manuel Garcia’s picture

Erm... you're totally right... I'll just blame this on today being Monday if that's ok.

The attached patch actually makes sense now for d7.

quicksketch’s picture

Ha, thanks. In D7, you'll have to use $view_mode to determine if it's a teaser. Since there isn't a $teaser (or $page) variable in D7's hook_node_view().

Manuel Garcia’s picture

Yup, but we're already doing that and setting up a $teaser variable earlier inside hook_node_view:

  // Set teaser and page variables a la Drupal 6.
  $teaser = $view_mode == 'teaser';
  $page = arg(0) == 'node' && arg(1) == $node->nid;
quicksketch’s picture

2.53 KB

Using @Manuel Garcia's patch as inspiration, I've made this patch which removes loading of the block settings from the webform_client_form() function. Instead of adding an odd property called $node->webform['is_teaser'] that affects the #action property, this patch takes a direct approach of just letting code set $node->webform['action'] to any arbitrary value. Then node_view() sets this property for teasers and webform_block_view() sets it for blocks. The approach is both direct and allows extra flexibility for other modules extending Webform.

How does this look to you guys?

quicksketch’s picture

2.54 KB

Updated version that only sets the $action property for teasers and not for full nodes.

quicksketch’s picture

Status: Needs review » Fixed
2.65 KB

Tested this out again today and it all works well. Ported to D6 in this patch and committed patches to both branches.

Manuel Garcia’s picture

Awesome, thanks quicksketch.

Sorry I never got around to testing the latest patch!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.