I'm struggling with #type 'text_format' for a widget form field as this field gets expanded two separate elements, one holding the orignal element and the other the format selector. The orignal element is moved into a child element.

All of this is fine, but as the orignal field is now moved into a child when the widget form is saved is tries to save the child element (array). As the widgets fields have to be at the root of the form with names that match 1:1 with db columns.

From form.inc:

If the property #text_format is set, the form element will be expanded into two separate form elements, one holding the content of the element, and the other holding the text format selector. The original element is shifted into a child element, but is otherwise unaltered, so that the format selector is at the same level as the text field which it affects.

I've looked at the text.module but I can't work out how it is getting around the issue of the field being expanded?

2 Answers 2


Good luck with that. What a head-scratching nightmare. See Missing hook_field_widget_form_submit()? for an idea of how to make this easier.

I got this to work once in a module, but then had to remove it for other reasons. The code is still there, look at this older version of flashcard.install and flashcard.module, especially flashcard_field_widget_form() and flashcard_field_formatter_view().

  • Sorted! You would not believe how much pain this has caused me due to there being no documentation regarding this expanding field and widgets. I might have to write an article on drupal.org!
    – Camsoft
    Jun 8, 2011 at 13:55

After hours, I finally solved it, taking in account the post by tim.plunkett; I have added a validator to the widget form, and then added the values to $form_state in the validator.

function ldn_panels_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element){
  $element['#element_validate'] = array('_ldn_panels_widget_validate');

  $element['title'] = array(
    '#type' => 'textfield',
    '#title' => 'Título',
    '#default_value' => isset($items[$delta]['title'])?$items[$delta]['title']:'',

  $element['content'] = array(
    '#type' => 'text_format',
    '#title' => 'Contenido',
    '#format' => isset($items[$delta]['content_format'])?$items[$delta]['content_format']:NULL,
    '#default_value' => isset($items[$delta]['content_value'])?$items[$delta]['content_value']:'',

  return $element;


function _ldn_panels_widget_validate($element, &$form_state){
  if($form_state['complete form']['#form_id'] == 'field_ui_field_edit_form') return;
  $field_name = $element['#field_name'];
  $values = $form_state['values'];
  $language = $element['#language'];
  $delta = $element['#delta'];
  $form_state['values'][$field_name][$language][$delta]['content_value'] = $values[$field_name][$language][$delta]['content']['value'];
  $form_state['values'][$field_name][$language][$delta]['content_format'] = $values[$field_name][$language][$delta]['content']['format'];

Note the content element in the widget splits in 2 values: value, and format. All I had to do was to modify my field schema to storage these 2 values, content_value and content_format.

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.