0

I am following the ajax_example.module in the example module closely. Essentially, I have a fieldset with several fields inside. The user fills out these fields, clicks 'add more', and then another fieldset loads beneath it via AJAX. a form with an AJAX-enabled button to load an additional fieldset

My form works fine for up to three entries. But, after a third entry is added, it begins duplicating fieldsets.

enter image description here

The logic that generates the form is a simple for loop; it should work the same for 1 or 100 values, and I'm not really sure why the duplicates are being generated. What's even more perplexing is that if I examine $form in a debugger, the form elements are all where they should be, and there are no duplicates.

Code overview: I have a page that calls this form. The form has a button with the 'ajax' property, and when clicked, it adds 1 to $form_state['item_quantity']. Then, it regenerates the form, and a for loop creates one fieldset per item_quantity. There is a conditional to check if this is the last item, which will add a special CSS class if true.

function manual_import_form($form, &$form_state) {
  //set up options for select list
  $task_options = get_task_options();
  $location_options = get_location_options();
  $model_options = get_model_options();

  $form['#attached'] = array(
    'css' => array(
      'type' => 'file',
      'data' => drupal_get_path('module','manual_import') . '/manual_import.css',
    ),
  );
  $form['#tree'] = TRUE;
  $form['scenario'] = array(
    '#type' => 'select',
    '#title' => t('Import Scenario'),
    '#options' => array(
      'shipment' => t('Shipment'),
      'location' => t('Location'),
      'manual' => t('Manual'),

      ),
    '#default_value' => 'shipment',
  );
  $form['scenario_shipment'] = array(
    '#type' => 'fieldset',
    '#title' => t('Associate Group To Shipment'),
    '#description' => t('Associate a group of items to a shipment, and auto-generate tasks'),
    '#states' => array(
      'visible' => array(
        ':input[name="scenario"]' => array('value' => 'shipment'),
      ),
    ),
    '#collapsible' => TRUE,
    '#collasped' => FALSE,
  );
  $form['scenario_shipment']['shipping_list_number'] = array(
    '#type' => 'textfield',
    '#title' => t('Shipping List Number'),
    '#prefix' => '<div class="manual-import-shipping-list">',
    '#suffix' => '</div>',
  );
  $form['scenario_shipment']['shipping_from'] = array(
    '#type' => 'select',
    '#title' => t('Shipping From'),
    '#options' => $location_options,
    '#default_value' => 283,
  );
  $form['scenario_shipment']['shipping_to'] = array(
    '#type' => 'select',
    '#title' => t('Shipping To'),
    '#options' => $location_options,
    '#default_value' => 283,
  );

  $form['scenario_location'] = array(
    '#type' => 'fieldset',
    '#title' => t('Associate Group To Location'),
    '#description' => t('Associate a group of items to a location, and auto-generate tasks'),
    '#states' => array(
      'visible' => array(
        ':input[name="scenario"]' => array('value' => 'location'),
      ),
    ),
    '#collapsible' => TRUE,
    '#collasped' => FALSE,
  );
  $form['scenario_location']['location'] = array(
    '#type' => 'select',
    '#title' => t('Location'),
    '#options' => $location_options,
    '#default_value' => 283,
  );
  $form['scenario_manual'] = array(
    '#type' => 'fieldset',
    '#title' => t('Manually Create Tasks'),
    '#description' => t('Manually select the tasks to be created for the items in the group.'),
    '#states' => array(
      'visible' => array(
        ':input[name="scenario"]' => array('value' => 'manual'),
      ),
    ),
    '#collapsible' => TRUE,
    '#collasped' => FALSE,
  );
  $form['scenario_manual']['task'] = array(
    '#type' => 'select',
    '#title' => t('Task Type'),
    '#options' => $task_options,
  );
  $form['import_items'] = array(
    '#type' => 'container',
    '#prefix' => '<div id="import_items">',
    '#suffix' => '</div>',
  );
  if (empty($form_state['import_item_quantity'])) {
      $form_state['import_item_quantity'] = 1;
  }
  for ($i = 1; $i <= $form_state['import_item_quantity']; $i++) {
    $form['import_items'][$i] = array(
      '#type' => 'fieldset',
      '#title' => t('Import Item @item', array('@item' => $i)),
      '#collapsible' => TRUE,
      '#collapsed' => FALSE,
    );
    $form['import_items'][$i]['ticket_number'] = array(
      '#type' => 'textfield',
      '#maxlength' => 32,
      '#title' => t('Ticket Number'),
      '#class' => 'manual-import-item-field',
      '#prefix' => '<div class="manual-import-item-field manual-import-item-ticket">',
      '#suffix' => '</div>',
    );
    $form['import_items'][$i]['device_id'] = array(
      '#type' => 'textfield',
      '#maxlength' => 32,
      '#title' => t('Device ID'),
      '#prefix' => '<div class="manual-import-item-field manual-import-item-device-id">',
      '#suffix' => '</div>',
    );
    $form['import_items'][$i]['device_model'] = array(
      '#type' => 'select',
      '#title' => t('Make/Model'),
      '#options' => $model_options,
      '#prefix' => '<div class="manual-import-item-field manual-import-item-device>',
      '#suffix' => '</div>',
    );
    if ($i == $form_state['import_item_quantity']) {
      $form['import_items'][$i]['device_model']['#prefix'] = 
        '<div class="manual-import-item-field manual-import-item-device manual-import-item-last">';
    }
  }
  $form['import_items']['item_add'] = array(
    '#type' => 'submit',
    '#value' => 'Add another!',
    '#ajax' => array(
      'callback' => 'manual_import_item_ajax_callback',
      'wrapper' => 'import_items',
    ),
    '#submit' => array('manual_import_item_add'),
  );
  xdebug_break();
  return $form;
}


function manual_import_item_ajax_callback($form, $form_state) {
  return $form['import_items'];
}


function manual_import_item_add($form, &$form_state) {
  $form_state['import_item_quantity']++;
  $form_state['rebuild'] = TRUE;
}

1 Answer 1

0

It's in your CSS.

$form['import_items'][$i]['device_model'] 

Is missing a double quote on the #prefix. Change To:

 '#prefix' => '<div class="manual-import-item-field manual-import-item-device">',
1
  • You're right; the missing quotation marks were interfering with the div structure, which compounded after every iteration. With the quotes in place, it's working normally now; thank you.
    – ouni
    Oct 6, 2013 at 17:39

Your Answer

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

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