I have a form, which contains an additional field. And I want to initiate the field via the form constructor.

class ServicesForm extends FormBase {

    private $service_type;

    public function __constructor($_service_type){
        $this->service_type = $_service_type;

The form is created in a controller.

class ServicesController extends ControllerBase {

    public function getServices($service_type){
        $data['form'] = \Drupal::formBuilder()->getForm('\Drupal\palom_services\Form\ServicesForm');

        return $data;

Could you clarify me, how to pass the parameter $service_type to the form inside the controller method ?

Maybe, should I do it without FormBuilder and getForm ?


Just add it to your form's buildForm method signature:

public function buildForm(array $form, FormStateInterface $form_state, $arg = NULL) {
  // Use $arg

Then literally pass it to the form builder's getForm method:

$data['form'] = \Drupal::formBuilder()->getForm('\Drupal\palom_services\Form\ServicesForm', $service_type);
| improve this answer | |

I have tried the Clive's solution, however, it breaks the interface of FormInterface.

In the \Drupal::formBuilder()->getForm() method, the code is the following:

  public function getForm($form_arg) {
    $form_state = new FormState();

    $args = func_get_args();
    // Remove $form_arg from the arguments.
    $form_state->addBuildInfo('args', array_values($args));

    return $this->buildForm($form_arg, $form_state);

So you don't need to modify the signature of buildForm(), you should access these values from $form_state.

It should be usable this way: $form_state->getBuildInfo()['args']

| improve this answer | |
  • Really good and clean method. – Christian Oct 24 '19 at 0:40

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.