1

I want to build a widget for a own field type. In the function formElement() of my widget I want the elements wrapped in a div. For this purpose exists the container element. So I build my form:

  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {

    $element['myitem'] = [
      '#type' => 'container',
      '#attributes' => [
          'class' => ['my-item'],
      ],
      '#attached' => [
        'library' => [
          'mymodule/mylibrary',
        ],
      ],
    ];
   $element['myitem']['label'] = [
    '#type' => 'select',
    '#title' => t('Label'),
    '#default_value' => isset($items[$delta]->label) ? $items[$delta]->label : NULL,
    '#options' => $options_for_label,
  ];     
  //… more elements

  return $element;
}

The rendering of the form looks like I wanted. But the form entries will not be saved. There are no errors and none of the elements were attached to the entity and persisted in the database.

If I don't use the container element and place my elements direct in $element like this:

 $element['label'] = [
  '#type' => 'select',
  '#title' => t('Label'),
  '#default_value' => isset($items[$delta]->label) ? $items[$delta]->label : NULL,
  '#options' => $options_for_label,
];
//… more elements

then all will be saved.

How can I get my widget-form elements be wrapped within a div for styling?

(A similar question using container element within form widget, here with focus at form state was asked 3 years ago, but without answer :-( )

3

From WidgetBase::form:

// Most widgets need their internal structure preserved in submitted values.
$elements += ['#tree' => TRUE];

When customizing the structure you also need to make sure the values get submitted correctly. For example by adding WidgetInterface::massageFormValues to your widget.

A much easier way though is to keep the standard structure, which is using property names as form keys, and add the container by #prefix/#suffix:

$element['label'] = [
  '#type' => 'select',
  '#title' => t('Label'),
  '#default_value' => isset($items[$delta]->label) ? $items[$delta]->label : NULL,
  '#options' => $options_for_label,
  '#prefix' => '<div class="my-item">',
  '#suffix' => '</div>',
];
| improve this answer | |

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.