Basically, I have a link which, upon clicking, will show a popup form, which after submission, I want the original page to be redirected to another page.

These are the things I have done:

1. Putting a <div> wrapper around the "print $content" and updating the id of that div in the theme settings
2. Added a link in my module -->
(i) popups_add_popups();
(ii) l("Test", "/myform", array('attributes' => array('class' => 'popups-form')));
3. Wrote a customized form, which has just a dummy text input field, and a submit button.
4. Inside the form_submit() function, the last statement is --> $form_state['redirect'] = 'admin';

Observations during testing:
1. The form popups as it should be.
2. Upon submission, the original page doesn't get redirected to the url I wanted.

I have permutated the options (i.e. changing the class to popups, popups-form, popups-form-reload; updateSource: {'final'} ).
But I still don't have the desired results.

Can anyone point me in the right direction?

Thank you in advance.

Comments

wik’s picture

same here...

gsvitak’s picture

subscribing

angel.h’s picture

same here

yfreeman’s picture

Running into the same problem.

It seems to me that the submission of the form occurs through AJAX (XMLHTTPRequest object). is such instances the redirect headers don't get processed.

One way around it which I'm trying to exploit is to get the form to submit through the regular browser post process not through ajax. I don't know if Popups supports this.

Another way around would be to specify somewhere in code when the form is successful where the browser should redirect, in the returning Ajax code....

I think the reason why the form is submitted via AJAX is that if there are validation errors the user will be confused, due to the change of the page, because the next page won't be displayed in the popup.

yfreeman’s picture

Ok, so who wants to redirect after submitting a form via popups?

Turns out that it is not easy at all.

The popups api module is well written and well thought out. Seems like some of the design elements makes it difficult to redirect the form to the $form["redirect"]

Why doesn't/shouldn't $form["redirect"] work in Popups?
1. If it did, then it would not redirect the page but the content in the popup. The forms are submitted through the Ajax, redirection for the browser does not work through ajax, Redirection during an ajax call will only effect the data return in the ajax request, not the whole browser page.
2. Popups need to know that the form was submitted without any validation errors. so it overwrites the $form["redirect"] mechanism (more details below)
3. The way Popups know that everything was successful is if it's own overriding mechanism was completed.
4. Popups need to know if the form was successful, so it should reload the page, and validation errors shouldn't appear outside the popup.

The way around it is
1. give the popup link the class ="popups-form-reload". this will force the original page to reload. So how do we get it to load to the page we want. You may ask, it will load the originating page not the $form["redirect"] page?!??, keep reading
2. we create a module that will intercept the page from reloading and force the user to go to a page we want. we will do this with the modulename_init() implementation of the hook. (I had originally created a complete module that can perform certain actions such as reloading the page, but this does not require any saving in the database or anything.)
What the hook looks like is this

function modulename_init(){
  if(isset($_SESSION["form_redirect"])){
    $path = $_SESSION["form_redirect"]; // we will set this session variable when the form is submitted. 
    unset($_SESSION["form_redirect"]); // unset this variable so we don't get an infinite loop
    drupal_goto($path); // redirect!
  }
}

3. in the submit handler of your form you put the following code

function yourformname_submit($form, &$form_state){
    // your code to run when form is submitted
// blah blah blah, ok, finished processing form....

    $path = $form_state["redirect"]; // or whatever url you want to redirect
    if(isset($_SERVER["HTTP_X_REQUESTED_WITH"])){ // this tell use that it was submitted through XMLHTTPRequest which popup sets
        $_SESSION["form_redirect"] =  $path; // set the session variable so on the next page load we will intercept the load and force it to redirect to this page
        if(function_exists("popups_render_as_json") && isset($_REQUEST["destination"])){ // just make sure that we have the popups module installed, and it has overridden our $form["redirect"]
           unset($_SESSION['page_override']); // remove this or the popups module will intercept the output and render it in JSON
           return drupal_json(array(
            'title' => drupal_get_title(), // set what ever you want
            'messages' => theme('status_messages'), // what ever you want
            'path' => $_REQUEST["destination"], // this fakes the form completion for popups api - it checks this variable to see if the form was correctly submitted.
            'content' => "",
          ));
        }
    }
  }

And it should work!

Why do we have to do all this?

Popups API checks the returning data of the form if it comes from the same URL as where the popup originated from
popups.js Line 422+

var done = (data.path === Drupal.settings.popups.originalPath) || (data.path === options.forceReturn);
 if (!done) { // Not done yet, so show new page in new popups.Drupal.popups.removeLoading();
Drupal.popups.openContent(data.title, data.messages + data.content, options, element);
}
else { // Done. 

So what step #3 does it fakes the path to think it's coming from the originating page.
Next we need to send data to the browser so drupal's form redirect won't be run. Once data is send any headers sent afterward are discarded.
If we let the drupal_redirect_form() run (fully), then our hook_init() function will run inside the popup and the Popups API will not yet know that the form was completely submitted, and will load the data sent back to the browser from drupals form redirect. and Popups API will never reload the page like we want it to.

How does Popups api try guarantee that the original page will be reloaded? it send over the "&destination=original_page" in the POST method action url.
this basically overrides the whole form redirect mechanism, So you can set values to $form["redirect"] all you want it will get overridden by $_REQUEST["destination"]
see http://api.drupal.org/api/function/drupal_goto/6 for more info....

Somewhere $_SESSION['page_override'] get set, this notifies popups that the pages should be rendered in json. this is not unset before we run our stuff so we need to manually remove it.

mtsanford’s picture

Subscribe.

It would be really nice to have support for this in the popups API module.

kristen pol’s picture

Someone was able to redirect from node add page to the new node page here:

http://drupal.org/node/455894

I imagine something similar could be done for other redirects.

Kristen

JGO’s picture

This sucks, I want my popup to be able to redirect to another page.

Also a page reload doesn't seem to work properly anymore when I use a form inside a popup with captcha verification.
As soon as the message for the wrong captcha wants to be show, the whole popup just closes. Anyone else experienced this :(

a_lawry’s picture

Here is how I am redirecting. Still testing this approach.

I set a session variable to say the form has been submitted (for me it is the user logging in and I am using Rules to do it but you should be able to do the same in your form submit function). The hook_init() in my custom module then checks for that session variable and the 'page_override' variable set by popups API.

So it is waiting until page_override is no longer set and then doing the redirect. When the popup form is submitted it does the standard behaviour and reloads the current page but this code then causes the redirect to happen.

function my_module_init() {
  global $user;

  if (isset($_SESSION['just_logged_in'])) {
    if (!$_SESSION['page_override']) {
      unset($_SESSION['just_logged_in']);
      drupal_goto('game');
    }
  }
}
oxford-dev’s picture

I got #9 to work where all others failed but there is a very important step missed out if you want to try it.

In for form_submit function you must remember to set $SESSION['just_logged_in'] = true otherwise it won't work.

ruslan.muradov’s picture