Problem
I'm creating a custom block class that extends BlockBase. In the overridden blockForm function I'm attempting to add a field with an 'Add More' button. The button successfully issues the callback, but the callback always comes back empty.
I can't tell if the form/form_status are not being passed to the callback, or if the callback is not being correctly called, or what specifically the issue is. Is there a different, correct way to do this in a block that I am unaware of?
Form code is based off an upcoming Example module commit
https://www.drupal.org/node/2720361 β
<?php
/**
* @file
* Contains \Drupal\test_module\Plugin\Block\UniqueTestBlock.
*/
namespace Drupal\test_module\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Block\BlockManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides my custom block.
*
* @Block(
* id = "unique_test_block",
* admin_label = @Translation("Unique Test Block"),
* category = @Translation("Test Blocks")
* )
*/
class UniqueTestBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* The Plugin Block Manager.
*
* @var \Drupal\Core\Block\BlockManagerInterface.
*/
protected $blockManager;
/**
* Constructs a new BlockContentBlock.
*
* @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\Block\BlockManagerInterface $block_manager
* The Plugin Block Manager.
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, BlockManagerInterface $block_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->blockManager = $block_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('plugin.manager.block')
);
}
/**
* {@inheritdoc}
*/
public function build() {
$config = $this->getConfiguration();
$block = array(
'#type' => '#markup',
'#markup' => 'This is a block\'s configuration: <br><pre>' . print_r($config, TRUE) . '</pre>',
);
return $block;
}
/**
* Overrides \Drupal\Core\Block\BlockBase::blockForm().
*
* Adds body and description fields to the block configuration form.
*/
public function blockForm($form, FormStateInterface $form_state) {
$form = parent::blockForm($form, $form_state);
$config = $this->getConfiguration();
$i = 0;
$name_field = $form_state->get('num_names');
$form['#tree'] = TRUE;
$form['names_fieldset'] = [
'#type' => 'fieldset',
'#title' => $this->t('People coming to picnic'),
'#prefix' => '<div id="names-fieldset-wrapper">',
'#suffix' => '</div>',
];
if (empty($name_field)) {
$name_field = $form_state->set('num_names', 1);
}
for ($i = 0; $i < $name_field; $i++) {
$form['names_fieldset']['name'][$i] = [
'#type' => 'textfield',
'#title' => t('Name'),
'#default_value' => $config['names']['name'][$i],
];
}
$form['actions'] = [
'#type' => 'actions',
];
$form['names_fieldset']['actions']['add_name'] = [
'#type' => 'submit',
'#value' => t('Add one more'),
'#submit' => array('::addOne'),
'#ajax' => [
'callback' => '\Drupal\test_module\Plugin\Block\UniqueTestBlock::addmoreCallback',
'wrapper' => 'names-fieldset-wrapper',
],
];
if ($name_field > 1) {
$form['names_fieldset']['actions']['remove_name'] = [
'#type' => 'submit',
'#value' => t('Remove one'),
'#submit' => array('::removeCallback'),
'#ajax' => [
'callback' => '\Drupal\test_module\Plugin\Block\UniqueTestBlock::addmoreCallback',
'wrapper' => 'names-fieldset-wrapper',
]
];
}
$form_state->setCached(FALSE);
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
$this->setConfigurationValue('names', $form_state->getValue('names_fieldset'));
}
/**
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*/
public function addOne(array &$form, FormStateInterface $form_state) {
$name_field = $form_state->get('num_names');
$add_button = $name_field + 1;
$form_state->set('num_names', $add_button);
$form_state->setRebuild();
}
/**
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
* @return mixed
*/
public function addmoreCallback(array &$form, FormStateInterface $form_state) {
$name_field = $form_state->get('num_names');
return $form['names_fieldset'];
}
/**
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*/
public function removeCallback(array &$form, FormStateInterface $form_state) {
$name_field = $form_state->get('num_names');
if ($name_field > 1) {
$remove_button = $name_field - 1;
$form_state->set('num_names', $remove_button);
}
$form_state->setRebuild();
}
}