Commit 17b1e5d2 by Qiang Xue

Fixes issue #234: Added Html::addCssClass() and removeCssClass().

parent 0b8d239a
...@@ -140,7 +140,7 @@ class Alert extends Widget ...@@ -140,7 +140,7 @@ class Alert extends Widget
'class' => 'fade in', 'class' => 'fade in',
), $this->options); ), $this->options);
$this->addCssClass($this->options, 'alert'); Html::addCssClass($this->options, 'alert');
if ($this->closeButton !== null) { if ($this->closeButton !== null) {
$this->closeButton = array_merge(array( $this->closeButton = array_merge(array(
......
...@@ -48,7 +48,7 @@ class Button extends Widget ...@@ -48,7 +48,7 @@ class Button extends Widget
{ {
parent::init(); parent::init();
$this->clientOptions = false; $this->clientOptions = false;
$this->addCssClass($this->options, 'btn'); Html::addCssClass($this->options, 'btn');
} }
/** /**
......
...@@ -64,7 +64,7 @@ class ButtonDropdown extends Widget ...@@ -64,7 +64,7 @@ class ButtonDropdown extends Widget
public function init() public function init()
{ {
parent::init(); parent::init();
$this->addCssClass($this->options, 'btn-group'); Html::addCssClass($this->options, 'btn-group');
} }
/** /**
...@@ -85,12 +85,12 @@ class ButtonDropdown extends Widget ...@@ -85,12 +85,12 @@ class ButtonDropdown extends Widget
*/ */
protected function renderButton() protected function renderButton()
{ {
$this->addCssClass($this->buttonOptions, 'btn'); Html::addCssClass($this->buttonOptions, 'btn');
if ($this->split) { if ($this->split) {
$tag = 'button'; $tag = 'button';
$options = $this->buttonOptions; $options = $this->buttonOptions;
$this->buttonOptions['data-toggle'] = 'dropdown'; $this->buttonOptions['data-toggle'] = 'dropdown';
$this->addCssClass($this->buttonOptions, 'dropdown-toggle'); Html::addCssClass($this->buttonOptions, 'dropdown-toggle');
$splitButton = Button::widget(array( $splitButton = Button::widget(array(
'label' => '<span class="caret"></span>', 'label' => '<span class="caret"></span>',
'encodeLabel' => false, 'encodeLabel' => false,
...@@ -103,7 +103,7 @@ class ButtonDropdown extends Widget ...@@ -103,7 +103,7 @@ class ButtonDropdown extends Widget
if (!isset($options['href'])) { if (!isset($options['href'])) {
$options['href'] = '#'; $options['href'] = '#';
} }
$this->addCssClass($options, 'dropdown-toggle'); Html::addCssClass($options, 'dropdown-toggle');
$options['data-toggle'] = 'dropdown'; $options['data-toggle'] = 'dropdown';
$splitButton = ''; $splitButton = '';
} }
......
...@@ -61,7 +61,7 @@ class ButtonGroup extends Widget ...@@ -61,7 +61,7 @@ class ButtonGroup extends Widget
{ {
parent::init(); parent::init();
$this->clientOptions = false; $this->clientOptions = false;
$this->addCssClass($this->options, 'btn-group'); Html::addCssClass($this->options, 'btn-group');
} }
/** /**
......
...@@ -70,7 +70,7 @@ class Carousel extends Widget ...@@ -70,7 +70,7 @@ class Carousel extends Widget
public function init() public function init()
{ {
parent::init(); parent::init();
$this->addCssClass($this->options, 'carousel'); Html::addCssClass($this->options, 'carousel');
} }
/** /**
...@@ -96,7 +96,7 @@ class Carousel extends Widget ...@@ -96,7 +96,7 @@ class Carousel extends Widget
for ($i = 0, $count = count($this->items); $i < $count; $i++) { for ($i = 0, $count = count($this->items); $i < $count; $i++) {
$options = array('data-target' => '#' . $this->options['id'], 'data-slide-to' => $i); $options = array('data-target' => '#' . $this->options['id'], 'data-slide-to' => $i);
if ($i === 0) { if ($i === 0) {
$this->addCssClass($options, 'active'); Html::addCssClass($options, 'active');
} }
$indicators[] = Html::tag('li', '', $options); $indicators[] = Html::tag('li', '', $options);
} }
...@@ -140,9 +140,9 @@ class Carousel extends Widget ...@@ -140,9 +140,9 @@ class Carousel extends Widget
throw new InvalidConfigException('The "content" option is required.'); throw new InvalidConfigException('The "content" option is required.');
} }
$this->addCssClass($options, 'item'); Html::addCssClass($options, 'item');
if ($index === 0) { if ($index === 0) {
$this->addCssClass($options, 'active'); Html::addCssClass($options, 'active');
} }
return Html::tag('div', $content . "\n" . $caption, $options); return Html::tag('div', $content . "\n" . $caption, $options);
......
...@@ -66,7 +66,7 @@ class Collapse extends Widget ...@@ -66,7 +66,7 @@ class Collapse extends Widget
public function init() public function init()
{ {
parent::init(); parent::init();
$this->addCssClass($this->options, 'accordion'); Html::addCssClass($this->options, 'accordion');
} }
/** /**
...@@ -90,7 +90,7 @@ class Collapse extends Widget ...@@ -90,7 +90,7 @@ class Collapse extends Widget
$index = 0; $index = 0;
foreach ($this->items as $header => $item) { foreach ($this->items as $header => $item) {
$options = ArrayHelper::getValue($item, 'options', array()); $options = ArrayHelper::getValue($item, 'options', array());
$this->addCssClass($options, 'accordion-group'); Html::addCssClass($options, 'accordion-group');
$items[] = Html::tag('div', $this->renderItem($header, $item, ++$index), $options); $items[] = Html::tag('div', $this->renderItem($header, $item, ++$index), $options);
} }
...@@ -111,7 +111,7 @@ class Collapse extends Widget ...@@ -111,7 +111,7 @@ class Collapse extends Widget
$id = $this->options['id'] . '-collapse' . $index; $id = $this->options['id'] . '-collapse' . $index;
$options = ArrayHelper::getValue($item, 'contentOptions', array()); $options = ArrayHelper::getValue($item, 'contentOptions', array());
$options['id'] = $id; $options['id'] = $id;
$this->addCssClass($options, 'accordion-body collapse'); Html::addCssClass($options, 'accordion-body collapse');
$header = Html::a($header, '#' . $id, array( $header = Html::a($header, '#' . $id, array(
'class' => 'accordion-toggle', 'class' => 'accordion-toggle',
......
...@@ -46,7 +46,7 @@ class Dropdown extends Widget ...@@ -46,7 +46,7 @@ class Dropdown extends Widget
public function init() public function init()
{ {
parent::init(); parent::init();
$this->addCssClass($this->options, 'dropdown-menu'); Html::addCssClass($this->options, 'dropdown-menu');
} }
/** /**
...@@ -81,7 +81,7 @@ class Dropdown extends Widget ...@@ -81,7 +81,7 @@ class Dropdown extends Widget
$linkOptions['tabindex'] = '-1'; $linkOptions['tabindex'] = '-1';
if (isset($item['items'])) { if (isset($item['items'])) {
$this->addCssClass($options, 'dropdown-submenu'); Html::addCssClass($options, 'dropdown-submenu');
$content = Html::a($label, '#', $linkOptions) . $this->renderItems($item['items']); $content = Html::a($label, '#', $linkOptions) . $this->renderItems($item['items']);
} else { } else {
$content = Html::a($label, ArrayHelper::getValue($item, 'url', '#'), $linkOptions); $content = Html::a($label, ArrayHelper::getValue($item, 'url', '#'), $linkOptions);
......
...@@ -197,7 +197,7 @@ class Modal extends Widget ...@@ -197,7 +197,7 @@ class Modal extends Widget
$this->options = array_merge(array( $this->options = array_merge(array(
'class' => 'modal hide', 'class' => 'modal hide',
), $this->options); ), $this->options);
$this->addCssClass($this->options, 'modal'); Html::addCssClass($this->options, 'modal');
$this->clientOptions = array_merge(array( $this->clientOptions = array_merge(array(
'show' => false, 'show' => false,
......
...@@ -79,7 +79,7 @@ class Nav extends Widget ...@@ -79,7 +79,7 @@ class Nav extends Widget
public function init() public function init()
{ {
parent::init(); parent::init();
$this->addCssClass($this->options, 'nav'); Html::addCssClass($this->options, 'nav');
} }
/** /**
...@@ -125,13 +125,13 @@ class Nav extends Widget ...@@ -125,13 +125,13 @@ class Nav extends Widget
$linkOptions = ArrayHelper::getValue($item, 'linkOptions', array()); $linkOptions = ArrayHelper::getValue($item, 'linkOptions', array());
if (ArrayHelper::getValue($item, 'active')) { if (ArrayHelper::getValue($item, 'active')) {
$this->addCssClass($options, 'active'); Html::addCssClass($options, 'active');
} }
if ($items !== null) { if ($items !== null) {
$linkOptions['data-toggle'] = 'dropdown'; $linkOptions['data-toggle'] = 'dropdown';
$this->addCssClass($options, 'dropdown'); Html::addCssClass($options, 'dropdown');
$this->addCssClass($urlOptions, 'dropdown-toggle'); Html::addCssClass($urlOptions, 'dropdown-toggle');
$label .= ' ' . Html::tag('b', '', array('class' => 'caret')); $label .= ' ' . Html::tag('b', '', array('class' => 'caret'));
if (is_array($items)) { if (is_array($items)) {
$items = Dropdown::widget(array( $items = Dropdown::widget(array(
......
...@@ -107,8 +107,8 @@ class NavBar extends Widget ...@@ -107,8 +107,8 @@ class NavBar extends Widget
{ {
parent::init(); parent::init();
$this->clientOptions = false; $this->clientOptions = false;
$this->addCssClass($this->options, 'navbar'); Html::addCssClass($this->options, 'navbar');
$this->addCssClass($this->brandOptions, 'brand'); Html::addCssClass($this->brandOptions, 'brand');
} }
/** /**
......
...@@ -94,7 +94,7 @@ class Progress extends Widget ...@@ -94,7 +94,7 @@ class Progress extends Widget
public function init() public function init()
{ {
parent::init(); parent::init();
$this->addCssClass($this->options, 'progress'); Html::addCssClass($this->options, 'progress');
} }
/** /**
...@@ -139,7 +139,7 @@ class Progress extends Widget ...@@ -139,7 +139,7 @@ class Progress extends Widget
*/ */
protected function renderBar($percent, $label = '', $options = array()) protected function renderBar($percent, $label = '', $options = array())
{ {
$this->addCssClass($options, 'bar'); Html::addCssClass($options, 'bar');
$options['style'] = "width:{$percent}%"; $options['style'] = "width:{$percent}%";
return Html::tag('div', $label, $options); return Html::tag('div', $label, $options);
} }
......
...@@ -93,7 +93,7 @@ class Tabs extends Widget ...@@ -93,7 +93,7 @@ class Tabs extends Widget
public function init() public function init()
{ {
parent::init(); parent::init();
$this->addCssClass($this->options, 'nav nav-tabs'); Html::addCssClass($this->options, 'nav nav-tabs');
} }
/** /**
...@@ -123,10 +123,10 @@ class Tabs extends Widget ...@@ -123,10 +123,10 @@ class Tabs extends Widget
if (isset($item['items'])) { if (isset($item['items'])) {
$label .= ' <b class="caret"></b>'; $label .= ' <b class="caret"></b>';
$this->addCssClass($headerOptions, 'dropdown'); Html::addCssClass($headerOptions, 'dropdown');
if ($this->renderDropdown($item['items'], $panes)) { if ($this->renderDropdown($item['items'], $panes)) {
$this->addCssClass($headerOptions, 'active'); Html::addCssClass($headerOptions, 'active');
} }
$header = Html::a($label, "#", array('class' => 'dropdown-toggle', 'data-toggle' => 'dropdown')) . "\n" $header = Html::a($label, "#", array('class' => 'dropdown-toggle', 'data-toggle' => 'dropdown')) . "\n"
...@@ -135,10 +135,10 @@ class Tabs extends Widget ...@@ -135,10 +135,10 @@ class Tabs extends Widget
$options = array_merge($this->itemOptions, ArrayHelper::getValue($item, 'options', array())); $options = array_merge($this->itemOptions, ArrayHelper::getValue($item, 'options', array()));
$options['id'] = ArrayHelper::getValue($options, 'id', $this->options['id'] . '-tab' . $n); $options['id'] = ArrayHelper::getValue($options, 'id', $this->options['id'] . '-tab' . $n);
$this->addCssClass($options, 'tab-pane'); Html::addCssClass($options, 'tab-pane');
if (ArrayHelper::remove($item, 'active')) { if (ArrayHelper::remove($item, 'active')) {
$this->addCssClass($options, 'active'); Html::addCssClass($options, 'active');
$this->addCssClass($headerOptions, 'active'); Html::addCssClass($headerOptions, 'active');
} }
$header = Html::a($label, '#' . $options['id'], array('data-toggle' => 'tab', 'tabindex' => '-1')); $header = Html::a($label, '#' . $options['id'], array('data-toggle' => 'tab', 'tabindex' => '-1'));
$panes[] = Html::tag('div', $item['content'], $options); $panes[] = Html::tag('div', $item['content'], $options);
...@@ -175,10 +175,10 @@ class Tabs extends Widget ...@@ -175,10 +175,10 @@ class Tabs extends Widget
$content = ArrayHelper::remove($item, 'content'); $content = ArrayHelper::remove($item, 'content');
$options = ArrayHelper::remove($item, 'contentOptions', array()); $options = ArrayHelper::remove($item, 'contentOptions', array());
$this->addCssClass($options, 'tab-pane'); Html::addCssClass($options, 'tab-pane');
if (ArrayHelper::remove($item, 'active')) { if (ArrayHelper::remove($item, 'active')) {
$this->addCssClass($options, 'active'); Html::addCssClass($options, 'active');
$this->addCssClass($item['options'], 'active'); Html::addCssClass($item['options'], 'active');
$itemActive = true; $itemActive = true;
} }
......
...@@ -82,20 +82,4 @@ class Widget extends \yii\base\Widget ...@@ -82,20 +82,4 @@ class Widget extends \yii\base\Widget
$view->registerJs(implode("\n", $js)); $view->registerJs(implode("\n", $js));
} }
} }
/**
* Adds a CSS class to the specified options.
* This method will ensure that the CSS class is unique and the "class" option is properly formatted.
* @param array $options the options to be modified.
* @param string $class the CSS class to be added
*/
protected function addCssClass(&$options, $class)
{
if (isset($options['class'])) {
$classes = preg_split('/\s+/', $options['class'] . ' ' . $class, -1, PREG_SPLIT_NO_EMPTY);
$options['class'] = implode(' ', array_unique($classes));
} else {
$options['class'] = $class;
}
}
} }
...@@ -1373,6 +1373,44 @@ class Html ...@@ -1373,6 +1373,44 @@ class Html
} }
/** /**
* Adds a CSS class to the specified options.
* If the CSS class is already in the options, it will not be added again.
* @param array $options the options to be modified.
* @param string $class the CSS class to be added
*/
public static function addCssClass(&$options, $class)
{
if (isset($options['class'])) {
$classes = ' ' . $options['class'] . ' ';
if (($pos = strpos($classes, ' ' . $class . ' ')) === false) {
$options['class'] .= ' ' . $class;
}
} else {
$options['class'] = $class;
}
}
/**
* Removes a CSS class from the specified options.
* @param array $options the options to be modified.
* @param string $class the CSS class to be removed
*/
public static function removeCssClass(&$options, $class)
{
if (isset($options['class'])) {
$classes = array_unique(preg_split('/\s+/', $options['class'] . ' ' . $class, -1, PREG_SPLIT_NO_EMPTY));
if (($index = array_search($class, $classes)) !== false) {
unset($classes[$index]);
}
if (empty($classes)) {
unset($options['class']);
} else {
$options['class'] = implode(' ', $classes);
}
}
}
/**
* Returns the real attribute name from the given attribute expression. * Returns the real attribute name from the given attribute expression.
* *
* An attribute expression is an attribute name prefixed and/or suffixed with array indexes. * An attribute expression is an attribute name prefixed and/or suffixed with array indexes.
......
...@@ -434,6 +434,38 @@ EOD; ...@@ -434,6 +434,38 @@ EOD;
Html::$showBooleanAttributeValues = true; Html::$showBooleanAttributeValues = true;
} }
public function testAddCssClass()
{
$options = array();
Html::addCssClass($options, 'test');
$this->assertEquals(array('class' => 'test'), $options);
Html::addCssClass($options, 'test');
$this->assertEquals(array('class' => 'test'), $options);
Html::addCssClass($options, 'test2');
$this->assertEquals(array('class' => 'test test2'), $options);
Html::addCssClass($options, 'test');
$this->assertEquals(array('class' => 'test test2'), $options);
Html::addCssClass($options, 'test2');
$this->assertEquals(array('class' => 'test test2'), $options);
Html::addCssClass($options, 'test3');
$this->assertEquals(array('class' => 'test test2 test3'), $options);
Html::addCssClass($options, 'test2');
$this->assertEquals(array('class' => 'test test2 test3'), $options);
}
public function testRemoveCssClass()
{
$options = array('class' => 'test test2 test3');
Html::removeCssClass($options, 'test2');
$this->assertEquals(array('class' => 'test test3'), $options);
Html::removeCssClass($options, 'test2');
$this->assertEquals(array('class' => 'test test3'), $options);
Html::removeCssClass($options, 'test');
$this->assertEquals(array('class' => 'test3'), $options);
Html::removeCssClass($options, 'test3');
$this->assertEquals(array(), $options);
}
protected function getDataItems() protected function getDataItems()
{ {
return array( return array(
......
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