Commit cff5bad8 authored by lauriii's avatar lauriii

Issue #2893586 by Manuel Garcia, amateescu, vijaycs85, dawehner: Add #optional...

Issue #2893586 by Manuel Garcia, amateescu, vijaycs85, dawehner: Add #optional support to the Container render element
parent 4aa7190b
......@@ -4,6 +4,7 @@
use Drupal\Component\Utility\Html as HtmlUtility;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
/**
* Provides a render element that wraps child elements in a container.
......@@ -11,6 +12,10 @@
* Surrounds child elements with a <div> and adds attributes such as classes or
* an HTML ID.
*
* Properties:
* - #optional: Indicates whether the container should render when it has no
* visible children. Defaults to FALSE.
*
* Usage example:
* @code
* $form['needs_accommodation'] = array(
......@@ -46,12 +51,14 @@ class Container extends RenderElement {
public function getInfo() {
$class = get_class($this);
return [
'#optional' => FALSE,
'#process' => [
[$class, 'processGroup'],
[$class, 'processContainer'],
],
'#pre_render' => [
[$class, 'preRenderGroup'],
[$class, 'preRenderContainer'],
],
'#theme_wrappers' => ['container'],
];
......@@ -79,4 +86,22 @@ public static function processContainer(&$element, FormStateInterface $form_stat
return $element;
}
/**
* Prevents optional containers from rendering if they have no children.
*
* @param array $element
* An associative array containing the properties and children of the
* container.
*
* @return array
* The modified element.
*/
public static function preRenderContainer($element) {
// Do not render optional container elements if there are no children.
if (empty($element['#printed']) && !empty($element['#optional']) && !Element::getVisibleChildren($element)) {
$element['#printed'] = TRUE;
}
return $element;
}
}
......@@ -489,3 +489,11 @@ form_test.get_form:
_form: '\Drupal\form_test\Form\FormTestGetForm'
requirements:
_access: 'TRUE'
form_test.optional_container:
path: '/form-test/optional-container'
defaults:
_form: '\Drupal\form_test\Form\FormTestOptionalContainerForm'
_title: 'Optional container testing'
requirements:
_access: 'TRUE'
<?php
namespace Drupal\form_test\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Builds a simple form to test the #optional property on #type 'container'.
*/
class FormTestOptionalContainerForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'form_test_optional_container';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
// Empty containers.
$form['empty_optional'] = [
'#type' => 'container',
'#attributes' => ['class' => ['empty_optional']],
'#optional' => TRUE,
];
$form['empty_nonoptional'] = [
'#type' => 'container',
'#attributes' => ['class' => ['empty_nonoptional']],
'#optional' => FALSE,
];
// Non-empty containers
$form['nonempty_optional'] = [
'#type' => 'container',
'#attributes' => ['class' => ['nonempty_optional']],
'#optional' => TRUE,
];
$form['nonempty_optional']['child_1'] = [];
$form['nonempty_nonoptional'] = [
'#type' => 'container',
'#attributes' => ['class' => ['nonempty_nonoptional']],
'#optional' => FALSE,
];
$form['nonempty_nonoptional']['child_2'] = [];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
}
}
<?php
namespace Drupal\Tests\system\Functional\Form;
use Drupal\Tests\BrowserTestBase;
/**
* Tests the container form element for expected behavior.
*
* @group Form
*/
class ElementsContainerTest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['form_test'];
/**
* Tests the #optional container property.
*/
public function testOptionalContainerElements() {
$this->drupalGet('form-test/optional-container');
$assertSession = $this->assertSession();
$assertSession->elementNotExists('css', 'div.empty_optional');
$assertSession->elementExists('css', 'div.empty_nonoptional');
$assertSession->elementExists('css', 'div.nonempty_optional');
$assertSession->elementExists('css', 'div.nonempty_nonoptional');
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment