I have a "profile" entity with a field "education" (to get started). That field contains various input fields that describe the "education". At the moment I have "institution" and "year". I created that field with the Field API in a dedicated module and attached it to my "profile" entity (currently this is a profile2 bundle). The entity form works as expected, the "education" field widget is included and I can add multiple "education" entries. I can view my entity and the fields get formatted, and I can edit my entity and the form widgets get rendered.

--profile entity
----education field
------education a
--------institution a
--------year a
------education b
--------institution b
--------year b

But I do not like the all or nothing approach here. There are going to be many different fields and I want to display the "profile" entity with various "edit" and "add new entry" buttons, which should load the specified field form widget via AJAX. The profile page on xing.com is a good example of what I am trying to achieve.

Is this possible with the fields form widget and Field API alone, or do I have to implement the ajax callback via a menu hook, which returns a form with the needed input fields? Can I even use my "education" field in that scenario or do I have to work with the entity API and database API?


3 Answers 3


The forms that FieldAPI can build for you automatically are useful but not terribly flexible. If you're interested in building out a really dynamic form, you're probably better off creating your own from scratch and simply creating/saving the entity programmatically once the finished form is submitted.

  • That's what I'm doing right now. I don't use the "education" field. Instead I create a "education" entity and use the Form API and Entity API to relate "education" entities n:1 to a "profile" entity. Mar 20, 2011 at 11:15

Have you looked at the Examples module? They have sample code for Ajax forms, using the FormAPI.

  • I did and I will soon post my approach. Bottom line: I did not use Field API at all. I used Form API with standard ajax page callbacks and Entity API to persist the form values. Mar 26, 2011 at 15:13

I have successfully made a hierarchical select with ajax on a profile2 form used in registration.

// implementation of hook_form_FORM_ID_alter()    
function impact_registration_form_profile2_edit_library_registration_form_alter(&$form, &$form_state) {
$form['profile_library_registration']['field_library_reg_state']['und']['#options'] = _impact_registration_library_states();
$form['profile_library_registration']['field_library_reg_state']['und']['#ajax'] = array(
                          'callback' => 'impact_registration_state_change_callback',
                          'wrapper' => 'name-select',
        $selected = isset($form_state['values']['profile_library_registration']['field_library_reg_state']['und'][0]['value']) ? $form_state['values']['profile_library_registration']['field_library_reg_state']['und'][0]['value'] : '';
    $form['profile_library_registration']['field_library_reg_system']['und']['#options'] = _impact_registration_library_names($selected);
    $form['profile_library_registration']['field_library_reg_system']['und']['#prefix'] = "<div id='name-select'>";
    $form['profile_library_registration']['field_library_reg_system']['und']['#suffix'] = "</div>";
    function impact_registration_state_change_callback(&$form, $form_state) {
    return $form['profile_library_registration']['field_library_reg_system']['und'];

When I select field_library_reg_state, AJAX returns field_library_reg_system, with a default value based on field_library_reg_state's value in $form_state. This is all adapted from the ajax example. Now, what isn't working for me is adding an additional ajax call on field_library_reg_system so that it pre-populates a text box. The documentation for doing this is non existent, I don't understand how profile2 and entity forms work differently than regular forms in drupal. Which array elements are we supposed to target for the wrapper and callback?

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.