2

I have a content type called service request, which have some conditional fields that each might appear or disappear based on an other field value called service type.

I have used conditional field and they work just right but for better user experience I want node form to be called using one of the service types.

so I tried to follow this instructions provided by Jaypan to extend NodeForm, but when overriding form function of NodeForm, it leads to Error: Call to a member function getEntityTypeId() on null in Drupal\Core\Entity\EntityForm->getBaseFormId()

this is how I used to create $form:

class ServiceBuilderForm extends NodeForm {
  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state, $serviceType = NULL) {
    // Added as a fallback in case a developer uses this form without passing
    // $someId:
    if (is_null($serviceType)) {
      $form = [
        '#prefix' => '<p class="error">',
        '#suffix' => '</p>',
        '#markup' => $this->t('Form is missing Service Type which is required'),
      ];
    }
    else {
      $form = parent::form($form, $form_state);
      // Do something with $form and $some_id
    }

    return $form;
  }
}

and in my Controller I have get my form using:

$form = \Drupal::formBuilder()->getForm('\Drupal\{my_module}\Form\ServiceFormBuilder', $serviceType);
2

2 Answers 2

2

After you have integrated the form class in the entity type as form mode

function mymodule_entity_type_build(array &$entity_types) {
  $entity_types['node']->setFormClass('service', 'Drupal\mymodule\Form\ServiceBuilderForm');
}

and invoked the node form in a controller

$form = $this->entityFormBuilder()->getForm($node, 'service');

or without controller directly in a route:

_entity_form: 'node.service'

the entity including the field data is passed to your form

class ServiceBuilderForm extends NodeForm {
  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    $node = $this->entity;
    if ($node->getType() == 'service_request') {
      $field_value = $node->field_service_type->value;
  

and you avoid the error from your question that the entity is null.

1
1

While 4k4 provided a great answer on how to extend an Entity Form and how to instantiate that , for any one who just needs to extend NodeForm class to send new argument to that, they can use a simple code like below :

$node = $this->entityService
  ->getStorage('node')
  ->create(['type' => 'service']);

$form = $this->entityService
  ->getFormObject('node', 'default')
  ->setEntity($node);

$form = $this->myFormBuilder->getForm($form, $questions);//arguments will be passed in form and can be accessed in form using `$form_state->getBuildInfo()['args'][0]`

$form['field_service_type']['widget']['#default_value'] = $rbid;
$form['field_service_type']['widget']['#value'] = $rbid;
$form['#validate'][] = 'my_form_validate';

return [
  'form' => $form,
];

in the code above $this->entityService is an EntityTypeManager object injected to my controller, when I got the usual form object I have set service type field (not recommended cause it is related to widget type).

as mentioned in code as comment arguments passed can be accessed in form using $form_state->getBuildInfo()['args']

So just in mind that if you need to pass arguments to an EntityForm and you are looking for a simple solution, then this code might help.

1

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.