Browse Source

Reformat code te be PSR-2 compatible

tags/2.0.0-beta
SonicGD 11 years ago
parent
commit
5cc2dc8dd4
  1. 180
      Alert.php
  2. 8
      BootstrapAsset.php
  3. 16
      BootstrapPluginAsset.php
  4. 14
      BootstrapThemeAsset.php
  5. 61
      Button.php
  6. 167
      ButtonDropdown.php
  7. 104
      ButtonGroup.php
  8. 239
      Carousel.php
  9. 161
      Collapse.php
  10. 140
      Dropdown.php
  11. 395
      Modal.php
  12. 329
      Nav.php
  13. 227
      NavBar.php
  14. 191
      Progress.php
  15. 351
      Tabs.php
  16. 107
      Widget.php

180
Alert.php

@ -46,105 +46,105 @@ use yii\helpers\Html;
*/
class Alert extends Widget
{
/**
* @var string the body content in the alert component. Note that anything between
* the [[begin()]] and [[end()]] calls of the Alert widget will also be treated
* as the body content, and will be rendered before this.
*/
public $body;
/**
* @var array the options for rendering the close button tag.
* The close button is displayed in the header of the modal window. Clicking
* on the button will hide the modal window. If this is null, no close button will be rendered.
*
* The following special options are supported:
*
* - tag: string, the tag name of the button. Defaults to 'button'.
* - label: string, the label of the button. Defaults to '×'.
*
* The rest of the options will be rendered as the HTML attributes of the button tag.
* Please refer to the [Alert documentation](http://getbootstrap.com/components/#alerts)
* for the supported HTML attributes.
*/
public $closeButton = [];
/**
* @var string the body content in the alert component. Note that anything between
* the [[begin()]] and [[end()]] calls of the Alert widget will also be treated
* as the body content, and will be rendered before this.
*/
public $body;
/**
* @var array the options for rendering the close button tag.
* The close button is displayed in the header of the modal window. Clicking
* on the button will hide the modal window. If this is null, no close button will be rendered.
*
* The following special options are supported:
*
* - tag: string, the tag name of the button. Defaults to 'button'.
* - label: string, the label of the button. Defaults to '×'.
*
* The rest of the options will be rendered as the HTML attributes of the button tag.
* Please refer to the [Alert documentation](http://getbootstrap.com/components/#alerts)
* for the supported HTML attributes.
*/
public $closeButton = [];
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
$this->initOptions();
$this->initOptions();
echo Html::beginTag('div', $this->options) . "\n";
echo $this->renderBodyBegin() . "\n";
}
echo Html::beginTag('div', $this->options) . "\n";
echo $this->renderBodyBegin() . "\n";
}
/**
* Renders the widget.
*/
public function run()
{
echo "\n" . $this->renderBodyEnd();
echo "\n" . Html::endTag('div');
/**
* Renders the widget.
*/
public function run()
{
echo "\n" . $this->renderBodyEnd();
echo "\n" . Html::endTag('div');
$this->registerPlugin('alert');
}
$this->registerPlugin('alert');
}
/**
* Renders the close button if any before rendering the content.
* @return string the rendering result
*/
protected function renderBodyBegin()
{
return $this->renderCloseButton();
}
/**
* Renders the close button if any before rendering the content.
* @return string the rendering result
*/
protected function renderBodyBegin()
{
return $this->renderCloseButton();
}
/**
* Renders the alert body (if any).
* @return string the rendering result
*/
protected function renderBodyEnd()
{
return $this->body . "\n";
}
/**
* Renders the alert body (if any).
* @return string the rendering result
*/
protected function renderBodyEnd()
{
return $this->body . "\n";
}
/**
* Renders the close button.
* @return string the rendering result
*/
protected function renderCloseButton()
{
if ($this->closeButton !== null) {
$tag = ArrayHelper::remove($this->closeButton, 'tag', 'button');
$label = ArrayHelper::remove($this->closeButton, 'label', '×');
if ($tag === 'button' && !isset($this->closeButton['type'])) {
$this->closeButton['type'] = 'button';
}
/**
* Renders the close button.
* @return string the rendering result
*/
protected function renderCloseButton()
{
if ($this->closeButton !== null) {
$tag = ArrayHelper::remove($this->closeButton, 'tag', 'button');
$label = ArrayHelper::remove($this->closeButton, 'label', '×');
if ($tag === 'button' && !isset($this->closeButton['type'])) {
$this->closeButton['type'] = 'button';
}
return Html::tag($tag, $label, $this->closeButton);
} else {
return null;
}
}
return Html::tag($tag, $label, $this->closeButton);
} else {
return null;
}
}
/**
* Initializes the widget options.
* This method sets the default values for various options.
*/
protected function initOptions()
{
Html::addCssClass($this->options, 'alert');
Html::addCssClass($this->options, 'fade');
Html::addCssClass($this->options, 'in');
/**
* Initializes the widget options.
* This method sets the default values for various options.
*/
protected function initOptions()
{
Html::addCssClass($this->options, 'alert');
Html::addCssClass($this->options, 'fade');
Html::addCssClass($this->options, 'in');
if ($this->closeButton !== null) {
$this->closeButton = array_merge([
'data-dismiss' => 'alert',
'aria-hidden' => 'true',
'class' => 'close',
], $this->closeButton);
}
}
if ($this->closeButton !== null) {
$this->closeButton = array_merge([
'data-dismiss' => 'alert',
'aria-hidden' => 'true',
'class' => 'close',
], $this->closeButton);
}
}
}

8
BootstrapAsset.php

@ -17,8 +17,8 @@ use yii\web\AssetBundle;
*/
class BootstrapAsset extends AssetBundle
{
public $sourcePath = '@vendor/twbs/bootstrap/dist';
public $css = [
'css/bootstrap.css',
];
public $sourcePath = '@vendor/twbs/bootstrap/dist';
public $css = [
'css/bootstrap.css',
];
}

16
BootstrapPluginAsset.php

@ -17,12 +17,12 @@ use yii\web\AssetBundle;
*/
class BootstrapPluginAsset extends AssetBundle
{
public $sourcePath = '@vendor/twbs/bootstrap/dist';
public $js = [
'js/bootstrap.js',
];
public $depends = [
'yii\web\JqueryAsset',
'yii\bootstrap\BootstrapAsset',
];
public $sourcePath = '@vendor/twbs/bootstrap/dist';
public $js = [
'js/bootstrap.js',
];
public $depends = [
'yii\web\JqueryAsset',
'yii\bootstrap\BootstrapAsset',
];
}

14
BootstrapThemeAsset.php

@ -17,11 +17,11 @@ use yii\web\AssetBundle;
*/
class BootstrapThemeAsset extends AssetBundle
{
public $sourcePath = '@vendor/twbs/bootstrap/dist';
public $css = [
'css/bootstrap-theme.css',
];
public $depends = [
'yii\bootstrap\BootstrapAsset',
];
public $sourcePath = '@vendor/twbs/bootstrap/dist';
public $css = [
'css/bootstrap-theme.css',
];
public $depends = [
'yii\bootstrap\BootstrapAsset',
];
}

61
Button.php

@ -26,37 +26,36 @@ use yii\helpers\Html;
*/
class Button extends Widget
{
/**
* @var string the tag to use to render the button
*/
public $tagName = 'button';
/**
* @var string the button label
*/
public $label = 'Button';
/**
* @var boolean whether the label should be HTML-encoded.
*/
public $encodeLabel = true;
/**
* @var string the tag to use to render the button
*/
public $tagName = 'button';
/**
* @var string the button label
*/
public $label = 'Button';
/**
* @var boolean whether the label should be HTML-encoded.
*/
public $encodeLabel = true;
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
$this->clientOptions = false;
Html::addCssClass($this->options, 'btn');
}
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
$this->clientOptions = false;
Html::addCssClass($this->options, 'btn');
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::tag($this->tagName, $this->encodeLabel ? Html::encode($this->label) : $this->label, $this->options);
$this->registerPlugin('button');
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::tag($this->tagName, $this->encodeLabel ? Html::encode($this->label) : $this->label, $this->options);
$this->registerPlugin('button');
}
}

167
ButtonDropdown.php

@ -33,91 +33,92 @@ use yii\helpers\Html;
*/
class ButtonDropdown extends Widget
{
/**
* @var string the button label
*/
public $label = 'Button';
/**
* @var array the HTML attributes of the button.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $options = [];
/**
* @var array the configuration array for [[Dropdown]].
*/
public $dropdown = [];
/**
* @var boolean whether to display a group of split-styled button group.
*/
public $split = false;
/**
* @var string the tag to use to render the button
*/
public $tagName = 'button';
/**
* @var boolean whether the label should be HTML-encoded.
*/
public $encodeLabel = true;
/**
* @var string the button label
*/
public $label = 'Button';
/**
* @var array the HTML attributes of the button.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $options = [];
/**
* @var array the configuration array for [[Dropdown]].
*/
public $dropdown = [];
/**
* @var boolean whether to display a group of split-styled button group.
*/
public $split = false;
/**
* @var string the tag to use to render the button
*/
public $tagName = 'button';
/**
* @var boolean whether the label should be HTML-encoded.
*/
public $encodeLabel = true;
/**
* Renders the widget.
*/
public function run()
{
echo $this->renderButton() . "\n" . $this->renderDropdown();
$this->registerPlugin('button');
}
/**
* Renders the widget.
*/
public function run()
{
echo $this->renderButton() . "\n" . $this->renderDropdown();
$this->registerPlugin('button');
}
/**
* Generates the button dropdown.
* @return string the rendering result.
*/
protected function renderButton()
{
Html::addCssClass($this->options, 'btn');
$label = $this->label;
if ($this->encodeLabel) {
$label = Html::encode($label);
}
if ($this->split) {
$options = $this->options;
$this->options['data-toggle'] = 'dropdown';
Html::addCssClass($this->options, 'dropdown-toggle');
$splitButton = Button::widget([
'label' => '<span class="caret"></span>',
'encodeLabel' => false,
'options' => $this->options,
'view' => $this->getView(),
]);
} else {
$label .= ' <span class="caret"></span>';
$options = $this->options;
if (!isset($options['href'])) {
$options['href'] = '#';
}
Html::addCssClass($options, 'dropdown-toggle');
$options['data-toggle'] = 'dropdown';
$splitButton = '';
}
/**
* Generates the button dropdown.
* @return string the rendering result.
*/
protected function renderButton()
{
Html::addCssClass($this->options, 'btn');
$label = $this->label;
if ($this->encodeLabel) {
$label = Html::encode($label);
}
if ($this->split) {
$options = $this->options;
$this->options['data-toggle'] = 'dropdown';
Html::addCssClass($this->options, 'dropdown-toggle');
$splitButton = Button::widget([
'label' => '<span class="caret"></span>',
'encodeLabel' => false,
'options' => $this->options,
'view' => $this->getView(),
]);
} else {
$label .= ' <span class="caret"></span>';
$options = $this->options;
if (!isset($options['href'])) {
$options['href'] = '#';
}
Html::addCssClass($options, 'dropdown-toggle');
$options['data-toggle'] = 'dropdown';
$splitButton = '';
}
return Button::widget([
'tagName' => $this->tagName,
'label' => $label,
'options' => $options,
'encodeLabel' => false,
'view' => $this->getView(),
]) . "\n" . $splitButton;
}
return Button::widget([
'tagName' => $this->tagName,
'label' => $label,
'options' => $options,
'encodeLabel' => false,
'view' => $this->getView(),
]) . "\n" . $splitButton;
}
/**
* Generates the dropdown menu.
* @return string the rendering result.
*/
protected function renderDropdown()
{
$config = $this->dropdown;
$config['clientOptions'] = false;
$config['view'] = $this->getView();
return Dropdown::widget($config);
}
/**
* Generates the dropdown menu.
* @return string the rendering result.
*/
protected function renderDropdown()
{
$config = $this->dropdown;
$config['clientOptions'] = false;
$config['view'] = $this->getView();
return Dropdown::widget($config);
}
}

104
ButtonGroup.php

@ -39,60 +39,60 @@ use yii\helpers\Html;
*/
class ButtonGroup extends Widget
{
/**
* @var array list of buttons. Each array element represents a single button
* which can be specified as a string or an array of the following structure:
*
* - label: string, required, the button label.
* - options: array, optional, the HTML attributes of the button.
*/
public $buttons = [];
/**
* @var boolean whether to HTML-encode the button labels.
*/
public $encodeLabels = true;
/**
* @var array list of buttons. Each array element represents a single button
* which can be specified as a string or an array of the following structure:
*
* - label: string, required, the button label.
* - options: array, optional, the HTML attributes of the button.
*/
public $buttons = [];
/**
* @var boolean whether to HTML-encode the button labels.
*/
public $encodeLabels = true;
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'btn-group');
}
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'btn-group');
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::tag('div', $this->renderButtons(), $this->options);
BootstrapAsset::register($this->getView());
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::tag('div', $this->renderButtons(), $this->options);
BootstrapAsset::register($this->getView());
}
/**
* Generates the buttons that compound the group as specified on [[items]].
* @return string the rendering result.
*/
protected function renderButtons()
{
$buttons = [];
foreach ($this->buttons as $button) {
if (is_array($button)) {
$label = ArrayHelper::getValue($button, 'label');
$options = ArrayHelper::getValue($button, 'options');
$buttons[] = Button::widget([
'label' => $label,
'options' => $options,
'encodeLabel' => $this->encodeLabels,
'view' => $this->getView()
]);
} else {
$buttons[] = $button;
}
}
/**
* Generates the buttons that compound the group as specified on [[items]].
* @return string the rendering result.
*/
protected function renderButtons()
{
$buttons = [];
foreach ($this->buttons as $button) {
if (is_array($button)) {
$label = ArrayHelper::getValue($button, 'label');
$options = ArrayHelper::getValue($button, 'options');
$buttons[] = Button::widget([
'label' => $label,
'options' => $options,
'encodeLabel' => $this->encodeLabels,
'view' => $this->getView()
]);
} else {
$buttons[] = $button;
}
}
return implode("\n", $buttons);
}
return implode("\n", $buttons);
}
}

239
Carousel.php

@ -39,132 +39,133 @@ use yii\helpers\Html;
*/
class Carousel extends Widget
{
/**
* @var array|boolean the labels for the previous and the next control buttons.
* If false, it means the previous and the next control buttons should not be displayed.
*/
public $controls = ['&lsaquo;', '&rsaquo;'];
/**
* @var array list of slides in the carousel. Each array element represents a single
* slide with the following structure:
*
* ```php
* [
* // required, slide content (HTML), such as an image tag
* 'content' => '<img src="http://twitter.github.io/bootstrap/assets/img/bootstrap-mdo-sfmoma-01.jpg"/>',
* // optional, the caption (HTML) of the slide
* 'caption' => '<h4>This is title</h4><p>This is the caption text</p>',
* // optional the HTML attributes of the slide container
* 'options' => [],
* ]
* ```
*/
public $items = [];
/**
* @var array|boolean the labels for the previous and the next control buttons.
* If false, it means the previous and the next control buttons should not be displayed.
*/
public $controls = ['&lsaquo;', '&rsaquo;'];
/**
* @var array list of slides in the carousel. Each array element represents a single
* slide with the following structure:
*
* ```php
* [
* // required, slide content (HTML), such as an image tag
* 'content' => '<img src="http://twitter.github.io/bootstrap/assets/img/bootstrap-mdo-sfmoma-01.jpg"/>',
* // optional, the caption (HTML) of the slide
* 'caption' => '<h4>This is title</h4><p>This is the caption text</p>',
* // optional the HTML attributes of the slide container
* 'options' => [],
* ]
* ```
*/
public $items = [];
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'carousel');
}
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'carousel');
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::beginTag('div', $this->options) . "\n";
echo $this->renderIndicators() . "\n";
echo $this->renderItems() . "\n";
echo $this->renderControls() . "\n";
echo Html::endTag('div') . "\n";
$this->registerPlugin('carousel');
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::beginTag('div', $this->options) . "\n";
echo $this->renderIndicators() . "\n";
echo $this->renderItems() . "\n";
echo $this->renderControls() . "\n";
echo Html::endTag('div') . "\n";
$this->registerPlugin('carousel');
}
/**
* Renders carousel indicators.
* @return string the rendering result
*/
public function renderIndicators()
{
$indicators = [];
for ($i = 0, $count = count($this->items); $i < $count; $i++) {
$options = ['data-target' => '#' . $this->options['id'], 'data-slide-to' => $i];
if ($i === 0) {
Html::addCssClass($options, 'active');
}
$indicators[] = Html::tag('li', '', $options);
}
/**
* Renders carousel indicators.
* @return string the rendering result
*/
public function renderIndicators()
{
$indicators = [];
for ($i = 0, $count = count($this->items); $i < $count; $i++) {
$options = ['data-target' => '#' . $this->options['id'], 'data-slide-to' => $i];
if ($i === 0) {
Html::addCssClass($options, 'active');
}
$indicators[] = Html::tag('li', '', $options);
}
return Html::tag('ol', implode("\n", $indicators), ['class' => 'carousel-indicators']);
}
return Html::tag('ol', implode("\n", $indicators), ['class' => 'carousel-indicators']);
}
/**
* Renders carousel items as specified on [[items]].
* @return string the rendering result
*/
public function renderItems()
{
$items = [];
for ($i = 0, $count = count($this->items); $i < $count; $i++) {
$items[] = $this->renderItem($this->items[$i], $i);
}
return Html::tag('div', implode("\n", $items), ['class' => 'carousel-inner']);
}
/**
* Renders carousel items as specified on [[items]].
* @return string the rendering result
*/
public function renderItems()
{
$items = [];
for ($i = 0, $count = count($this->items); $i < $count; $i++) {
$items[] = $this->renderItem($this->items[$i], $i);
}
/**
* Renders a single carousel item
* @param string|array $item a single item from [[items]]
* @param integer $index the item index as the first item should be set to `active`
* @return string the rendering result
* @throws InvalidConfigException if the item is invalid
*/
public function renderItem($item, $index)
{
if (is_string($item)) {
$content = $item;
$caption = null;
$options = [];
} elseif (isset($item['content'])) {
$content = $item['content'];
$caption = ArrayHelper::getValue($item, 'caption');
if ($caption !== null) {
$caption = Html::tag('div', $caption, ['class' => 'carousel-caption']);
}
$options = ArrayHelper::getValue($item, 'options', []);
} else {
throw new InvalidConfigException('The "content" option is required.');
}
return Html::tag('div', implode("\n", $items), ['class' => 'carousel-inner']);
}
Html::addCssClass($options, 'item');
if ($index === 0) {
Html::addCssClass($options, 'active');
}
/**
* Renders a single carousel item
* @param string|array $item a single item from [[items]]
* @param integer $index the item index as the first item should be set to `active`
* @return string the rendering result
* @throws InvalidConfigException if the item is invalid
*/
public function renderItem($item, $index)
{
if (is_string($item)) {
$content = $item;
$caption = null;
$options = [];
} elseif (isset($item['content'])) {
$content = $item['content'];
$caption = ArrayHelper::getValue($item, 'caption');
if ($caption !== null) {
$caption = Html::tag('div', $caption, ['class' => 'carousel-caption']);
}
$options = ArrayHelper::getValue($item, 'options', []);
} else {
throw new InvalidConfigException('The "content" option is required.');
}
return Html::tag('div', $content . "\n" . $caption, $options);
}
Html::addCssClass($options, 'item');
if ($index === 0) {
Html::addCssClass($options, 'active');
}
/**
* Renders previous and next control buttons.
* @throws InvalidConfigException if [[controls]] is invalid.
*/
public function renderControls()
{
if (isset($this->controls[0], $this->controls[1])) {
return Html::a($this->controls[0], '#' . $this->options['id'], [
'class' => 'left carousel-control',
'data-slide' => 'prev',
]) . "\n"
. Html::a($this->controls[1], '#' . $this->options['id'], [
'class' => 'right carousel-control',
'data-slide' => 'next',
]);
} elseif ($this->controls === false) {
return '';
} else {
throw new InvalidConfigException('The "controls" property must be either false or an array of two elements.');
}
}
return Html::tag('div', $content . "\n" . $caption, $options);
}
/**
* Renders previous and next control buttons.
* @throws InvalidConfigException if [[controls]] is invalid.
*/
public function renderControls()
{
if (isset($this->controls[0], $this->controls[1])) {
return Html::a($this->controls[0], '#' . $this->options['id'], [
'class' => 'left carousel-control',
'data-slide' => 'prev',
]) . "\n"
. Html::a($this->controls[1], '#' . $this->options['id'], [
'class' => 'right carousel-control',
'data-slide' => 'next',
]);
} elseif ($this->controls === false) {
return '';
} else {
throw new InvalidConfigException('The "controls" property must be either false or an array of two elements.');
}
}
}

161
Collapse.php

@ -41,95 +41,94 @@ use yii\helpers\Html;
*/
class Collapse extends Widget
{
/**
* @var array list of groups in the collapse widget. Each array element represents a single
* group with the following structure:
*
* ```php
* // item key is the actual group header
* 'Collapsible Group Item #1' => [
* // required, the content (HTML) of the group
* 'content' => 'Anim pariatur cliche...',
* // optional the HTML attributes of the content group
* 'contentOptions' => [],
* // optional the HTML attributes of the group
* 'options' => [],
* ]
* ```
*/
public $items = [];
/**
* @var array list of groups in the collapse widget. Each array element represents a single
* group with the following structure:
*
* ```php
* // item key is the actual group header
* 'Collapsible Group Item #1' => [
* // required, the content (HTML) of the group
* 'content' => 'Anim pariatur cliche...',
* // optional the HTML attributes of the content group
* 'contentOptions' => [],
* // optional the HTML attributes of the group
* 'options' => [],
* ]
* ```
*/
public $items = [];
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'panel-group');
}
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'panel-group');
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::beginTag('div', $this->options) . "\n";
echo $this->renderItems() . "\n";
echo Html::endTag('div') . "\n";
$this->registerPlugin('collapse');
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::beginTag('div', $this->options) . "\n";
echo $this->renderItems() . "\n";
echo Html::endTag('div') . "\n";
$this->registerPlugin('collapse');
}
/**
* Renders collapsible items as specified on [[items]].
* @return string the rendering result
*/
public function renderItems()
{
$items = [];
$index = 0;
foreach ($this->items as $header => $item) {
$options = ArrayHelper::getValue($item, 'options', []);
Html::addCssClass($options, 'panel panel-default');
$items[] = Html::tag('div', $this->renderItem($header, $item, ++$index), $options);
}
/**
* Renders collapsible items as specified on [[items]].
* @return string the rendering result
*/
public function renderItems()
{
$items = [];
$index = 0;
foreach ($this->items as $header => $item) {
$options = ArrayHelper::getValue($item, 'options', []);
Html::addCssClass($options, 'panel panel-default');
$items[] = Html::tag('div', $this->renderItem($header, $item, ++$index), $options);
}
return implode("\n", $items);
}
return implode("\n", $items);
}
/**
* Renders a single collapsible item group
* @param string $header a label of the item group [[items]]
* @param array $item a single item from [[items]]
* @param integer $index the item index as each item group content must have an id
* @return string the rendering result
* @throws InvalidConfigException
*/
public function renderItem($header, $item, $index)
{
if (isset($item['content'])) {
$id = $this->options['id'] . '-collapse' . $index;
$options = ArrayHelper::getValue($item, 'contentOptions', []);
$options['id'] = $id;
Html::addCssClass($options, 'panel-collapse collapse');
/**
* Renders a single collapsible item group
* @param string $header a label of the item group [[items]]
* @param array $item a single item from [[items]]
* @param integer $index the item index as each item group content must have an id
* @return string the rendering result
* @throws InvalidConfigException
*/
public function renderItem($header, $item, $index)
{
if (isset($item['content'])) {
$id = $this->options['id'] . '-collapse' . $index;
$options = ArrayHelper::getValue($item, 'contentOptions', []);
$options['id'] = $id;
Html::addCssClass($options, 'panel-collapse collapse');
$headerToggle = Html::a($header, '#' . $id, [
'class' => 'collapse-toggle',
'data-toggle' => 'collapse',
'data-parent' => '#' . $this->options['id']
]) . "\n";
$headerToggle = Html::a($header, '#' . $id, [
'class' => 'collapse-toggle',
'data-toggle' => 'collapse',
'data-parent' => '#' . $this->options['id']
]) . "\n";
$header = Html::tag('h4', $headerToggle, ['class' => 'panel-title']);
$header = Html::tag('h4', $headerToggle, ['class' => 'panel-title']);
$content = Html::tag('div', $item['content'], ['class' => 'panel-body']) . "\n";
} else {
throw new InvalidConfigException('The "content" option is required.');
}
$group = [];
$content = Html::tag('div', $item['content'], ['class' => 'panel-body']) . "\n";
} else {
throw new InvalidConfigException('The "content" option is required.');
}
$group = [];
$group[] = Html::tag('div', $header, ['class' => 'panel-heading']);
$group[] = Html::tag('div', $content, $options);
$group[] = Html::tag('div', $header, ['class' => 'panel-heading']);
$group[] = Html::tag('div', $content, $options);
return implode("\n", $group);
}
return implode("\n", $group);
}
}

140
Dropdown.php

@ -20,79 +20,79 @@ use yii\helpers\Html;
*/
class Dropdown extends Widget
{
/**
* @var array list of menu items in the dropdown. Each array element can be either an HTML string,
* or an array representing a single menu with the following structure:
*
* - label: string, required, the label of the item link
* - url: string, optional, the url of the item link. Defaults to "#".
* - visible: boolean, optional, whether this menu item is visible. Defaults to true.
* - linkOptions: array, optional, the HTML attributes of the item link.
* - options: array, optional, the HTML attributes of the item.
* - items: array, optional, the submenu items. The structure is the same as this property.
* Note that Bootstrap doesn't support dropdown submenu. You have to add your own CSS styles to support it.
*
* To insert divider use `<li role="presentation" class="divider"></li>`.
*/
public $items = [];
/**
* @var boolean whether the labels for header items should be HTML-encoded.
*/
public $encodeLabels = true;
/**
* @var array list of menu items in the dropdown. Each array element can be either an HTML string,
* or an array representing a single menu with the following structure:
*
* - label: string, required, the label of the item link
* - url: string, optional, the url of the item link. Defaults to "#".
* - visible: boolean, optional, whether this menu item is visible. Defaults to true.
* - linkOptions: array, optional, the HTML attributes of the item link.
* - options: array, optional, the HTML attributes of the item.
* - items: array, optional, the submenu items. The structure is the same as this property.
* Note that Bootstrap doesn't support dropdown submenu. You have to add your own CSS styles to support it.
*
* To insert divider use `<li role="presentation" class="divider"></li>`.
*/
public $items = [];
/**
* @var boolean whether the labels for header items should be HTML-encoded.
*/
public $encodeLabels = true;
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'dropdown-menu');
}
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'dropdown-menu');
}
/**
* Renders the widget.
*/
public function run()
{
echo $this->renderItems($this->items);
$this->registerPlugin('dropdown');
}
/**
* Renders the widget.
*/
public function run()
{
echo $this->renderItems($this->items);
$this->registerPlugin('dropdown');
}
/**
* Renders menu items.
* @param array $items the menu items to be rendered
* @return string the rendering result.
* @throws InvalidConfigException if the label option is not specified in one of the items.
*/
protected function renderItems($items)
{
$lines = [];
foreach ($items as $i => $item) {
if (isset($item['visible']) && !$item['visible']) {
unset($items[$i]);
continue;
}
if (is_string($item)) {
$lines[] = $item;
continue;
}
if (!isset($item['label'])) {
throw new InvalidConfigException("The 'label' option is required.");
}
$label = $this->encodeLabels ? Html::encode($item['label']) : $item['label'];
$options = ArrayHelper::getValue($item, 'options', []);
$linkOptions = ArrayHelper::getValue($item, 'linkOptions', []);
$linkOptions['tabindex'] = '-1';
$content = Html::a($label, ArrayHelper::getValue($item, 'url', '#'), $linkOptions);
if (!empty($item['items'])) {
$content .= $this->renderItems($item['items']);
Html::addCssClass($options, 'dropdown-submenu');
}
$lines[] = Html::tag('li', $content, $options);
}
/**
* Renders menu items.
* @param array $items the menu items to be rendered
* @return string the rendering result.
* @throws InvalidConfigException if the label option is not specified in one of the items.
*/
protected function renderItems($items)
{
$lines = [];
foreach ($items as $i => $item) {
if (isset($item['visible']) && !$item['visible']) {
unset($items[$i]);
continue;
}
if (is_string($item)) {
$lines[] = $item;
continue;
}
if (!isset($item['label'])) {
throw new InvalidConfigException("The 'label' option is required.");
}
$label = $this->encodeLabels ? Html::encode($item['label']) : $item['label'];
$options = ArrayHelper::getValue($item, 'options', []);
$linkOptions = ArrayHelper::getValue($item, 'linkOptions', []);
$linkOptions['tabindex'] = '-1';
$content = Html::a($label, ArrayHelper::getValue($item, 'url', '#'), $linkOptions);
if (!empty($item['items'])) {
$content .= $this->renderItems($item['items']);
Html::addCssClass($options, 'dropdown-submenu');
}
$lines[] = Html::tag('li', $content, $options);
}
return Html::tag('ul', implode("\n", $lines), $this->options);
}
return Html::tag('ul', implode("\n", $lines), $this->options);
}
}

395
Modal.php

@ -35,201 +35,202 @@ use yii\helpers\Html;
*/
class Modal extends Widget
{
const SIZE_LARGE = "modal-lg";
const SIZE_SMALL = "modal-sm";
const SIZE_DEFAULT = "";
/**
* @var string the header content in the modal window.
*/
public $header;
/**
* @var string the footer content in the modal window.
*/
public $footer;
/**
* @var string the modal size. Can be MODAL_LG or MODAL_SM, or empty for default.
*/
public $size;
/**
* @var array the options for rendering the close button tag.
* The close button is displayed in the header of the modal window. Clicking
* on the button will hide the modal window. If this is null, no close button will be rendered.
*
* The following special options are supported:
*
* - tag: string, the tag name of the button. Defaults to 'button'.
* - label: string, the label of the button. Defaults to '&times;'.
*
* The rest of the options will be rendered as the HTML attributes of the button tag.
* Please refer to the [Modal plugin help](http://getbootstrap.com/javascript/#modals)
* for the supported HTML attributes.
*/
public $closeButton = [];
/**
* @var array the options for rendering the toggle button tag.
* The toggle button is used to toggle the visibility of the modal window.
* If this property is null, no toggle button will be rendered.
*
* The following special options are supported:
*
* - tag: string, the tag name of the button. Defaults to 'button'.
* - label: string, the label of the button. Defaults to 'Show'.
*
* The rest of the options will be rendered as the HTML attributes of the button tag.
* Please refer to the [Modal plugin help](http://getbootstrap.com/javascript/#modals)
* for the supported HTML attributes.
*/
public $toggleButton;
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
$this->initOptions();
echo $this->renderToggleButton() . "\n";
echo Html::beginTag('div', $this->options) . "\n";
echo Html::beginTag('div', ['class' => 'modal-dialog ' . $this->size]) . "\n";
echo Html::beginTag('div', ['class' => 'modal-content']) . "\n";
echo $this->renderHeader() . "\n";
echo $this->renderBodyBegin() . "\n";
}
/**
* Renders the widget.
*/
public function run()
{
echo "\n" . $this->renderBodyEnd();
echo "\n" . $this->renderFooter();
echo "\n" . Html::endTag('div'); // modal-content
echo "\n" . Html::endTag('div'); // modal-dialog
echo "\n" . Html::endTag('div');
$this->registerPlugin('modal');
}
/**
* Renders the header HTML markup of the modal
* @return string the rendering result
*/
protected function renderHeader()
{
$button = $this->renderCloseButton();
if ($button !== null) {
$this->header = $button . "\n" . $this->header;
}
if ($this->header !== null) {
return Html::tag('div', "\n" . $this->header . "\n", ['class' => 'modal-header']);
} else {
return null;
}
}
/**
* Renders the opening tag of the modal body.
* @return string the rendering result
*/
protected function renderBodyBegin()
{
return Html::beginTag('div', ['class' => 'modal-body']);
}
/**
* Renders the closing tag of the modal body.
* @return string the rendering result
*/
protected function renderBodyEnd()
{
return Html::endTag('div');
}
/**
* Renders the HTML markup for the footer of the modal
* @return string the rendering result
*/
protected function renderFooter()
{
if ($this->footer !== null) {
return Html::tag('div', "\n" . $this->footer . "\n", ['class' => 'modal-footer']);
} else {
return null;
}
}
/**
* Renders the toggle button.
* @return string the rendering result
*/
protected function renderToggleButton()
{
if ($this->toggleButton !== null) {
$tag = ArrayHelper::remove($this->toggleButton, 'tag', 'button');
$label = ArrayHelper::remove($this->toggleButton, 'label', 'Show');
if ($tag === 'button' && !isset($this->toggleButton['type'])) {
$this->toggleButton['type'] = 'button';
}
return Html::tag($tag, $label, $this->toggleButton);
} else {
return null;
}
}
/**
* Renders the close button.
* @return string the rendering result
*/
protected function renderCloseButton()
{
if ($this->closeButton !== null) {
$tag = ArrayHelper::remove($this->closeButton, 'tag', 'button');
$label = ArrayHelper::remove($this->closeButton, 'label', '&times;');
if ($tag === 'button' && !isset($this->closeButton['type'])) {
$this->closeButton['type'] = 'button';
}
return Html::tag($tag, $label, $this->closeButton);
} else {
return null;
}
}
/**
* Initializes the widget options.
* This method sets the default values for various options.
*/
protected function initOptions()
{
$this->options = array_merge([
'class' => 'fade',
'role' => 'dialog',
'tabindex' => -1,
], $this->options);
Html::addCssClass($this->options, 'modal');
if ($this->clientOptions !== false) {
$this->clientOptions = array_merge(['show' => false], $this->clientOptions);
}
if ($this->closeButton !== null) {
$this->closeButton = array_merge([
'data-dismiss' => 'modal',
'aria-hidden' => 'true',
'class' => 'close',
], $this->closeButton);
}
if ($this->toggleButton !== null) {
$this->toggleButton = array_merge([
'data-toggle' => 'modal',
], $this->toggleButton);
if (!isset($this->toggleButton['data-target']) && !isset($this->toggleButton['href'])) {
$this->toggleButton['data-target'] = '#' . $this->options['id'];
}
}
}
const SIZE_LARGE = "modal-lg";
const SIZE_SMALL = "modal-sm";
const SIZE_DEFAULT = "";
/**
* @var string the header content in the modal window.
*/
public $header;
/**
* @var string the footer content in the modal window.
*/
public $footer;
/**
* @var string the modal size. Can be MODAL_LG or MODAL_SM, or empty for default.
*/
public $size;
/**
* @var array the options for rendering the close button tag.
* The close button is displayed in the header of the modal window. Clicking
* on the button will hide the modal window. If this is null, no close button will be rendered.
*
* The following special options are supported:
*
* - tag: string, the tag name of the button. Defaults to 'button'.
* - label: string, the label of the button. Defaults to '&times;'.
*
* The rest of the options will be rendered as the HTML attributes of the button tag.
* Please refer to the [Modal plugin help](http://getbootstrap.com/javascript/#modals)
* for the supported HTML attributes.
*/
public $closeButton = [];
/**
* @var array the options for rendering the toggle button tag.
* The toggle button is used to toggle the visibility of the modal window.
* If this property is null, no toggle button will be rendered.
*
* The following special options are supported:
*
* - tag: string, the tag name of the button. Defaults to 'button'.
* - label: string, the label of the button. Defaults to 'Show'.
*
* The rest of the options will be rendered as the HTML attributes of the button tag.
* Please refer to the [Modal plugin help](http://getbootstrap.com/javascript/#modals)
* for the supported HTML attributes.
*/
public $toggleButton;
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
$this->initOptions();
echo $this->renderToggleButton() . "\n";
echo Html::beginTag('div', $this->options) . "\n";
echo Html::beginTag('div', ['class' => 'modal-dialog ' . $this->size]) . "\n";
echo Html::beginTag('div', ['class' => 'modal-content']) . "\n";
echo $this->renderHeader() . "\n";
echo $this->renderBodyBegin() . "\n";
}
/**
* Renders the widget.
*/
public function run()
{
echo "\n" . $this->renderBodyEnd();
echo "\n" . $this->renderFooter();
echo "\n" . Html::endTag('div'); // modal-content
echo "\n" . Html::endTag('div'); // modal-dialog
echo "\n" . Html::endTag('div');
$this->registerPlugin('modal');
}
/**
* Renders the header HTML markup of the modal
* @return string the rendering result
*/
protected function renderHeader()
{
$button = $this->renderCloseButton();
if ($button !== null) {
$this->header = $button . "\n" . $this->header;
}
if ($this->header !== null) {
return Html::tag('div', "\n" . $this->header . "\n", ['class' => 'modal-header']);
} else {
return null;
}
}
/**
* Renders the opening tag of the modal body.
* @return string the rendering result
*/
protected function renderBodyBegin()
{
return Html::beginTag('div', ['class' => 'modal-body']);
}
/**
* Renders the closing tag of the modal body.
* @return string the rendering result
*/
protected function renderBodyEnd()
{
return Html::endTag('div');
}
/**
* Renders the HTML markup for the footer of the modal
* @return string the rendering result
*/
protected function renderFooter()
{
if ($this->footer !== null) {
return Html::tag('div', "\n" . $this->footer . "\n", ['class' => 'modal-footer']);
} else {
return null;
}
}
/**
* Renders the toggle button.
* @return string the rendering result
*/
protected function renderToggleButton()
{
if ($this->toggleButton !== null) {
$tag = ArrayHelper::remove($this->toggleButton, 'tag', 'button');
$label = ArrayHelper::remove($this->toggleButton, 'label', 'Show');
if ($tag === 'button' && !isset($this->toggleButton['type'])) {
$this->toggleButton['type'] = 'button';
}
return Html::tag($tag, $label, $this->toggleButton);
} else {
return null;
}
}
/**
* Renders the close button.
* @return string the rendering result
*/
protected function renderCloseButton()
{
if ($this->closeButton !== null) {
$tag = ArrayHelper::remove($this->closeButton, 'tag', 'button');
$label = ArrayHelper::remove($this->closeButton, 'label', '&times;');
if ($tag === 'button' && !isset($this->closeButton['type'])) {
$this->closeButton['type'] = 'button';
}
return Html::tag($tag, $label, $this->closeButton);
} else {
return null;
}
}
/**
* Initializes the widget options.
* This method sets the default values for various options.
*/
protected function initOptions()
{
$this->options = array_merge([
'class' => 'fade',
'role' => 'dialog',
'tabindex' => -1,
], $this->options);
Html::addCssClass($this->options, 'modal');
if ($this->clientOptions !== false) {
$this->clientOptions = array_merge(['show' => false], $this->clientOptions);
}
if ($this->closeButton !== null) {
$this->closeButton = array_merge([
'data-dismiss' => 'modal',
'aria-hidden' => 'true',
'class' => 'close',
], $this->closeButton);
}
if ($this->toggleButton !== null) {
$this->toggleButton = array_merge([
'data-toggle' => 'modal',
], $this->toggleButton);
if (!isset($this->toggleButton['data-target']) && !isset($this->toggleButton['href'])) {
$this->toggleButton['data-target'] = '#' . $this->options['id'];
}
}
}
}

329
Nav.php

@ -48,168 +48,169 @@ use yii\helpers\Html;
*/
class Nav extends Widget
{
/**
* @var array list of items in the nav widget. Each array element represents a single
* menu item which can be either a string or an array with the following structure:
*
* - label: string, required, the nav item label.
* - url: optional, the item's URL. Defaults to "#".
* - visible: boolean, optional, whether this menu item is visible. Defaults to true.
* - linkOptions: array, optional, the HTML attributes of the item's link.
* - options: array, optional, the HTML attributes of the item container (LI).
* - active: boolean, optional, whether the item should be on active state or not.
* - items: array|string, optional, the configuration array for creating a [[Dropdown]] widget,
* or a string representing the dropdown menu. Note that Bootstrap does not support sub-dropdown menus.
*
* If a menu item is a string, it will be rendered directly without HTML encoding.
*/
public $items = [];
/**
* @var boolean whether the nav items labels should be HTML-encoded.
*/
public $encodeLabels = true;
/**
* @var boolean whether to automatically activate items according to whether their route setting
* matches the currently requested route.
* @see isItemActive
*/
public $activateItems = true;
/**
* @var string the route used to determine if a menu item is active or not.
* If not set, it will use the route of the current request.
* @see params
* @see isItemActive
*/
public $route;
/**
* @var array the parameters used to determine if a menu item is active or not.
* If not set, it will use `$_GET`.
* @see route
* @see isItemActive
*/
public $params;
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
if ($this->route === null && Yii::$app->controller !== null) {
$this->route = Yii::$app->controller->getRoute();
}
if ($this->params === null) {
$this->params = Yii::$app->request->getQueryParams();
}
Html::addCssClass($this->options, 'nav');
}
/**
* Renders the widget.
*/
public function run()
{
echo $this->renderItems();
BootstrapAsset::register($this->getView());
}
/**
* Renders widget items.
*/
public function renderItems()
{
$items = [];
foreach ($this->items as $i => $item) {
if (isset($item['visible']) && !$item['visible']) {
unset($items[$i]);
continue;
}
$items[] = $this->renderItem($item);
}
return Html::tag('ul', implode("\n", $items), $this->options);
}
/**
* Renders a widget's item.
* @param string|array $item the item to render.
* @return string the rendering result.
* @throws InvalidConfigException
*/
public function renderItem($item)
{
if (is_string($item)) {
return $item;
}
if (!isset($item['label'])) {
throw new InvalidConfigException("The 'label' option is required.");
}
$label = $this->encodeLabels ? Html::encode($item['label']) : $item['label'];
$options = ArrayHelper::getValue($item, 'options', []);
$items = ArrayHelper::getValue($item, 'items');
$url = ArrayHelper::getValue($item, 'url', '#');
$linkOptions = ArrayHelper::getValue($item, 'linkOptions', []);
if (isset($item['active'])) {
$active = ArrayHelper::remove($item, 'active', false);
} else {
$active = $this->isItemActive($item);
}
if ($active) {
Html::addCssClass($options, 'active');
}
if ($items !== null) {
$linkOptions['data-toggle'] = 'dropdown';
Html::addCssClass($options, 'dropdown');
Html::addCssClass($linkOptions, 'dropdown-toggle');
$label .= ' ' . Html::tag('b', '', ['class' => 'caret']);
if (is_array($items)) {
$items = Dropdown::widget([
'items' => $items,
'encodeLabels' => $this->encodeLabels,
'clientOptions' => false,
'view' => $this->getView(),
]);
}
}
return Html::tag('li', Html::a($label, $url, $linkOptions) . $items, $options);
}
/**
* Checks whether a menu item is active.
* This is done by checking if [[route]] and [[params]] match that specified in the `url` option of the menu item.
* When the `url` option of a menu item is specified in terms of an array, its first element is treated
* as the route for the item and the rest of the elements are the associated parameters.
* Only when its route and parameters match [[route]] and [[params]], respectively, will a menu item
* be considered active.
* @param array $item the menu item to be checked
* @return boolean whether the menu item is active
*/
protected function isItemActive($item)
{
if (isset($item['url']) && is_array($item['url']) && isset($item['url'][0])) {
$route = $item['url'][0];
if ($route[0] !== '/' && Yii::$app->controller) {
$route = Yii::$app->controller->module->getUniqueId() . '/' . $route;
}
if (ltrim($route, '/') !== $this->route) {
return false;
}
unset($item['url']['#']);
if (count($item['url']) > 1) {
foreach (array_splice($item['url'], 1) as $name => $value) {
if ($value !== null && (!isset($this->params[$name]) || $this->params[$name] != $value)) {
return false;
}
}
}
return true;
}
return false;
}
/**
* @var array list of items in the nav widget. Each array element represents a single
* menu item which can be either a string or an array with the following structure:
*
* - label: string, required, the nav item label.
* - url: optional, the item's URL. Defaults to "#".
* - visible: boolean, optional, whether this menu item is visible. Defaults to true.
* - linkOptions: array, optional, the HTML attributes of the item's link.
* - options: array, optional, the HTML attributes of the item container (LI).
* - active: boolean, optional, whether the item should be on active state or not.
* - items: array|string, optional, the configuration array for creating a [[Dropdown]] widget,
* or a string representing the dropdown menu. Note that Bootstrap does not support sub-dropdown menus.
*
* If a menu item is a string, it will be rendered directly without HTML encoding.
*/
public $items = [];
/**
* @var boolean whether the nav items labels should be HTML-encoded.
*/
public $encodeLabels = true;
/**
* @var boolean whether to automatically activate items according to whether their route setting
* matches the currently requested route.
* @see isItemActive
*/
public $activateItems = true;
/**
* @var string the route used to determine if a menu item is active or not.
* If not set, it will use the route of the current request.
* @see params
* @see isItemActive
*/
public $route;
/**
* @var array the parameters used to determine if a menu item is active or not.
* If not set, it will use `$_GET`.
* @see route
* @see isItemActive
*/
public $params;
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
if ($this->route === null && Yii::$app->controller !== null) {
$this->route = Yii::$app->controller->getRoute();
}
if ($this->params === null) {
$this->params = Yii::$app->request->getQueryParams();
}
Html::addCssClass($this->options, 'nav');
}
/**
* Renders the widget.
*/
public function run()
{
echo $this->renderItems();
BootstrapAsset::register($this->getView());
}
/**
* Renders widget items.
*/
public function renderItems()
{
$items = [];
foreach ($this->items as $i => $item) {
if (isset($item['visible']) && !$item['visible']) {
unset($items[$i]);
continue;
}
$items[] = $this->renderItem($item);
}
return Html::tag('ul', implode("\n", $items), $this->options);
}
/**
* Renders a widget's item.
* @param string|array $item the item to render.
* @return string the rendering result.
* @throws InvalidConfigException
*/
public function renderItem($item)
{
if (is_string($item)) {
return $item;
}
if (!isset($item['label'])) {
throw new InvalidConfigException("The 'label' option is required.");
}
$label = $this->encodeLabels ? Html::encode($item['label']) : $item['label'];
$options = ArrayHelper::getValue($item, 'options', []);
$items = ArrayHelper::getValue($item, 'items');
$url = ArrayHelper::getValue($item, 'url', '#');
$linkOptions = ArrayHelper::getValue($item, 'linkOptions', []);
if (isset($item['active'])) {
$active = ArrayHelper::remove($item, 'active', false);
} else {
$active = $this->isItemActive($item);
}
if ($active) {
Html::addCssClass($options, 'active');
}
if ($items !== null) {
$linkOptions['data-toggle'] = 'dropdown';
Html::addCssClass($options, 'dropdown');
Html::addCssClass($linkOptions, 'dropdown-toggle');
$label .= ' ' . Html::tag('b', '', ['class' => 'caret']);
if (is_array($items)) {
$items = Dropdown::widget([
'items' => $items,
'encodeLabels' => $this->encodeLabels,
'clientOptions' => false,
'view' => $this->getView(),
]);
}
}
return Html::tag('li', Html::a($label, $url, $linkOptions) . $items, $options);
}
/**
* Checks whether a menu item is active.
* This is done by checking if [[route]] and [[params]] match that specified in the `url` option of the menu item.
* When the `url` option of a menu item is specified in terms of an array, its first element is treated
* as the route for the item and the rest of the elements are the associated parameters.
* Only when its route and parameters match [[route]] and [[params]], respectively, will a menu item
* be considered active.
* @param array $item the menu item to be checked
* @return boolean whether the menu item is active
*/
protected function isItemActive($item)
{
if (isset($item['url']) && is_array($item['url']) && isset($item['url'][0])) {
$route = $item['url'][0];
if ($route[0] !== '/' && Yii::$app->controller) {
$route = Yii::$app->controller->module->getUniqueId() . '/' . $route;
}
if (ltrim($route, '/') !== $this->route) {
return false;
}
unset($item['url']['#']);
if (count($item['url']) > 1) {
foreach (array_splice($item['url'], 1) as $name => $value) {
if ($value !== null && (!isset($this->params[$name]) || $this->params[$name] != $value)) {
return false;
}
}
}
return true;
}
return false;
}
}

227
NavBar.php

@ -39,120 +39,121 @@ use yii\helpers\Html;
*/
class NavBar extends Widget
{
/**
* @var array the HTML attributes for the widget container tag. The following special options are recognized:
*
* - tag: string, defaults to "nav", the name of the container tag.
*
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $options = [];
/**
* @var array the HTML attributes for the container tag. The following special options are recognized:
*
* - tag: string, defaults to "div", the name of the container tag.
*
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $containerOptions = [];
/**
* @var string the text of the brand. Note that this is not HTML-encoded.
* @see http://getbootstrap.com/components/#navbar
*/
public $brandLabel;
/**
* @param array|string $url the URL for the brand's hyperlink tag. This parameter will be processed by [[Url::to()]]
* and will be used for the "href" attribute of the brand link. If not set, [[\yii\web\Application::homeUrl]] will be used.
*/
public $brandUrl;
/**
* @var array the HTML attributes of the brand link.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $brandOptions = [];
/**
* @var string text to show for screen readers for the button to toggle the navbar.
*/
public $screenReaderToggleText = 'Toggle navigation';
/**
* @var boolean whether the navbar content should be included in an inner div container which by default
* adds left and right padding. Set this to false for a 100% width navbar.
*/
public $renderInnerContainer = true;
/**
* @var array the HTML attributes of the inner container.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $innerContainerOptions = [];
/**
* @var array the HTML attributes for the widget container tag. The following special options are recognized:
*
* - tag: string, defaults to "nav", the name of the container tag.
*
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $options = [];
/**
* @var array the HTML attributes for the container tag. The following special options are recognized:
*
* - tag: string, defaults to "div", the name of the container tag.
*
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $containerOptions = [];
/**
* @var string the text of the brand. Note that this is not HTML-encoded.
* @see http://getbootstrap.com/components/#navbar
*/
public $brandLabel;
/**
* @param array|string $url the URL for the brand's hyperlink tag. This parameter will be processed by [[Url::to()]]
* and will be used for the "href" attribute of the brand link. If not set, [[\yii\web\Application::homeUrl]] will be used.
*/
public $brandUrl;
/**
* @var array the HTML attributes of the brand link.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $brandOptions = [];
/**
* @var string text to show for screen readers for the button to toggle the navbar.
*/
public $screenReaderToggleText = 'Toggle navigation';
/**
* @var boolean whether the navbar content should be included in an inner div container which by default
* adds left and right padding. Set this to false for a 100% width navbar.
*/
public $renderInnerContainer = true;
/**
* @var array the HTML attributes of the inner container.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $innerContainerOptions = [];
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
$this->clientOptions = false;
Html::addCssClass($this->options, 'navbar');
if ($this->options['class'] === 'navbar') {
Html::addCssClass($this->options, 'navbar-default');
}
Html::addCssClass($this->brandOptions, 'navbar-brand');
if (empty($this->options['role'])) {
$this->options['role'] = 'navigation';
}
$options = $this->options;
$tag = ArrayHelper::remove($options, 'tag', 'nav');
echo Html::beginTag($tag, $options);
if ($this->renderInnerContainer) {
if (!isset($this->innerContainerOptions['class'])) {
Html::addCssClass($this->innerContainerOptions, 'container');
}
echo Html::beginTag('div', $this->innerContainerOptions);
}
echo Html::beginTag('div', ['class' => 'navbar-header']);
if (!isset($this->containerOptions['id'])) {
$this->containerOptions['id'] = "{$this->options['id']}-collapse";
}
echo $this->renderToggleButton();
if ($this->brandLabel !== null) {
Html::addCssClass($this->brandOptions, 'navbar-brand');
echo Html::a($this->brandLabel, $this->brandUrl === null ? Yii::$app->homeUrl : $this->brandUrl, $this->brandOptions);
}
echo Html::endTag('div');
Html::addCssClass($this->containerOptions, 'collapse');
Html::addCssClass($this->containerOptions, 'navbar-collapse');
$options = $this->containerOptions;
$tag = ArrayHelper::remove($options, 'tag', 'div');
echo Html::beginTag($tag, $options);
}
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
$this->clientOptions = false;
Html::addCssClass($this->options, 'navbar');
if ($this->options['class'] === 'navbar') {
Html::addCssClass($this->options, 'navbar-default');
}
Html::addCssClass($this->brandOptions, 'navbar-brand');
if (empty($this->options['role'])) {
$this->options['role'] = 'navigation';
}
$options = $this->options;
$tag = ArrayHelper::remove($options, 'tag', 'nav');
echo Html::beginTag($tag, $options);
if ($this->renderInnerContainer) {
if (!isset($this->innerContainerOptions['class'])) {
Html::addCssClass($this->innerContainerOptions, 'container');
}
echo Html::beginTag('div', $this->innerContainerOptions);
}
echo Html::beginTag('div', ['class' => 'navbar-header']);
if (!isset($this->containerOptions['id'])) {
$this->containerOptions['id'] = "{$this->options['id']}-collapse";
}
echo $this->renderToggleButton();
if ($this->brandLabel !== null) {
Html::addCssClass($this->brandOptions, 'navbar-brand');
echo Html::a($this->brandLabel, $this->brandUrl === null ? Yii::$app->homeUrl : $this->brandUrl, $this->brandOptions);
}
echo Html::endTag('div');
Html::addCssClass($this->containerOptions, 'collapse');
Html::addCssClass($this->containerOptions, 'navbar-collapse');
$options = $this->containerOptions;
$tag = ArrayHelper::remove($options, 'tag', 'div');
echo Html::beginTag($tag, $options);
}
/**
* Renders the widget.
*/
public function run()
{
$tag = ArrayHelper::remove($this->containerOptions, 'tag', 'div');
echo Html::endTag($tag);
if ($this->renderInnerContainer) {
echo Html::endTag('div');
}
$tag = ArrayHelper::remove($this->options, 'tag', 'nav');
echo Html::endTag($tag, $this->options);
BootstrapPluginAsset::register($this->getView());
}
/**
* Renders the widget.
*/
public function run()
{
$tag = ArrayHelper::remove($this->containerOptions, 'tag', 'div');
echo Html::endTag($tag);
if ($this->renderInnerContainer) {
echo Html::endTag('div');
}
$tag = ArrayHelper::remove($this->options, 'tag', 'nav');
echo Html::endTag($tag, $this->options);
BootstrapPluginAsset::register($this->getView());
}
/**
* Renders collapsible toggle button.
* @return string the rendering toggle button.
*/
protected function renderToggleButton()
{
$bar = Html::tag('span', '', ['class' => 'icon-bar']);
$screenReader = "<span class=\"sr-only\">{$this->screenReaderToggleText}</span>";
return Html::button("{$screenReader}\n{$bar}\n{$bar}\n{$bar}", [
'class' => 'navbar-toggle',
'data-toggle' => 'collapse',
'data-target' => "#{$this->containerOptions['id']}",
]);
}
/**
* Renders collapsible toggle button.
* @return string the rendering toggle button.
*/
protected function renderToggleButton()
{
$bar = Html::tag('span', '', ['class' => 'icon-bar']);
$screenReader = "<span class=\"sr-only\">{$this->screenReaderToggleText}</span>";
return Html::button("{$screenReader}\n{$bar}\n{$bar}\n{$bar}", [
'class' => 'navbar-toggle',
'data-toggle' => 'collapse',
'data-target' => "#{$this->containerOptions['id']}",
]);
}
}

191
Progress.php

@ -59,105 +59,106 @@ use yii\helpers\Html;
*/
class Progress extends Widget
{
/**
* @var string the button label.
*/
public $label;
/**
* @var integer the amount of progress as a percentage.
*/
public $percent = 0;
/**
* @var array the HTML attributes of the bar.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $barOptions = [];
/**
* @var array a set of bars that are stacked together to form a single progress bar.
* Each bar is an array of the following structure:
*
* ```php
* [
* // required, the amount of progress as a percentage.
* 'percent' => 30,
* // optional, the label to be displayed on the bar
* 'label' => '30%',
* // optional, array, additional HTML attributes for the bar tag
* 'options' => [],
* ]
* ```
*/
public $bars;
/**
* @var string the button label.
*/
public $label;
/**
* @var integer the amount of progress as a percentage.
*/
public $percent = 0;
/**
* @var array the HTML attributes of the bar.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $barOptions = [];
/**
* @var array a set of bars that are stacked together to form a single progress bar.
* Each bar is an array of the following structure:
*
* ```php
* [
* // required, the amount of progress as a percentage.
* 'percent' => 30,
* // optional, the label to be displayed on the bar
* 'label' => '30%',
* // optional, array, additional HTML attributes for the bar tag
* 'options' => [],
* ]
* ```
*/
public $bars;
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'progress');
}
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'progress');
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::beginTag('div', $this->options) . "\n";
echo $this->renderProgress() . "\n";
echo Html::endTag('div') . "\n";
BootstrapAsset::register($this->getView());
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::beginTag('div', $this->options) . "\n";
echo $this->renderProgress() . "\n";
echo Html::endTag('div') . "\n";
BootstrapAsset::register($this->getView());
}
/**
* Renders the progress.
* @return string the rendering result.
* @throws InvalidConfigException if the "percent" option is not set in a stacked progress bar.
*/
protected function renderProgress()
{
if (empty($this->bars)) {
return $this->renderBar($this->percent, $this->label, $this->barOptions);
}
$bars = [];
foreach ($this->bars as $bar) {
$label = ArrayHelper::getValue($bar, 'label', '');
if (!isset($bar['percent'])) {
throw new InvalidConfigException("The 'percent' option is required.");
}
$options = ArrayHelper::getValue($bar, 'options', []);
$bars[] = $this->renderBar($bar['percent'], $label, $options);
}
/**
* Renders the progress.
* @return string the rendering result.
* @throws InvalidConfigException if the "percent" option is not set in a stacked progress bar.
*/
protected function renderProgress()
{
if (empty($this->bars)) {
return $this->renderBar($this->percent, $this->label, $this->barOptions);
}
$bars = [];
foreach ($this->bars as $bar) {
$label = ArrayHelper::getValue($bar, 'label', '');
if (!isset($bar['percent'])) {
throw new InvalidConfigException("The 'percent' option is required.");
}
$options = ArrayHelper::getValue($bar, 'options', []);
$bars[] = $this->renderBar($bar['percent'], $label, $options);
}
return implode("\n", $bars);
}
return implode("\n", $bars);
}
/**
* Generates a bar
* @param integer $percent the percentage of the bar
* @param string $label, optional, the label to display at the bar
* @param array $options the HTML attributes of the bar
* @return string the rendering result.
*/
protected function renderBar($percent, $label = '', $options = [])
{
$defaultOptions = [
'role' => 'progressbar',
'aria-valuenow' => $percent,
'aria-valuemin' => 0,
'aria-valuemax' => 100,
'style' => "width:{$percent}%",
];
$options = array_merge($defaultOptions, $options);
Html::addCssClass($options, 'progress-bar');
/**
* Generates a bar
* @param integer $percent the percentage of the bar
* @param string $label, optional, the label to display at the bar
* @param array $options the HTML attributes of the bar
* @return string the rendering result.
*/
protected function renderBar($percent, $label = '', $options = [])
{
$defaultOptions = [
'role' => 'progressbar',
'aria-valuenow' => $percent,
'aria-valuemin' => 0,
'aria-valuemax' => 100,
'style' => "width:{$percent}%",
];
$options = array_merge($defaultOptions, $options);
Html::addCssClass($options, 'progress-bar');
$out = Html::beginTag('div', $options);
$out .= $label;
$out .= Html::tag('span', \Yii::t('yii', '{percent}% Complete', ['percent' => $percent]), [
'class' => 'sr-only'
]);
$out .= Html::endTag('div');
return $out;
}
$out = Html::beginTag('div', $options);
$out .= $label;
$out .= Html::tag('span', \Yii::t('yii', '{percent}% Complete', ['percent' => $percent]), [
'class' => 'sr-only'
]);
$out .= Html::endTag('div');
return $out;
}
}

351
Tabs.php

@ -53,179 +53,180 @@ use yii\helpers\Html;
*/
class Tabs extends Widget
{
/**
* @var array list of tabs in the tabs widget. Each array element represents a single
* tab with the following structure:
*
* - label: string, required, the tab header label.
* - headerOptions: array, optional, the HTML attributes of the tab header.
* - linkOptions: array, optional, the HTML attributes of the tab header link tags.
* - content: array, required if `items` is not set. The content (HTML) of the tab pane.
* - options: array, optional, the HTML attributes of the tab pane container.
* - active: boolean, optional, whether the item tab header and pane should be visible or not.
* - items: array, optional, if not set then `content` will be required. The `items` specify a dropdown items
* configuration array. Each item can hold two extra keys, besides the above ones:
* * active: boolean, optional, whether the item tab header and pane should be visible or not.
* * content: string, required if `items` is not set. The content (HTML) of the tab pane.
* * contentOptions: optional, array, the HTML attributes of the tab content container.
*/
public $items = [];
/**
* @var array list of HTML attributes for the item container tags. This will be overwritten
* by the "options" set in individual [[items]]. The following special options are recognized:
*
* - tag: string, defaults to "div", the tag name of the item container tags.
*
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $itemOptions = [];
/**
* @var array list of HTML attributes for the header container tags. This will be overwritten
* by the "headerOptions" set in individual [[items]].
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $headerOptions = [];
/**
* @var array list of HTML attributes for the tab header link tags. This will be overwritten
* by the "linkOptions" set in individual [[items]].
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $linkOptions = [];
/**
* @var boolean whether the labels for header items should be HTML-encoded.
*/
public $encodeLabels = true;
/**
* @var string specifies the Bootstrap tab styling.
*/
public $navType = 'nav-tabs';
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'nav ' . $this->navType);
}
/**
* Renders the widget.
*/
public function run()
{
echo $this->renderItems();
$this->registerPlugin('tab');
}
/**
* Renders tab items as specified on [[items]].
* @return string the rendering result.
* @throws InvalidConfigException.
*/
protected function renderItems()
{
$headers = [];
$panes = [];
if (!$this->hasActiveTab() && !empty($this->items)) {
$this->items[0]['active'] = true;
}
foreach ($this->items as $n => $item) {
if (!isset($item['label'])) {
throw new InvalidConfigException("The 'label' option is required.");
}
$label = $this->encodeLabels ? Html::encode($item['label']) : $item['label'];
$headerOptions = array_merge($this->headerOptions, ArrayHelper::getValue($item, 'headerOptions', []));
$linkOptions = array_merge($this->linkOptions, ArrayHelper::getValue($item, 'linkOptions', []));
if (isset($item['items'])) {
$label .= ' <b class="caret"></b>';
Html::addCssClass($headerOptions, 'dropdown');
if ($this->renderDropdown($item['items'], $panes)) {
Html::addCssClass($headerOptions, 'active');
}
Html::addCssClass($linkOptions, 'dropdown-toggle');
$linkOptions['data-toggle'] = 'dropdown';
$header = Html::a($label, "#", $linkOptions) . "\n"
. Dropdown::widget(['items' => $item['items'], 'clientOptions' => false, 'view' => $this->getView()]);
} elseif (isset($item['content'])) {
$options = array_merge($this->itemOptions, ArrayHelper::getValue($item, 'options', []));
$options['id'] = ArrayHelper::getValue($options, 'id', $this->options['id'] . '-tab' . $n);
Html::addCssClass($options, 'tab-pane');
if (ArrayHelper::remove($item, 'active')) {
Html::addCssClass($options, 'active');
Html::addCssClass($headerOptions, 'active');
}
$linkOptions['data-toggle'] = 'tab';
$header = Html::a($label, '#' . $options['id'], $linkOptions);
$panes[] = Html::tag('div', $item['content'], $options);
} else {
throw new InvalidConfigException("Either the 'content' or 'items' option must be set.");
}
$headers[] = Html::tag('li', $header, $headerOptions);
}
return Html::tag('ul', implode("\n", $headers), $this->options) . "\n"
. Html::tag('div', implode("\n", $panes), ['class' => 'tab-content']);
}
/**
* @return boolean if there's active tab defined
*/
protected function hasActiveTab()
{
foreach ($this->items as $item) {
if (isset($item['active']) && $item['active']===true) {
return true;
}
}
return false;
}
/**
* Normalizes dropdown item options by removing tab specific keys `content` and `contentOptions`, and also
* configure `panes` accordingly.
* @param array $items the dropdown items configuration.
* @param array $panes the panes reference array.
* @return boolean whether any of the dropdown items is `active` or not.
* @throws InvalidConfigException
*/
protected function renderDropdown(&$items, &$panes)
{
$itemActive = false;
foreach ($items as $n => &$item) {
if (is_string($item)) {
continue;
}
if (!isset($item['content'])) {
throw new InvalidConfigException("The 'content' option is required.");
}
$content = ArrayHelper::remove($item, 'content');
$options = ArrayHelper::remove($item, 'contentOptions', []);
Html::addCssClass($options, 'tab-pane');
if (ArrayHelper::remove($item, 'active')) {
Html::addCssClass($options, 'active');
Html::addCssClass($item['options'], 'active');
$itemActive = true;
}
$options['id'] = ArrayHelper::getValue($options, 'id', $this->options['id'] . '-dd-tab' . $n);
$item['url'] = '#' . $options['id'];
$item['linkOptions']['data-toggle'] = 'tab';
$panes[] = Html::tag('div', $content, $options);
unset($item);
}
return $itemActive;
}
/**
* @var array list of tabs in the tabs widget. Each array element represents a single
* tab with the following structure:
*
* - label: string, required, the tab header label.
* - headerOptions: array, optional, the HTML attributes of the tab header.
* - linkOptions: array, optional, the HTML attributes of the tab header link tags.
* - content: array, required if `items` is not set. The content (HTML) of the tab pane.
* - options: array, optional, the HTML attributes of the tab pane container.
* - active: boolean, optional, whether the item tab header and pane should be visible or not.
* - items: array, optional, if not set then `content` will be required. The `items` specify a dropdown items
* configuration array. Each item can hold two extra keys, besides the above ones:
* * active: boolean, optional, whether the item tab header and pane should be visible or not.
* * content: string, required if `items` is not set. The content (HTML) of the tab pane.
* * contentOptions: optional, array, the HTML attributes of the tab content container.
*/
public $items = [];
/**
* @var array list of HTML attributes for the item container tags. This will be overwritten
* by the "options" set in individual [[items]]. The following special options are recognized:
*
* - tag: string, defaults to "div", the tag name of the item container tags.
*
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $itemOptions = [];
/**
* @var array list of HTML attributes for the header container tags. This will be overwritten
* by the "headerOptions" set in individual [[items]].
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $headerOptions = [];
/**
* @var array list of HTML attributes for the tab header link tags. This will be overwritten
* by the "linkOptions" set in individual [[items]].
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $linkOptions = [];
/**
* @var boolean whether the labels for header items should be HTML-encoded.
*/
public $encodeLabels = true;
/**
* @var string specifies the Bootstrap tab styling.
*/
public $navType = 'nav-tabs';
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'nav ' . $this->navType);
}
/**
* Renders the widget.
*/
public function run()
{
echo $this->renderItems();
$this->registerPlugin('tab');
}
/**
* Renders tab items as specified on [[items]].
* @return string the rendering result.
* @throws InvalidConfigException.
*/
protected function renderItems()
{
$headers = [];
$panes = [];
if (!$this->hasActiveTab() && !empty($this->items)) {
$this->items[0]['active'] = true;
}
foreach ($this->items as $n => $item) {
if (!isset($item['label'])) {
throw new InvalidConfigException("The 'label' option is required.");
}
$label = $this->encodeLabels ? Html::encode($item['label']) : $item['label'];
$headerOptions = array_merge($this->headerOptions, ArrayHelper::getValue($item, 'headerOptions', []));
$linkOptions = array_merge($this->linkOptions, ArrayHelper::getValue($item, 'linkOptions', []));
if (isset($item['items'])) {
$label .= ' <b class="caret"></b>';
Html::addCssClass($headerOptions, 'dropdown');
if ($this->renderDropdown($item['items'], $panes)) {
Html::addCssClass($headerOptions, 'active');
}
Html::addCssClass($linkOptions, 'dropdown-toggle');
$linkOptions['data-toggle'] = 'dropdown';
$header = Html::a($label, "#", $linkOptions) . "\n"
. Dropdown::widget(['items' => $item['items'], 'clientOptions' => false, 'view' => $this->getView()]);
} elseif (isset($item['content'])) {
$options = array_merge($this->itemOptions, ArrayHelper::getValue($item, 'options', []));
$options['id'] = ArrayHelper::getValue($options, 'id', $this->options['id'] . '-tab' . $n);
Html::addCssClass($options, 'tab-pane');
if (ArrayHelper::remove($item, 'active')) {
Html::addCssClass($options, 'active');
Html::addCssClass($headerOptions, 'active');
}
$linkOptions['data-toggle'] = 'tab';
$header = Html::a($label, '#' . $options['id'], $linkOptions);
$panes[] = Html::tag('div', $item['content'], $options);
} else {
throw new InvalidConfigException("Either the 'content' or 'items' option must be set.");
}
$headers[] = Html::tag('li', $header, $headerOptions);
}
return Html::tag('ul', implode("\n", $headers), $this->options) . "\n"
. Html::tag('div', implode("\n", $panes), ['class' => 'tab-content']);
}
/**
* @return boolean if there's active tab defined
*/
protected function hasActiveTab()
{
foreach ($this->items as $item) {
if (isset($item['active']) && $item['active']===true) {
return true;
}
}
return false;
}
/**
* Normalizes dropdown item options by removing tab specific keys `content` and `contentOptions`, and also
* configure `panes` accordingly.
* @param array $items the dropdown items configuration.
* @param array $panes the panes reference array.
* @return boolean whether any of the dropdown items is `active` or not.
* @throws InvalidConfigException
*/
protected function renderDropdown(&$items, &$panes)
{
$itemActive = false;
foreach ($items as $n => &$item) {
if (is_string($item)) {
continue;
}
if (!isset($item['content'])) {
throw new InvalidConfigException("The 'content' option is required.");
}
$content = ArrayHelper::remove($item, 'content');
$options = ArrayHelper::remove($item, 'contentOptions', []);
Html::addCssClass($options, 'tab-pane');
if (ArrayHelper::remove($item, 'active')) {
Html::addCssClass($options, 'active');
Html::addCssClass($item['options'], 'active');
$itemActive = true;
}
$options['id'] = ArrayHelper::getValue($options, 'id', $this->options['id'] . '-dd-tab' . $n);
$item['url'] = '#' . $options['id'];
$item['linkOptions']['data-toggle'] = 'tab';
$panes[] = Html::tag('div', $content, $options);
unset($item);
}
return $itemActive;
}
}

107
Widget.php

@ -19,64 +19,63 @@ use yii\helpers\Json;
*/
class Widget extends \yii\base\Widget
{
/**
* @var array the HTML attributes for the widget container tag.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $options = [];
/**
* @var array the options for the underlying Bootstrap JS plugin.
* Please refer to the corresponding Bootstrap plugin Web page for possible options.
* For example, [this page](http://getbootstrap.com/javascript/#modals) shows
* how to use the "Modal" plugin and the supported options (e.g. "remote").
*/
public $clientOptions = [];
/**
* @var array the event handlers for the underlying Bootstrap JS plugin.
* Please refer to the corresponding Bootstrap plugin Web page for possible events.
* For example, [this page](http://getbootstrap.com/javascript/#modals) shows
* how to use the "Modal" plugin and the supported events (e.g. "shown").
*/
public $clientEvents = [];
/**
* @var array the HTML attributes for the widget container tag.
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $options = [];
/**
* @var array the options for the underlying Bootstrap JS plugin.
* Please refer to the corresponding Bootstrap plugin Web page for possible options.
* For example, [this page](http://getbootstrap.com/javascript/#modals) shows
* how to use the "Modal" plugin and the supported options (e.g. "remote").
*/
public $clientOptions = [];
/**
* @var array the event handlers for the underlying Bootstrap JS plugin.
* Please refer to the corresponding Bootstrap plugin Web page for possible events.
* For example, [this page](http://getbootstrap.com/javascript/#modals) shows
* how to use the "Modal" plugin and the supported events (e.g. "shown").
*/
public $clientEvents = [];
/**
* Initializes the widget.
* This method will register the bootstrap asset bundle. If you override this method,
* make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
if (!isset($this->options['id'])) {
$this->options['id'] = $this->getId();
}
}
/**
* Initializes the widget.
* This method will register the bootstrap asset bundle. If you override this method,
* make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
if (!isset($this->options['id'])) {
$this->options['id'] = $this->getId();
}
}
/**
* Registers a specific Bootstrap plugin and the related events
* @param string $name the name of the Bootstrap plugin
*/
protected function registerPlugin($name)
{
$view = $this->getView();
/**
* Registers a specific Bootstrap plugin and the related events
* @param string $name the name of the Bootstrap plugin
*/
protected function registerPlugin($name)
{
$view = $this->getView();
BootstrapPluginAsset::register($view);
BootstrapPluginAsset::register($view);
$id = $this->options['id'];
$id = $this->options['id'];
if ($this->clientOptions !== false) {
$options = empty($this->clientOptions) ? '' : Json::encode($this->clientOptions);
$js = "jQuery('#$id').$name($options);";
$view->registerJs($js);
}
if ($this->clientOptions !== false) {
$options = empty($this->clientOptions) ? '' : Json::encode($this->clientOptions);
$js = "jQuery('#$id').$name($options);";
$view->registerJs($js);
}
if (!empty($this->clientEvents)) {
$js = [];
foreach ($this->clientEvents as $event => $handler) {
$js[] = "jQuery('#$id').on('$event', $handler);";
}
$view->registerJs(implode("\n", $js));
}
}
if (!empty($this->clientEvents)) {
$js = [];
foreach ($this->clientEvents as $event => $handler) {
$js[] = "jQuery('#$id').on('$event', $handler);";
}
$view->registerJs(implode("\n", $js));
}
}
}

Loading…
Cancel
Save