You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
4.6KB

  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\bootstrap;
  8. use yii\base\InvalidConfigException;
  9. use yii\helpers\ArrayHelper;
  10. use yii\helpers\Html;
  11. /**
  12. * Collapse renders an accordion bootstrap javascript component.
  13. *
  14. * For example:
  15. *
  16. * ```php
  17. * echo Collapse::widget([
  18. * 'items' => [
  19. * // equivalent to the above
  20. * [
  21. * 'label' => 'Collapsible Group Item #1',
  22. * 'content' => 'Anim pariatur cliche...',
  23. * // open its content by default
  24. * 'contentOptions' => ['class' => 'in']
  25. * ],
  26. * // another group item
  27. * [
  28. * 'label' => 'Collapsible Group Item #1',
  29. * 'content' => 'Anim pariatur cliche...',
  30. * 'contentOptions' => [...],
  31. * 'options' => [...],
  32. * ],
  33. * ]
  34. * ]);
  35. * ```
  36. *
  37. * @see http://getbootstrap.com/javascript/#collapse
  38. * @author Antonio Ramirez <amigo.cobos@gmail.com>
  39. * @since 2.0
  40. */
  41. class Collapse extends Widget
  42. {
  43. /**
  44. * @var array list of groups in the collapse widget. Each array element represents a single
  45. * group with the following structure:
  46. *
  47. * - label: string, required, the group header label.
  48. * - encode: boolean, optional, whether this label should be HTML-encoded. This param will override
  49. * global `$this->encodeLabels` param.
  50. * - content: string, required, the content (HTML) of the group
  51. * - options: array, optional, the HTML attributes of the group
  52. * - contentOptions: optional, the HTML attributes of the group's content
  53. */
  54. public $items = [];
  55. /**
  56. * @var boolean whether the labels for header items should be HTML-encoded.
  57. */
  58. public $encodeLabels = true;
  59. /**
  60. * Initializes the widget.
  61. */
  62. public function init()
  63. {
  64. parent::init();
  65. Html::addCssClass($this->options, 'panel-group');
  66. }
  67. /**
  68. * Renders the widget.
  69. */
  70. public function run()
  71. {
  72. $this->registerPlugin('collapse');
  73. return implode("\n", [
  74. Html::beginTag('div', $this->options),
  75. $this->renderItems(),
  76. Html::endTag('div')
  77. ]) . "\n";
  78. }
  79. /**
  80. * Renders collapsible items as specified on [[items]].
  81. * @throws InvalidConfigException if label isn't specified
  82. * @return string the rendering result
  83. */
  84. public function renderItems()
  85. {
  86. $items = [];
  87. $index = 0;
  88. foreach ($this->items as $item) {
  89. if (!array_key_exists('label', $item)) {
  90. throw new InvalidConfigException("The 'label' option is required.");
  91. }
  92. $header = $item['label'];
  93. $options = ArrayHelper::getValue($item, 'options', []);
  94. Html::addCssClass($options, 'panel panel-default');
  95. $items[] = Html::tag('div', $this->renderItem($header, $item, ++$index), $options);
  96. }
  97. return implode("\n", $items);
  98. }
  99. /**
  100. * Renders a single collapsible item group
  101. * @param string $header a label of the item group [[items]]
  102. * @param array $item a single item from [[items]]
  103. * @param integer $index the item index as each item group content must have an id
  104. * @return string the rendering result
  105. * @throws InvalidConfigException
  106. */
  107. public function renderItem($header, $item, $index)
  108. {
  109. if (array_key_exists('content', $item)) {
  110. $id = $this->options['id'] . '-collapse' . $index;
  111. $options = ArrayHelper::getValue($item, 'contentOptions', []);
  112. $options['id'] = $id;
  113. Html::addCssClass($options, 'panel-collapse collapse');
  114. $encodeLabel = isset($item['encode']) ? $item['encode'] : $this->encodeLabels;
  115. if ($encodeLabel) {
  116. $header = Html::encode($header);
  117. }
  118. $headerToggle = Html::a($header, '#' . $id, [
  119. 'class' => 'collapse-toggle',
  120. 'data-toggle' => 'collapse',
  121. 'data-parent' => '#' . $this->options['id']
  122. ]) . "\n";
  123. $header = Html::tag('h4', $headerToggle, ['class' => 'panel-title']);
  124. $content = Html::tag('div', $item['content'], ['class' => 'panel-body']) . "\n";
  125. } else {
  126. throw new InvalidConfigException('The "content" option is required.');
  127. }
  128. $group = [];
  129. $group[] = Html::tag('div', $header, ['class' => 'panel-heading']);
  130. $group[] = Html::tag('div', $content, $options);
  131. return implode("\n", $group);
  132. }
  133. }