3

I added a number of fields to a node content type in Drupal 8. I want to create a custom form and add the field widget form (the one used during node creation) to this form. How can I achieve this?

2 Answers 2

6

Answering my own question, I ended up using the following:

<?php
//Create an empty representative entity
$node = \Drupal::service('entity_type.manager')->getStorage('node')->create(array(
                'type' => 'article'
            )
        );

//Get the EntityFormDisplay (i.e. the default Form Display) of this content type
$entity_form_display = \Drupal::service('entity_type.manager')->getStorage('entity_form_display')
                                        ->load('node.article.default');

$form['#parents'] = []; // Mandatory, otherwise the widget class throws an error

//Get the body field widget and add it to the form
if ($widget = $entity_form_display->getRenderer('body')) { //Returns the widget class
  $items = $node->get('body'); //Returns the FieldItemsList interface
  $items->filterEmptyItems();
  $form['body'] = $widget->form($items, $form, $form_state); //Builds the widget form and attach it to your form
  $form['body']['#access'] = $items->access('edit');
}

see EntityFormDisplay::buildForm

3
  • 1
    $form['#parents'] needs to be set to something or you'll get an exception - an empty array will do.
    – George
    Jan 18, 2018 at 6:39
  • 2
    I can confirm that it does not work without setting $form['#parents'] = array(); beforehand. Maybe add this to your answer? Mar 30, 2018 at 18:55
  • 1
    I'm using this for a field on a node where the user doesn't have permission to edit the node. It's specifically a paragraph field and it is not being fully shown in the custom form. How can I alter the permission so the user has full access to the field, or do I need to allow them to edit the node? Feb 28, 2019 at 16:28
3

Also you can use this code

$entity = \Drupal::entityManager()->getStorage('node')->create([
        'type' => 'article'
      ]);
$form_state->set('node', $entity );       
$form_display = EntityFormDisplay::collectRenderDisplay($entity, 'default');
$form_display->buildForm($entity, $form, $form_state);

I found this solution here

1
  • Drupal::entityManager() is deprecated and shouldn't be used. This comment is for people who want to make the code work for Drupal 8.9/ 9 Jun 29, 2020 at 17:03

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.