0

I have added an add field button to a module form. The fieldset displays properly and the callback works one time - I click the add more button, and my fields add properly.

The issue is when I click it a second time...the fields add to the form, but outside of the fieldset, and the add/remove buttons start to duplicate.

Here is my form and callback functions...basically copied directly from the example module. I'm leaving the entire form...the top part is a bunch of other fields, the AJAX fields and function are at the bottom. I've spent 2 days fiddling...so I'd very much appreciate some direction!

    function _nnreport_shipping_new($form, &$form_state) {
    $jobId = $_GET['id'];
    $job = new stdClass();
    $job = _nnjob_retrieve_jobid($jobId);


    $form['jobId'] = array(
           '#type'=>'hidden',
           '#value'=>$jobId, );
    $form['rigId'] = array(
        '#type'=>'hidden',
        '#value'=>$job->rigId,);
    $form['clientId'] = array(
        '#type'=>'hidden',
        '#value'=>$job->clientId, );
    $form['clientsName'] = array(
            '#type'=>'hidden',
            '#value'=>$job->clientName, );
    $form['wellsName'] = array(
            '#type'=>'hidden',
            '#value'=>$job->wellName, );
    $form['rigCo'] = array(
            '#type'=>'hidden',
            '#value'=>$job->rigCoId, );
    $form['fullRig'] = array(
            '#type'=>'hidden',
        '#value'=>$job->rigCompanyName.' '.$job->rigName, );
    $form['jobIdTitle'] = array(
            '#markup' => '<h2>For:  ' .$job->clientName. ' | '.$job->rigCompanyName.' '.$job->rigName. ' | '.$job->wellName. ' | ' ._nnjob_format_job_id($jobId).'</h2>', );
    $form['date'] = array(
            '#markup' => '<div style="float:right; padding-right: 350px;"><label for="date" class="ui-input-text">Date</label><input type="date" data-clear-btn="true" name="date" id="date" value=""></div>',

        );

     $form['carrier'] = array(
        '#type' => 'textfield',
        '#size' => 30,
        '#title' => t('Carrier:'),
        '#required' => FALSE,);
    $form['carrierPhone'] = array(
        '#type' => 'textfield',
        '#size' => 30,
        '#title' => t('Carrier Phone:'),
        '#required' => FALSE,
        //'#suffix' => '</div><div style="float:left; padding-right: 50px;">',
        );



    $form['origin'] = array(
        '#type' => 'textarea',
        '#cols' => 30,
        '#rows' => 5,
        '#title' => t('Origination:'),
        '#prefix' => '</div><div style="float:left; padding-right: 50px;">',
        );

    $form['fromContact'] = array(
        '#type' => 'textfield',
        '#size' => 30,
        '#title' => t('Contact:'),
        '#required' => FALSE,);

    $form['destination'] = array(
        '#type' => 'textarea',
        '#cols' => 30,
        '#rows' => 5,
        '#title' => t('Destination:'),
        '#required' => FALSE,
        '#prefix' => '</div><div style="float:right; padding-right: 350px;">',

        );


    $form['destContact'] = array(
        '#type' => 'textfield',
        '#size' => 30,
        '#title' => t('Contact:'),
        '#required' => TRUE,
        '#suffix' => '</div><div style="clear:both;"></div>',
        );

    $form['#tree'] = TRUE;

    $form['items_fieldset'] = array(
    '#type' => 'fieldset',
    '#title' => t('Shippment Inventory Items:'),
    '#prefix' => '<div id="items-fieldset-wrapper">',
    '#suffix' => '</div>',
    ); 

     if (empty($form_state['num_items'])) {
    $form_state['num_items'] = 1;
    } 


     for ($i = 0; $i < $form_state['num_items']; $i++) {

    $form['items_fieldset'][$i] = array(
    '#prefix' => '<div class="two-col">',
    '#suffix' => '</div>'
    );


    $form['items_fieldset'][$i]['amount'] = array(
        '#type' => 'textfield',
        '#size' => 30,
        '#title' => t('Amount:'),
        '#required' => TRUE,
        '#prefix' => '</div><div style="float:left; padding-right: 50px;">',

    );

    $form['items_fieldset'][$i]['description'] = array(
        '#type' => 'textfield',
        '#size' => 50,
        '#title' => t('Description:'),
        '#required' => TRUE,
        '#prefix' => '</div><div style="float:left; padding-right: 50px;">',
        ); 

    $form['items_fieldset'][$i]['serial'] = array(
        '#type' => 'textfield',
        '#size' => 30,
        '#title' => t('Serial Number:'),
        '#required' => TRUE,
        '#prefix' => '</div><div style="float:left;">',
        '#suffix' => '</div><div style="clear:both;"></div>',

            );
    } 

    $form['items_fieldset']['add_items'] = array(
    '#type' => 'submit',
    '#value' => t('Add more'),
    '#submit' => array('_nnreport_shipping_new_add_one'),
    '#ajax' => array(
        'callback' => '_nnreport_shipping_new_callback',
        'wrapper' => 'items-fieldset-wrapper',
        //'method' => 'after',
    ),
    ); 

    if ($form_state['num_items'] > 1) {
    $form['items_fieldset']['remove_items'] = array(
    '#type' => 'submit',
    '#value' => t('Remove one'),
    '#ajax' => array(
        'callback' => '_nnreport_shipping_new_callback',
        'wrapper' => 'items-fieldset-wrapper',

//added this prevent  and limit validation error as another attempt...didn't change anything

'prevent' => 'submit click mousedown',
        ),
    '#limit_validation_errors' => array(),
    '#submit' => array('_nnreport_shipping_new_remove_one'),
    );
    } 


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




    return $form;

    }

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

    function _nnreport_shipping_new_callback($form, $form_state) {
    return $form['items_fieldset'];
    } 

    function _nnreport_shipping_new_remove_one($form, &$form_state) {
      if ($form_state['num_items'] > 1) {
        $form_state['num_items']--;
      }
      $form_state['rebuild'] = TRUE;
    }

1 Answer 1

2

There are some errors with opening and closing divs that you declare in the #prefix.

See the code below where I simply removed your #prefix and #suffix definitions. If there are unclosed divs in the markup it will create problems such as the one you mention with the new markup ending up outside the fieldset.

So simply replace the definition of $form['items_fieldset'][$i], $form['items_fieldset'][$i]['amount'], $form['items_fieldset'][$i]['description'] and $form['items_fieldset'][$i]['serial'] with the code below.

$form['items_fieldset'][$i] = array(
  '#prefix' => '<div class="two-col">',
  '#suffix' => '</div>'
);

$form['items_fieldset'][$i]['amount'] = array(
  '#type' => 'textfield',
  '#size' => 30,
  '#title' => t('Amount:'),
  '#required' => TRUE,
);

$form['items_fieldset'][$i]['description'] = array(
  '#type' => 'textfield',
  '#size' => 50,
  '#title' => t('Description:'),
  '#required' => TRUE,
); 

$form['items_fieldset'][$i]['serial'] = array(
  '#type' => 'textfield',
  '#size' => 30,
  '#title' => t('Serial Number:'),
  '#required' => TRUE,
);
1
  • That did it! Got to love that it came down to the markup, I didn't even consider that by the nature of the buttons glitching. Thanks again. Commented Aug 2, 2013 at 14:21

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.