Hello.

I'm currently writing a CTools' content types plugin using a multistep form.

I would like to implement the 'back callback' property of these forms. In fact I couldn't find any valuable documentation about this property.

Either way, I found some weird things in the code :

  • The back button (which name is 'previous') has a '#wizard type' set to 'next' (line 244 of wizard.inc) :
    $form['buttons']['previous'] = array(
      '#type' => 'submit',
      '#value' => $form_info['back text'],
      '#next' => $form_state['previous'],
      '#wizard type' => 'next',
      '#weight' => -2000,
      '#skip validation' => TRUE,
      // hardcode the submit so that it doesn't try to save data.
      '#submit' => array('ctools_wizard_submit'),
      '#attributes' => $button_attributes,
    );
    

    So I think the 'back callback' will never be called.

  • The only way I found to "overload" the 'back callback' property is (line 442 of wizard.inc) :
    // set button callbacks
    $callbacks = array(
      'back callback' => '_back',
      'next callback' => '_next',
      'return callback' => '_return',
      'cancel callback' => '_cancel',
      'finish callback' => '_finish',
    );
    
    foreach($callbacks as $key => $callback) {
      // never overwrite if explicity defined
      if (empty($form_info[$key])) {
        $wizard_callback = $hook . $callback;
        if (function_exists($wizard_callback))  {
          $form_info[$key] = $wizard_callback;
        }
      }
    }
    

    Where the $hook variable comes from the $form_info (line 414 of wizard.inc) :

    $hook = $form_info['id'];
    

    Which is hardcoded to 'ctools_content_form' (line 558 of content.inc) :

    $form_info += array(
      'id' => 'ctools_content_form',
      'show back' => TRUE,
    );
    

Did I miss something? Is it possible to overload the 'back callback' property?

Thanks a lot.

Olivier Demarteau.

Comments

dimduj’s picture

Hi,

I'm facing the same issue...

It seems that when you use a wizzard in a Ctools content type you couldn't override the "next callback" *.
(* "cancel callback" is never used in wizzard, see http://drupal.org/node/749362)

This is because, in the ctools_content_form(), when we set an array for the "edit/add form"** in the $plugin of our content type, we only pass $subtype['edit form'] to the _ctools_content_create_form_info() and we have no other chances to provide a $form_info['next callback'] with a correct and custom value before calling ctools_wizard_multistep_form()...

** An array for 'edit form' or 'add form' => we want a wizzard for the content type

content.inc line 572

  if (empty($form_info['order'])) {
    // Use the edit form for the add form if add form was completely left off.
    if (!empty($subtype['edit form'])) {
      _ctools_content_create_form_info($form_info, $subtype['edit form'], $subtype, $subtype, $op);
    }
    else if (!empty($plugin['edit form'])) {
      _ctools_content_create_form_info($form_info, $plugin['edit form'], $plugin, $subtype, $op);
    }
  }

  if (empty($form_info['order'])) {
    return FALSE;
  }

  ctools_include('wizard');
  return ctools_wizard_multistep_form($form_info, $step, $form_state);

If somebody has an idea , he 's welcome !
Maybe I can try to provide a patch for that but I would like to have some guildeline/advice from a maintener ...

b-prod’s picture

Version: 6.x-1.8 » 7.x-1.x-dev
Category: support » bug
Status: Active » Needs review
StatusFileSize
new548 bytes

Does it trouble anybody to tag this issue as 7.x, since there is the main issue in this version of cTools wizard? If the bug is fixed for the 7.x, which is the current active version, I could easily add a backport for D6.

For a quick workaround, you can check if the 'next' key exists in $form_state array. If not, the 'previous' key should exist. Like that you can easily know which kind of action to perform. Maybe it could be better to rename the 'next callback' key but I am afraid that it needs everybody who uses cTools wizard to update his code... almost bad!

I just said it was a quick workaround, but it could be the way for cTools wizard to work. So the 'back callback' key could be totally removed from the code and documentation, and there would be only one callback function to handle 'next' and 'back' behavior.

@maintainers: tell me if you agree with that, so I could post a patch that fixes this stuff. Otherwise, if you prefer to have a separate callback, you just have to apply the provided patch.

b-prod’s picture

Hmmm I renamed the wrong patch file, sorry.
Here is the correct one.

tim.plunkett’s picture

Status: Needs review » Needs work

There are a large number of references to 'next' throughout other parts of CTools.
I haven't tried this, but have you looked at the code to ensure no further changes are needed?

b-prod’s picture

If I remember well, the other are related to AJAX calls. I didn't change those parts because I have currently no way to test them.

b-prod’s picture

Category: bug » feature
Status: Needs work » Closed (won't fix)

Time has passed... and the patch does not apply anymore to the current cTools release. No time to investigate on what changed in wizard and how to process.

There is still something to fix there, so I changed the issue as a feature request, if somebody in the future will work on that.

abratko’s picture

I Have this issue in 7.x-1.3 version
Thanks for patch.

abratko’s picture

abratko’s picture

Assigned: Unassigned » abratko
Category: Feature request » Bug report
Status: Closed (won't fix) » Active
intrafusion’s picture

I am encountering this problem, but found a workaround:

/**
 * Callback executed when the 'back' or 'next' button is clicked.
 */
function MODULE_next(&$form_state) {
  if ($form_state['clicked_button']['#value'] == t('Back')) {
    // Do whatever, but use $form_state['input'] instead of $form_state['values']
  }
  else {
    // Use $form_state['values']
  }
}

I would prefer not to use the if statement, but this provides a workaround as my MODULE_back(&$form_state) is never called

japerry’s picture

Status: Active » Closed (outdated)

Drupal 7 is no longer supported, closing.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.