AJAX form test mock module's AjaxFormBlock.php
is quite a nice example for getting both in one, the form builder and the form interface! Look how it implements FormInterface, ContainerFactoryPluginInterface
to then provide the form from within the block and injecting the form builder via dependency injection to then be used to get the form in the block's build()
method at the same time.
Of course, when you only need the form builder, you don't need to implement the FormInterface
! Then you just need the ContainerFactoryPluginInterface
.
namespace Drupal\ajax_forms_test\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides an AJAX form block.
*
* @Block(
* id = "ajax_forms_test_block",
* admin_label = @Translation("AJAX test form"),
* category = @Translation("Forms")
* )
*/
class AjaxFormBlock extends BlockBase implements FormInterface, ContainerFactoryPluginInterface {
/**
* The form builder.
*
* @var \Drupal\Core\Form\FormBuilderInterface
*/
protected $formBuilder;
/**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* Constructs a new AjaxFormBlock.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Form\FormBuilderInterface $form_builder
* The form builder.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, FormBuilderInterface $form_builder, MessengerInterface $messenger) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->formBuilder = $form_builder;
$this->messenger = $messenger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('form_builder'),
$container->get('messenger')
);
}
/**
* {@inheritdoc}
*/
public function build() {
return $this->formBuilder->getForm($this);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'ajax_forms_test_block';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['test1'] = [
'#type' => 'select',
'#title' => $this->t('Test 1'),
'#required' => TRUE,
'#options' => [
'option1' => $this->t('Option 1'),
'option2' => $this->t('Option 2'),
],
'#ajax' => [
'callback' => '::updateOptions',
'wrapper' => 'edit-test1-wrapper',
],
'#prefix' => '<div id="edit-test1-wrapper">',
'#suffix' => '</div>',
];
$form['actions'] = [
'#type' => 'actions',
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
];
return $form;
}
/**
* Updates the options of a select list.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return array
* The updated form element.
*/
public function updateOptions(array $form, FormStateInterface $form_state) {
$form['test1']['#options']['option1'] = $this->t('Option 1!!!');
$form['test1']['#options'] += [
'option3' => $this->t('Option 3'),
'option4' => $this->t('Option 4'),
];
return $form['test1'];
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->messenger->addStatus('Submission successful.');
}
}
Another nice example is core's SearchBlock.php
.
Also worth checking out the docs on Dependency injection in Plugin (Block).