4

I want to build kind of a search form in Drupal 8: On submit, it shall load itself again, but below the results shall rendered. And the URL shall contain the search term, so that the result page is linkable.

This is my minimal example. My current problem ist, that the submitted form value is not fed to $form_state.

public function buildForm(array $form, FormStateInterface $form_state) {

  $form_state->setMethod('get');

  $query = $form_state->getValue('query');
  // Unfortunately, this is empty, even after submit.

  $form['query'] = array(
    '#type' => 'textfield',
    '#title' => $this->t('Query'),
  );
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => $this->t('Search'),
  );

  return $form;
}

public function submitForm(array &$form, FormStateInterface $form_state) {
  $form_state->setRebuild();
  $form_state->setAlwaysProcess(TRUE);
}

When I comment out $form_state->setMethod('get');, it is working as I want: query is readable in the rebuild form and set as default value in the text field.

But with setMethod('get');, query is empty and no default is set.

I thought that $form_state->setAlwaysProcess(TRUE); makes sure the values get processed, even via GET method, as the documentation suggests. But apparently, something is missing. Any ideas, what?

3
  • I'd advise ditching setMethod and instead do an AJAX implementation, and have the commands insert results into an HTML wrapper ready to receive them.
    – Kevin
    Jan 24, 2017 at 18:48
  • Well, sure, I could somehow manually fill in the GET-submitted values into the form. But unlike the minimal example, my actual form is way more complicated and may also change in the future. So I wanted to avoid future work of constantly adapting the GET->form filling and rely solely on the Form API. – But I really wonder: Is there really no way to tell Drupal to treat the GET params like POST params? Jan 25, 2017 at 15:14
  • AJAX is part of the Form API. In the past, I have changed submit buttons to #ajax with properties and callbacks, in them, you can set AJAX commands. But yeah if your actual form is more complex than shown, maybe not. Perhaps $foo = \Drupal::request()->get('url_param')?
    – Kevin
    Jan 25, 2017 at 15:17

1 Answer 1

5

I could solve the problem myself, based on this solution for Drupal 7.

Instead calling the form directly in the router, I define a page callback in my_module.routing.yml.

my_module.form:
  path: '/my-module-form'
  defaults:
    _title: 'My module form'
    _controller: '\Drupal\my_module\Controller\MyModuleController::searchForm'

In MyModuleController, I load my form via the builder.

public function searchForm() {

  $form_state = new FormState();
  $form_state->setMethod('get');
  $form_state->setAlwaysProcess(TRUE);
  $form_state->setRebuild();

  $form = \Drupal::formBuilder()->buildForm('Drupal\my_module\Form\MyModuleSearchForm', $form_state);
  unset($form['form_build_id']);
  unset($form['form_id']);

  return $form;
}

The code of form then is like in the question above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.