2

I am having somewhat of a problem, I am trying to use ajax commands to go to the next case on my form. I dont really understand how to complete this and ive tried numerous ways without any success. Basically what im trying to do in my ajax callback load my preloader function into the #neato_form div's with a 10 second delay and then make it go to case 2 which is step 2 on my form.

Ive included my ajax callback since this is the main problem. Along with my form and submit function in case ive done something wrong there.

Any Suggestions is greatly appreciated.

Ajax commands

function neato_form_ajax_callback($form, &$form_state)
{
    $commands = array();

    $commands[] = array(
        'command' => 'mortgage_response',
        'leadstatus' => 'success',
    );

    $commands[] = ajax_command_replace('#neato_form', preloader());
    $commands[] = ajax_command_invoke(NULL, "preloader");

    if($commands[0]['leadstatus'] == 'success'){

        $commands[] = ajax_command_replace('#neato_form', $form_state['step2']);
    }

    return array('#type' => 'ajax', '#commands' => $commands);
}

Form and Submit function

function neato_form($form, &$form_state)
{
    $form_state['step'] = isset($form_state['step']) ? $form_state['step'] : 1;

    $form['#prefix'] = '<div id="neato_form">';
    $form['#suffix'] = '</div>';

    switch($form_state['step'])
    {
        // Step 1
        case 1:
            $default_value = '';
            if(isset($form_state['values']['step_1']))
            {
                $default_value = $form_state['values']['step_1'];
            }
            elseif(isset($form_state['storage']['step_1']))
            {
                $default_value = $form_state['storage']['step_1'];
            }

            $form['step_1'] = array
            (
                '#type' => 'textfield',
                '#title' => t('Step 1'),
                '#required' => TRUE,
                '#default_value' => $default_value,
            );
            break;

        // Step 2
        case 2:
            $default_value = '';
            if(isset($form_state['values']['step_2']))
            {
                $default_value = $form_state['values']['step_2'];
            }
            elseif(isset($form_state['storage']['step_2']))
            {
                $default_value = $form_state['storage']['step_2'];
            }

            $form['step_2'] = array
            (
                '#type' => 'textfield',
                '#title' => t('Step 2'),
                '#required' => TRUE,
                '#default_value' => $default_value,
            );

            break;

        // Step 3
        case 3:
            $default_value = '';
            if(isset($form_state['values']['step_3']))
            {
                $default_value = $form_state['values']['step_3'];
            }
            elseif(isset($form_state['storage']['step_3']))
            {
                $default_value = $form_state['storage']['step_3'];
            }

            $form['step_3'] = array
            (
                '#type' => 'textfield',
                '#title' => t('Step 3'),
                '#required' => TRUE,
                '#default_value' => $default_value,
            );

            break;
    }

    $form['buttons'] = array
    (
        '#type' => 'container',
    );

        $form['buttons']['submit'] = array
        (
            '#type' => 'submit',
            '#value' => t('Submit'),
            '#ajax' => array
            (
                'wrapper' => 'neato_form',
                'callback' => 'neato_form_ajax_callback',
            ),
        );

    return $form;
}

function neato_form_back_submit($form, &$form_state)
{
    $form_state['step']--;
    $form_state['rebuild'] = TRUE;
}

function neato_form_submit($form, &$form_state)
{
    $step = $form_state['step'];
    $form_state['storage']['step_' . $step] = $form_state['values']['step_' . $step];

    if(isset($form_state['values']['forward']) && $form_state['values']['op'] == $form_state['values']['forward'])
    {
        $form_state['step']++;
    }
    elseif(isset($form_state['values']['submit']) && $form_state['values']['op'] == $form_state['values']['submit'])
    {

        $items = array($form_state['storage']['step_1'], $form_state['storage']['step_2'], $form_state['storage']['step_3']);
        drupal_set_message(t('My !values', array('!values' => theme('item_list', array('items' => $items)))));

        $form_state['step'] = 1;
        $form_state['storage'] = array();
    }
    $form_state['rebuild'] = TRUE;
}

1 Answer 1

2

I think you should attach your custom ajax preloader function to the form as follows:

$form['#attached']['js'] = array(
  array(
    'type'  => 'file',
    'data' => drupal_get_path('module', 'MY_MODULE') . '/js/ajax_preloader.js',
  ),
);

ajax_preloader.js

(function($) {
  Drupal.behaviors.events = {
    attach: function(context, settings) {
      $('#steps-form', context).ajaxStart(function() {
        // ...
      });
      $('#steps-form', context).ajaxSuccess(function() {
        // ...   
      });
    }
  };
})(jQuery);

alternatively, you can create your custom command (myPreloaderExample)

(function($, Drupal) {
  Drupal.ajax.prototype.commands.myPreloaderExample = function(ajax, response, status) {
    $('#steps-form').ajaxStart(function() {
      //...
    });
    $('#steps-form').ajaxSuccess(function() {
      // ...
    });
  };
}(jQuery, Drupal));

I'm not sure what your aim is, but if you're going to create a multistep ajax form with the following features:

  • Show only the current form item
  • Store all previously provided values (allow to preview all the values without loosing them)

You can create this kind of form as follows:

/**
 * An example of steps form.
 */
function steps_form($form, &$form_state) {

  // Because we have many fields with the same values, we have to set
  // #tree to be able to access them.
  $form['#tree'] = TRUE;

  $form['steps_fieldset'] = array(
    '#type' => 'fieldset',
    '#title' => t('Steps form'),
    // Set up the wrapper so that AJAX will be able to replace the fieldset.
    '#prefix' => '<div id="steps-fieldset-wrapper">',
    '#suffix' => '</div>',
  );

  $form['steps_fieldset']['actions'] = array(
    '#type' => 'actions'
  );

  // Build the fieldset with the proper number of steps.
  // Use $form_state['step'] to determine the number of textfields to build.
  if (empty($form_state['step'])) {
    $form_state['step'] = 1;
  }

  // An array with form values.
  if (empty($form_state['storage'])) {
    $form_state['storage'] = array();
  }

  // Define the number of steps.
  $form_state['steps_number'] = 3;

  // build all textfields with steps
  for ($i = 0; $i < $form_state['step']; $i++) {

    // set the type of each previous form item as a hidden. Only last step will be shown.
    $type = ($i == ($form_state['step']-1)) ? 'textfield' : 'hidden';

    // get the default value of step.
    $default_value = isset($form_state['storage'][$i]) ?  $form_state['storage'][$i] : '';  

    $form['steps_fieldset']['step'][$i] = array(
      '#type' => $type,
      '#title' => t('Step') . ' ' . ($i+1),
      '#required' => FALSE,
      '#default_value' => $default_value,
    );
  }

  // The next step button.
  if ($form_state['step'] != $form_state['steps_number']) {
    $form['steps_fieldset']['actions']['add_step'] = array(
      '#type' => 'submit',
      '#weight' => '1',
      '#value' => t('Next step'),
      '#submit' => array('steps_form_add_one'),
      '#ajax' => array(
        'callback' => 'steps_form_callback',
        'wrapper' => 'steps-fieldset-wrapper',
      ),
    );
  }

  // The previous step button.  
  if ($form_state['step'] > 1) {
    $form['steps_fieldset']['actions']['remove_step'] = array(
      '#type' => 'submit',
      '#weight' => '0',
      '#value' => t('Previous step'),
      '#submit' => array('steps_form_remove_one'),
      '#ajax' => array(
        'callback' => 'steps_form_callback',
        'wrapper' => 'steps-fieldset-wrapper',
      ),
    );
  }

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );

  $form['#attached']['js'] = array(
    array(
      'type'  => 'file',
      'data' => drupal_get_path('module', 'MY_MODULE') . '/js/ajax_preloader.js',
    ),
  );
  return $form;
}

/**
 * Callback for both ajax-enabled buttons.
 *
 * Selects and returns the fieldset with all values in it.
 */
function steps_form_callback($form, $form_state) {

  $commands = array();
  // return the form
  $commands[] = ajax_command_html('#steps-fieldset-wrapper', render($form['steps_fieldset']));
  // add your custom ajax command
  $commands[] = array(
    'command' => 'myPreloaderExample',
    // define some custom variables if you need to
    'someValue' => 'some value',
  );

  return array('#type' => 'ajax', '#commands' => $commands);
}

/**
 * Submit handler for the "add-one-more" button.
 *
 * - save the form value, so the user will be able to preview all previously provided values without loosing them.
 * - increments the step counter.
 * - rebuild the form.
 */
function steps_form_add_one($form, &$form_state) {

  $form_state['storage'][$form_state['step']-1] = $form_state['input']['steps_fieldset']['step'][$form_state['step']-1];
  if ($form_state['step'] < $form_state['steps_number']) {
    $form_state['step']++;
  }
  $form_state['rebuild'] = TRUE;
}

/**
 * Submit handler for the "remove one" button.
 *
 * Decrements the step counter and causes a form rebuild.
 */
function steps_form_remove_one($form, &$form_state) {
  if ($form_state['step'] > 1) {
    $form_state['step']--;
  }
  $form_state['rebuild'] = TRUE;
}

/**
 * Final submit handler.
 *
 * Reports what values were finally set.
 */
function steps_form_submit($form, &$form_state) {
  $output = t('All my values: @steps',
    array('@steps' => implode(', ', $form_state['values']['steps_fieldset']['step'])) );
  drupal_set_message($output);
}

Results

enter image description here

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.