I have created a form. I want to submit the form values, validate them, then confirm that the user wishes to proceed. I place a drupal_execute('confirmation_form', $form_values) in my submit hook, and in the 'confirmation_form' I execute "confirm_form". But, it doesn't work. I don't get a confirmation form: the code execution cycles through to conformation_form_submit.

form()
Input values

form_validate()
validate values

form_submit()
Now, I want to confirm that the user wants to continue. If I call a form from within this submit hook that executes a confirm_form, the confirm_form() function doesn't work

form_confirm()
Execute confirm_form() doesn't work.

Code example:

function og_user_roles_register_submit($form, &$form_state) {
  global $user;
 
  if ($user->uid) {
    $regcode = $form_state['values']['og_user_roles_regcode'];
    $gid = og_user_roles_gid_from_regcode($regcode);
    if ($gid > 0) {
      $node = node_load($gid);
      drupal_execute('og_user_roles_register_confirm', $form_state, $node, $regcode);
    }
  } else {
    drupal_access_denied();
  }
}

/**
* Form builder; Builds the confirmation form for adding user to group using regcode.
*
* @ingroup forms
* @see og_user_roles_register_confirm_submit()
*/
function og_user_roles_register_confirm(&$form_state, $node, $regcode) {
  $form = array();
  $form['#node'] = $node;
  $form['#regcode'] = $regcode;
  return confirm_form($form, t('Are you sure you want to join this group %title?', array('%title' => $node->title)), 'node/'. $node->nid, t('This action can only be undone by unsubscribing from the group once joined.'), t('Delete'), t('Cancel'), 'og_user_roles_register_confirm');
}
// Confirmation form does NOT display.  Code continues to successfully execute
// og_user_roles_register_confirm_submit()
//
// It's like if a form is called from a successful submit, then it's subsequent submit hook is
// automatically successful as well.

In all the working examples of confirm_form() I've seen in Drupal 6.x, I do not see an example where it is called from a form submit hook.

I want to enter values, validate those values, then confirm that the user wishes to proceed. How do I do that using confirm_form() (if that's even possible)?

Comments

Steven Jones’s picture

Category: bug » support

Calls to drupal_execute submit the form you pass as a parameter, so yes, you will jump to the submit handler of the confirmation form. In your initial form you'll probably want to redirect to another page (passing the values to it somehow) and render your confirmation form. Or you could do a multistep form with confirmation as the last step, but that might get REALLY ugly.

SomebodySysop’s picture

Thank you. What I did to get this to work was to put the confirm_form into a function that is called as a menu callback:

    $items['og/regcode/confirm/%'] = array(
      'title' => 'Confirm registration code',
      'page callback' => 'drupal_get_form',
      'page arguments' => array('og_user_roles_register_confirm'),
      'access callback' => 'user_access',
      'access arguments' => array('use registration codes'),
      'weight' => 10,
      'type' => MENU_LOCAL_TASK,
     ); 

So, in my submit hook, I do a "drupal_goto" (as opposed to drupal_execute or drupal_get_form) and put the key variable in the argument as part of the url. This works. But, seems to me that it would be much easier to be able to call another form and pass the form variables from the submit hook (as I was attempting to do).

The reason I labled it as a bug was because neither drupal_execute nor drupal_get_form (which is suppose to render the form) worked. To me, it seems like I should be able to take the form values that I just validated, and send them to another form for further confirmation.

Here's what I mean:

The form in question is og_user_roles_register_confirmRight now, what works is to do a drupal goto from the submit hook:

function og_user_roles_register_submit($form, &$form_state) {
  global $user;
  
  if ($user->uid) {
    $regcode = $form_state['values']['og_user_roles_regcode'];
    $gid = og_user_roles_gid_from_regcode($regcode);
	if ($gid > 0) {
         drupal_goto('og/regcode/confirm/'.$regcode); // this is menu callback for og_user_roles_register_confirm()
	}
  } else {
    drupal_access_denied();
  }
}

What I believe I should be able to do (but cannot) is do a drupal_get_form (which should render the confirm_form) and pass the form values that I have already validated to a confirmation screen:

function og_user_roles_register_submit($form, &$form_state) {
  global $user;
  
  if ($user->uid) {
    $regcode = $form_state['values']['og_user_roles_regcode'];
    $gid = og_user_roles_gid_from_regcode($regcode);
	if ($gid > 0) {
         drupal_get_form('og_user_roles_register_confirm', $form_state); 
	}
  } else {
    drupal_access_denied();
  }
}

Shouldn't the latter work as well? If not, why?

kobnim’s picture

subscribing

aacraig’s picture

I had the same issue. The confirm workflow could certainly be better documented, especially for cases where you don't use the standard hooks.

I've implemented your solution as well, and it's got the job done. Thanks for posting your solution!

aacraig’s picture

Just to follow up on my own experience with this, I've added a second drupal_goto call at the end of the function that gets confirmed, which returns the user to the original page.

One nice side effect of this workaround is that the action to be confirmed (in my case, deleting some configuration settings) now appears as a child of my module in Admin Menu :)

sun’s picture

Status: Active » Closed (won't fix)

Form submit handlers are not supposed to output a new form, especially not a confirm_form(), which is supposed to live on a separate menu callback.

And, drupal_execute() programmatically submits a form, which is definitely not what you want when talking about confirm_form().