Container.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. namespace Drupal\Core\Render\Element;
  3. use Drupal\Component\Utility\Html as HtmlUtility;
  4. use Drupal\Core\Form\FormStateInterface;
  5. use Drupal\Core\Render\Element;
  6. /**
  7. * Provides a render element that wraps child elements in a container.
  8. *
  9. * Surrounds child elements with a <div> and adds attributes such as classes or
  10. * an HTML ID.
  11. *
  12. * Properties:
  13. * - #optional: Indicates whether the container should render when it has no
  14. * visible children. Defaults to FALSE.
  15. *
  16. * Usage example:
  17. * @code
  18. * $form['needs_accommodation'] = array(
  19. * '#type' => 'checkbox',
  20. * '#title' => $this->t('Need Special Accommodations?'),
  21. * );
  22. *
  23. * $form['accommodation'] = array(
  24. * '#type' => 'container',
  25. * '#attributes' => array(
  26. * 'class' => 'accommodation',
  27. * ),
  28. * '#states' => array(
  29. * 'invisible' => array(
  30. * 'input[name="needs_accommodation"]' => array('checked' => FALSE),
  31. * ),
  32. * ),
  33. * );
  34. *
  35. * $form['accommodation']['diet'] = array(
  36. * '#type' => 'textfield',
  37. * '#title' => $this->t('Dietary Restrictions'),
  38. * );
  39. * @endcode
  40. *
  41. * @RenderElement("container")
  42. */
  43. class Container extends RenderElement {
  44. /**
  45. * {@inheritdoc}
  46. */
  47. public function getInfo() {
  48. $class = get_class($this);
  49. return [
  50. '#optional' => FALSE,
  51. '#process' => [
  52. [$class, 'processGroup'],
  53. [$class, 'processContainer'],
  54. ],
  55. '#pre_render' => [
  56. [$class, 'preRenderGroup'],
  57. [$class, 'preRenderContainer'],
  58. ],
  59. '#theme_wrappers' => ['container'],
  60. ];
  61. }
  62. /**
  63. * Processes a container element.
  64. *
  65. * @param array $element
  66. * An associative array containing the properties and children of the
  67. * container.
  68. * @param \Drupal\Core\Form\FormStateInterface $form_state
  69. * The current state of the form.
  70. * @param array $complete_form
  71. * The complete form structure.
  72. *
  73. * @return array
  74. * The processed element.
  75. */
  76. public static function processContainer(&$element, FormStateInterface $form_state, &$complete_form) {
  77. // Generate the ID of the element if it's not explicitly given.
  78. if (!isset($element['#id'])) {
  79. $element['#id'] = HtmlUtility::getUniqueId(implode('-', $element['#parents']) . '-wrapper');
  80. }
  81. return $element;
  82. }
  83. /**
  84. * Prevents optional containers from rendering if they have no children.
  85. *
  86. * @param array $element
  87. * An associative array containing the properties and children of the
  88. * container.
  89. *
  90. * @return array
  91. * The modified element.
  92. */
  93. public static function preRenderContainer($element) {
  94. // Do not render optional container elements if there are no children.
  95. if (empty($element['#printed']) && !empty($element['#optional']) && !Element::getVisibleChildren($element)) {
  96. $element['#printed'] = TRUE;
  97. }
  98. return $element;
  99. }
  100. }