I'm trying to create a compound field in Drupal 7 that combines and image field, text field and a textarea field.

I've successfully done this but I'm now trying to add text format option to the textarea and I'm having problems getting it working.

It seems that when I change the widget's textarea field into a text_format field Drupal expands that field into two fields value and format (see: filter_process_format), this means that when the node displaying the field is saved it stores the array into the database and not the field value.

Here is my widget:

  * Implements hook_field_widget_form().
function MYMODULE_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {

    $elements = image_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);

    foreach (element_children($elements) as $delta) {   
        foreach ($elements[$delta]['#process'] as $key => $process) {
            if($process == 'image_field_widget_process') {
      $elements[$delta]['#process'][] = 'MYMODULE_widget_process';  

    return $elements;

 * Element #process callback function.
 * @param array $element
 * @param arrayreference $form_state
 * @param array $form
 * @return array
function MYMODULE_widget_process($element, &$form_state, $form) {

    $element = @image_field_widget_process($element, $form_state, $form);

    $item = $element['#value'];
    $item['fid'] = $element['fid']['#value'];

  $instance = field_widget_instance($element, $form_state);

    $settings = $instance['settings'];
    $widget_settings = $instance['widget']['settings'];  

    $element['title'] = array(
        '#type' => 'textfield',
        '#title' => 'Title',
        '#default_value' => isset($item['title']) ? $item['title'] : '',

    $element['text'] = array(
        '#type' => 'textarea',
        '#title' => 'Text',
        '#default_value' => isset($item['text']) ? $item['text'] : '',

    if($instance['settings']['text_processing']) {
      $element['text']['#type'] = 'text_format';
      $element['text']['#format'] = isset($item['format']) ? $item['format'] : NULL;
      $element['text']['#base_type'] = 'textarea';

    return $element;

The field value in the database is "Array" and not the string the user entered. If the field is set to a normal textarea the field value is stored correctly.

I'm guessing this is something to do with the structure of the widget but I can't work it out and the documentation is non existent.

1 Answer 1


I recently needed to create a widget for file field, that among other things needed to be able to handle multiple uploads via plupload.

Anyways, during the process of getting everything to work, I discovered the #value_callback attribute that you can put on a form item. It allows you to change the data of the submitted data and extra extra infomation, like fid of a file.

This isn't documented yet, but you can take a look at it's use in the file module. There is an issue for this on the Drupal issue tracker, but no good patch has been created with some document example yet.

I'm not sure if this would be a good case for the use of #value_callback, but it seems to me, that it could be of good use in this case.

  • Interesting, that might work. I think the reason my form is not working is that all the fields in a widget have to be at the root of the form. Each field name it seems is mapped to the column of the same name in the DB, though this is not documented. I wonder if I create two hidden fields text and format and then use the callback to map the two values from the text field (which has been expanded into 'value' and 'format'). I'll give that a go and see if it works, though it sounds like a bit of a hack.
    – Camsoft
    May 26, 2011 at 14:34
  • @camsoft If you are working on something non generic, hook_field_attach_submit could be of use
    – googletorp
    May 26, 2011 at 14:36

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.