I have implemented a box type, but can't get ajax functionality to work with it. I haven't worked much with classes before so probably a stupid question. It works fine with a "normal form" (code based on the examples module) but can't manage to convert it to work in a box.

What I'm trying to do is add an "add more" option so you can add more field to a box"

/**
 * Custom box.
 */
class custom_box extends boxes_box {
  /**
   * Implementation of boxes_content::options_defaults().
   */
  public function options_defaults() {
    return array();
  }

  /**
   * Implementation of boxes_content::options_form().
   */
  public function options_form() {
    $form = array();

  // Because we have many fields with the same values, we have to set
  // #tree to be able to access them.
  $form['#tree'] = TRUE;
  $form['names_fieldset'] = array(
    '#type' => 'fieldset',
    '#title' => t('People coming to the picnic'),
    // Set up the wrapper so that AJAX will be able to replace the fieldset.
    '#prefix' => '<div id="names-fieldset-wrapper">',
    '#suffix' => '</div>',
  );

  // Build the fieldset with the proper number of names. We'll use
  // $form_state['num_names'] to determine the number of textfields to build.
  if (empty($this->options['num_names'])) {
    $this->options['num_names'] = 2;
  }
  for ($i = 0; $i < $this->options['num_names']; $i++) {
    $form['names_fieldset']['name'][$i] = array(
      '#type' => 'textfield',
      '#title' => t('Name'),
    );
  }
  $form['names_fieldset']['add_name'] = array(
    '#type' => 'submit',
    '#value' => t('Add one more'),
    '#submit' => array('custom_box_add_more_add_one'),
    // See the examples in ajax_example.module for more details on the
    // properties of #ajax.
    '#ajax' => array(
      'callback' => 'custom_box_add_more_callback',
      'wrapper' => 'names-fieldset-wrapper',
    ),
  );
  }

    return $form;
  }

  /**
   * Implementation of boxes_content::options_form().
   */
  public function render() {
    $title = isset($this->title) ? check_plain($this->title) : NULL;
    return array(
      'delta' => $this->delta, // Crucial.
      'title' => $title,
      'subject' => $title,
      'content' => $content,
    );
  }
}
/**
 * Submit handler for the "add-one-more" button.
 *
 * It just increments the max counter and causes a rebuild.
 */
function custom_box_example_add_more_add_one($form, &$form_state) {
  $form_state['box']->options['num_names'] = $form_state['box']->options['num_names'] + 1;
  $form_state['rebuild'] = TRUE;
}

/**
 * Callback for both ajax-enabled buttons.
 *
 * This simply selects and returns the fieldset with the names in it.
 */
function custom_box_add_more_callback($form, $form_state) {
  return $form['options']['names_fieldset'];
}

I get the form rebuild when I click "add one more" but I can't figure out how to the the new number of rows back to the form build so I can create another field.

Comments

e2thex’s picture

The problem here was that the box->options_form does not have access to the form state
we change this in http://drupal.org/node/1126378

you will have to change the option_from sig to options_form(&$form_state) but I think that should get you some of the way.
(not the change is now in dev)

febbraro’s picture

Status: Active » Closed (duplicate)

Yes, see #1126378 and even possibly #1126378