1

Here is the form:

function payment_form($form, &$form_state) {
  $form['#tree'] = TRUE;

  // since credit card is also an option, the gift card section is contained in this div.
  $form['payment']['giftcard'] = array(
    '#type' => 'container',
  );

  // there are additional fields above here, but trimmed them out since they are not relevant to the issue.
  $form['payment']['giftcard']['giftcards'] = array(
    '#type' => 'container',
    '#attributes' => array(
      'class' => array('giftcards'),
    ),
    '#prefix' => '<div class="giftcards-wrapper">',
    '#suffix' => '</div>',
  );

  // initialize the gift card field counter
  if (!isset($form_state['gift_cards'])) {
    $form_state['gift_cards'] = 1;
  }
  // build the fields
  for ($i = 0; $i < $form_state['gift_cards']; $i++) {
    $form['payment']['giftcard']['giftcards']['gift_card_number'][$i] = array(
      '#type' => 'textfield',
      '#title' => t('Gift Card Number'),
      '#title_display' => 'invisible',
    );
  }
  // validate the current gift card and add another field.
  $form['payment']['giftcard']['giftcards']['validate'] = array(
    '#type' => 'submit',
    '#value' => t('Validate'),
    '#ajax' => array(
      'callback' => 'validate_giftcard_add_field',
      'wrapper' => 'giftcards-wrapper',
      'method' => 'replace',
    ),
  );

Here is the callback function for the AJAX call. There is no validation currently, just trying to get it to add another field. If I add print statements in this function they are being output in a javascript alert, so this function is being called. However it is not returning any new fields.

function validate_giftcard_add_field($form, $form_state) {
  $form_state['gift_cards']++;

  return $form['payment']['giftcard']['giftcards'];
}

What is the right way to add new fields via ajax?

Additionally, all instances of '#required' => TRUE, have been removed during my testing. I have not done anything with the validate or submit callbacks either.

2

#ajax->wrapper refers to an ID. Where as you have class="giftcards-wrapper". Change it to ID and it should replace it.

  • This was only part of the issue, see my answer below. – Scott Joudry Jun 30 '16 at 13:59
2

There were a couple of issues here. The first was with the wrapper, changed the class to and id:

// there are additional fields above here, but trimmed them out since they are not relevant to the issue.
$form['payment']['giftcard']['giftcards'] = array(
  '#type' => 'container',
  '#attributes' => array(
    'class' => array('giftcards'),
  ),
  '#prefix' => '<div id="giftcards-wrapper">',
  '#suffix' => '</div>',
);

The second issue is missing the submit callback for the ajax button:

// validate the current gift card and add another field.
$form['payment']['giftcard']['giftcards']['validate'] = array(
  '#type' => 'submit',
  '#value' => t('Validate'),
  '#submit' => array('validate_giftcard_add_field_submit'),
  '#ajax' => array(
    'callback' => 'validate_giftcard_add_field',
    'wrapper' => 'giftcards-wrapper',
    'method' => 'replace',
  ),
);

Updated ajax callback:

function validate_giftcard_add_field($form, $form_state) {
  return $form['payment']['giftcard']['giftcards'];
}

Defined the ajax submit callback:

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

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.