Hello,

I'm using this module for a central feature on one of my projects and am very satisfied with it. I did everything I wanted to until now.

I need to create a button to save the form and then go to the last step. To achieve this, I put the following code in mymodule_form_alter :

 $form['buttons']['last'] = array(
                    '#type' => 'submit',
                    '#value' => 'Save and go to last step',
                    '#submit' => array('last_step'),
                    '#weight' => -1000,
                );

Whatever I tried, a click on this button always triggers the behaviour of another button, most frequently the 'delete' one.

I guess it has to do with something I don't understand in the form API, but I can't guess what.

I would greatly appreciate any bit of information.

Thanks

Comments

vkareh’s picture

I'm interested in seeing what the code looks like for your function last_step().

A while ago I did something similar for a client. At that time, the way the multistep module was designed, I could not find a better way than adding this to the submit function:

if ($form_state['clicked_button']['#id'] == 'edit-next') {
  if ( ** condition to skip steps **) {
    $_REQUEST['destination'] = 'node/' . $node->nid . '/edit/' . $last_step;
  }
}

It's not very elegant, but it worked. It makes me think that there should be a hook_multistep_set_next_step() or something like that in this module.

Countzero’s picture

Hello,

I solved my issue in the meantime and forgot to update, sorry.

My function didn't work because form_alter was called twice when the form was submitted, so I had to test where I was in the submit process otherwise the form began to behave strangely.

My last_step function is a rewrite of next_step included in the module :

function last_step($form, &$form_state) {
  node_form_submit($form, $form_state);
  $type = $form_state['values']['type'];
  $step = 5; //  My form has 6 steps
  $nid = $form_state['values']['nid'];
  // Update the multistep table.
  multistep_update_status($form_state, 'submitted', $step);
  $form_state['redirect'] = array('node/' . $nid . '/edit/6');
}

And I had to test the context in hook_form_alter:

if ($_GET['from'] == 6) {
     $form['buttons']['save']['#submit'] = array('last_step');
     $form['#redirect'] = array('node/' . arg(1) . '/edit/6');
}

The 'from' variable was added to the URL to 'remember' how I got there. I guess I could have used the 'destination' parameter, but was afraid of interfering with something else and was urged.

Not very beautiful code if you ask me, but it works.

vkareh’s picture

Title: Adding a button to go to given step » Adding a hook to go to a different step after submission
Version: 6.x-1.4 » 6.x-1.x-dev
Category: support » feature

Awesome! I'm glad you solved it.

Still, I think a hook_multistep_set_next_step() would be very valuable for users in this situation. I'll mark this as a feature request for the development version.

Countzero’s picture

It's clear it would have simplified my life for a while ;-).

My solution lacks a tight integration with the logic of your code, because I didn't have time to study it for long. For this kind of problems it's clear the hook would somewhat 'force' developpers to adhere more closely to the internal logic of the module, which may or may not be a good thing.

Anyway, it scaled good enough to at least allow an unexpected behaviour, which not every module does.

Again, thanks for your work.

vkareh’s picture

Status: Active » Fixed

Added hook_multistep_set_step() to the latest development snapshot. Here's the documentation with an example:

/**
 * Change which step should the form redirect to upon submission.
 *
 * If there are multiple implementations of this hook, the last one to be run
 * is the one that will be used. Check your module weights!
 *
 * @param $form_state
 *   The form's form state.
 * @param $step
 *   The current step being submitted.
 * @param $action
 *   The button that was used for submission.
 *
 * @return
 *   The step to which the form should be redirected. Only return an integer.
 */
function hook_multistep_set_step($form_state, $step, $action) {
  switch ($action) {
    case 'previous':
      if ($step > 1 && $form_state['values']['go_to_first_step'][0]['value'] == 'yes') {
        return 1;
      }
      break;
    case 'next':
      $last = variable_get('multistep_steps_' . $form_state['node']['type'], 0);
      if ($step < $last && $form_state['values']['go_to_last_step'][0]['value'] == 'yes') {
        return $last;
      }
      break;
  }
} 

Status: Fixed » Closed (fixed)

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

roball’s picture

This new hook is working fine, thanks! Exactly what I needed for one project.

Do you think this wiill go into 6.x-1.6 anytime soon?

fnikola’s picture

how does this hook get exectured?

roball’s picture

In your own module MY_MODULE, implement the hook_multistep_set_step(), like this:

/**
 * Implementation of hook_multistep_set_step().
 * Is triggered when the Previous, Next or Done button of the multistep form has been submitted
 *   (either by clicking on it or by pressing ENTER on the keyboard).
 * http://drupal.org/node/791620#comment-3704222
 * Requires multistep module version >= 6.x-1.x-dev (2011-Feb-25)
 */
function MY_MODULE_multistep_set_step($form_state, $step_submitted, $action) {
  if ($action == 'done') {
    // Form has been completed
    $nid = $form_state['node']['nid'];
    drupal_set_message(
      t('Congratulations! The input form of node ID') . ' ' . $nid  . ' ' .
      t('has been completed.'),
      'status',
      FALSE
    );
  }
}
roball’s picture

@fnikola: Did you try that?