3

I'm building a module that implement a multistep form based on a custom entity. The entity contains fields which are created by the install file.

I was able to create the steps and if I print the $form_state[storage] array in the last step I can see all the values entered all along the form.

But when I submit the last step the entity is empty. This is what I have in the last_step_submit:

$organisation = entity_ui_form_submit_build_entity('organisation',$organisation, $form, $form_state);
$organisation->save();
drupal_set_message(t('The organisation: @name has been saved.', array('@name' => $organisation->name)));
$form_state['redirect'] = 'admin/organisations';

I know that I'm missing something but really I can't figure out what. I'm quite new in module developing and I'd appreciate any help.

0

After struggling for a couple of days I finally was able to store the values in the entity.

The first mistake was that I forgot to pass my entity ('organisation') as an argument in the primary hook_form:

  // Return the current form
  $function = $form_state['storage']['step'];
  $form = $function($form, $form_state, $organisation);
  return $form;

The second was that I had to build and save my entity each step with the code I attached in this question.

$organisation = entity_ui_form_submit_build_entity('organisation',$organisation, $form, $form_state);
$organisation->save();

Now I have my custom entity with custom fields and a multistep conditional adding form!

This is the code if someone else need the same functionality. Primary form and submission functions:

function organisation_form($form, &$form_state, $organisation) {
  if ($form_state['rebuild']) {
      $form_state['input'] = array();
  }
  if (empty($form_state['storage'])) {
// No step has been set so start with the first.
   $form_state['storage'] = array(
      'step' => 'organisation_first_form',
   );
  } 
// Return the current form
  $function = $form_state['storage']['step'];
  $form = $function($form, $form_state, $organisation);
  return $form;
}

function organisation_form_submit($form, &$form_state) {
 $values = $form_state['values'];
 if (isset($values['back']) && $values['op'] == $values['back']) {
   // Moving back in form.
   $step = $form_state['storage']['step'];
   // Call current step submit handler if it exists to unset step form data.
   if (function_exists($step . '_submit')) {
     $function = $step . '_submit';
     $function($form, $form_state);
   }
// Remove the last saved step so we use it next.
$last_step = array_pop($form_state['storage']['steps']);
$form_state['storage']['step'] = $last_step;
  }
  else {
   // Record step.
   $step = $form_state['storage']['step'];
   $form_state['storage']['steps'][] = $step;
   // Call step submit handler if it exists.
   if (function_exists($step . '_submit')) {
      $function = $step . '_submit';
      $function($form, $form_state);
   }
  }
return;
}

This is one of the steps and its submission function.

function organisation_second_form($form, $form_state, $organisation) {
  $form['#parents'] = array();  
  // These variables are needed to build field forms.
  $entity_type = 'organisation'; // Substitute with any entity type.
  $bundle_name = 'organisation'; // Substitute with the entity's bundle.
  $entity = $organisation;
  $langcode = LANGUAGE_NONE; // Substitute as appropriate.

  $field_name = 'hub_position_activities';
  $items = field_get_items($entity_type, $entity, $field_name);
  $field = field_info_field($field_name);
  $instance = field_info_instance($entity_type, $field_name, $bundle_name);
  $field_form = field_default_form($entity_type, $entity, $field, $instance, $langcode, $items, $form, $form_state);
  $form += $field_form;

  $field_name = 'hub_market';
  $items = field_get_items($entity_type, $entity, $field_name);
  $field = field_info_field($field_name);
  $instance = field_info_instance($entity_type, $field_name, $bundle_name);
  $field_form = field_default_form($entity_type, $entity, $field, $instance, $langcode, $items, $form, $form_state);
  $form += $field_form;

  $form['back'] = array(
    '#type' => 'submit',
    '#value' => t('Back'),
    '#limit_validation_errors' => array(),
    '#submit' => array('organisation_second_form_submit'),
    '#weight' => 499,
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Next'),
    '#weight' => 500,
  );
  return $form;
}

function organisation_second_form_submit($form, &$form_state) {
  $values = $form_state['values'];
  $form_state['rebuild'] = TRUE;
  if (isset($values['back']) && $values['op'] == $values['back']) {
    $input = $form_state['input'];
    // The user clicked the back button, save values that were input
    if (isset($input['hub_position_activities'])) {
      $form_state['storage']['hub_position_activities'] = $input['hub_position_activities'];
    }
    if (isset($input['hub_market'])) {   
      $form_state['storage']['hub_market'] = $input['hub_market'];
    }
    $form_state['storage']['step'] = 'organisation_first_form';
  }
  else {
    $form_state['storage']['hub_position_activities'] = $values['hub_position_activities'];
    $form_state['storage']['hub_market'] = $values['hub_market'];
    $organisation = entity_ui_form_submit_build_entity($form, $form_state);
    $organisation->save();
    $form_state['storage']['step'] = 'organisation_third_form';
  }
}

And the last submission function.

function organisation_last_form_submit($form, &$form_state) {
  $values = $form_state['values'];


  if (isset($values['back']) && $values['op'] == $values['back']) {
    $form_state['storage']['step'] = 'organisation_second_form';
    $form_state['rebuild'] = TRUE;
  }
  else {
    $form_state['storage']['hub_equipment_measurement'] = $values['hub_equipment_measurement'];
    $form_state['storage']['hub_equipment_software'] = $values['hub_equipment_software'];
    $organisation = entity_ui_form_submit_build_entity($form, $form_state);
    $organisation->save();
    drupal_set_message(t('The organisation: @name has been saved.', array('@name' => $organisation->name)));
    $form_state['redirect'] = 'admin/organisations';
  }
}

Perhaps there were easier way to achieve this goal but, so far, is the only one that worked for me. If anyone has better solutions I'm eager to know them.

Thanks to Alex Weber for his great tutorial on how to get the form for existent fields http://www.alexweber.com.br/en/articles/how-manually-add-entity-field-forms-custom-drupal-form and to Bryan Jones for his Multi-step form tutorial http://bryanjones.us/article/custom-multi-step-forms-drupal-7

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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