Programmatically render an exposed filter form

Posted by patrick on Wed, 03/08/2017 - 09:13

If you need to render an exposed form programmatically, you could use the following snippet. The result will be a renderable array for the exposed form.

use Drupal\Core\Form\FormState;
use Drupal\views\Views;
 
$form = [];
$view_id = 'your_view_id';
$display_id = 'your_display_id';
$view = Views::getView($view_id);
if ($view && $view->access($display_id)) {
  $view->setDisplay($display_id);
  $view->initHandlers();
  $form_state = (new FormState())
    ->setStorage([
      'view' => $view,
      'display' => &$view->display_handler->display,
      'rerender' => TRUE,
    ])
    ->setMethod('get')
    ->setAlwaysProcess()
    ->disableRedirect();
  $form_state->set('rerender', NULL);
  $form = \Drupal::formBuilder()->buildForm('\Drupal\views\Form\ViewsExposedForm', $form_state);
}

First we'll get the ViewExecutable object from Views by calling its getView method with the view id. We'll set the correct display and initialize the handlers. Then we'll create a new FormState object that is suitable for use with ViewsExposedForm. Finally, we'll get the FormBuilder service and build the renderable array for the form.

Note: If your view display has no URL (e.g. if it is a master or block display), then the action URL of the form will be the URL of the current page. For the form to work, it needs to be a URL, where your view display is actually shown. So, if you want to show the form on another page than the display, you'd need to adjust the action URL manually. You can do this, by overriding $form['#action'] in the renderable array.

Systems
Drupal 8/9