2

Suppose that, in Drupal 7, EntityA includes one or more instances of EntityB.

Is there an example of building the create/edit form for EntityA that includes one or more edit forms for EntityB, and that can ajax in a new create form for a new EntityB?

1
  • 1
    You might want to have a look at Node Connect, it's not AJAX but will get you the workflow you're after.
    – Clive
    Mar 12 '12 at 16:27
3

It's not really that hard. You would want to create form elements that use the #tree attribute, to make sure the data for instances of EntityB will be well structured.

In order to make add another functionality you need to:

  • Keep track of the count in the $form_state.

    if (empty($form_state['count'])) {
      $form_state['count'] = 2;
    }
    
  • Add a button somewhere to add another.

    $form['entity_b']['add_another'] = array(
      '#type' => 'submit',
      '#value' => t('Add another'),
      '#limit_validation_errors' => array(),
      '#submit' => array('add_another_submit_handler'),
    );
    
    function add_another_submit_handler(&$form, &$form_state) {
      // Add one to our counter and rebuild the form
      $form_state['count'] += 1;
      $form_state['rebuild'] = TRUE;
    }
    

The above will work with no JavaScript. If you want to Ajax-enable it, you need to do some work on the wrapper.

  • Add a CSS ID that is used from the Ajax callback.

    $form['entity_b'] = array(
      '#tree' => TRUE,
      '#attributes' => array('id' => array('add-another')),
      // ...
    );
    
  • Add the #ajax element.

     // ...
     '#ajax' =>  array(
      'callback' => 'add_another_ajax',
      'wrapper' => 'add-another',
      'effect' => 'fade',
     ),
     // ...
    
  • Add the Ajax callback function.

    function add_another_ajax($form, &$form_state) {
      return $form['entity_b'];
    }
    
3
  • This is a great description of how to manage the count with ajax. What about the bit that loads and shows the edit and create forms for EntityB? Mar 12 '12 at 17:56
  • @JoeBeuckman All you really need to do, is too loop through range(0, $form_state['count']) and create the form for the entity B, maybe through some wrapper function or directly in the form, depending on how you want to mange it.
    – googletorp
    Mar 12 '12 at 19:58
  • I'm taking this approach and have run into another problem: drupal.stackexchange.com/questions/25381/… Mar 13 '12 at 16:01
1

See my approach at rszrama's sandbox: Commerce Inline Product Form. I am planning to promote it to a full project this week. I am going to call it "Entity Inline Form" or "Inline Entity Form", since it can support any entity type.

Basically, you're either doing what that module does (having custom built forms for the embedded entity B), or using Subform to embed the original add / edit form of entity B. A third option would be to have a dialog in which the add / edit form is displayed (so that it's not embedded into the main form at all), and JS code that notes the final entity ids after the dialog is closed.

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.