Commit bec066ab by Crisu83

rewrote the menu implementation

parent 6c1e1f56
......@@ -4,7 +4,7 @@
* @author Christoffer Niska <ChristofferNiska@gmail.com>
* @copyright Copyright &copy; Christoffer Niska 2011-
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @version 0.10.0
* @version 1.0.0
*/
/**
......@@ -346,4 +346,13 @@ class Bootstrap extends CApplicationComponent
return $this->_assetsUrl = $assetsUrl;
}
}
/**
* Returns the version number.
* @return string the version
*/
public function getVersion()
{
return '1.0.0';
}
}
......@@ -127,7 +127,7 @@ mixpanel.init("733930f08f73894be317b7fdbfd15229");</script><!-- end Mixpanel -->
</p>
<p class="copy">
&copy; Christoffer Niska 2011
&copy; Christoffer Niska <?php echo date('Y'); ?>
</p>
</footer>
......
......@@ -16,7 +16,7 @@ Yii::app()->clientScript->registerScript('ConsolePolyfill', "
");
?>
<section id="bootAlert">
<section id="tbAlert">
<h2>Alerts</h2>
......@@ -49,7 +49,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootBreadcrumbs">
<section id="tbBreadcrumbs">
<h2>Breadcrumbs</h2>
......@@ -75,7 +75,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootNavbar">
<section id="tbNavbar">
<h2>Navbar</h2>
......@@ -169,7 +169,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootMenu">
<section id="tbMenu">
<h2>Menus</h2>
......@@ -271,7 +271,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootTabbable">
<section id="tbTabbable">
<h2>Tabbable</h2>
......@@ -361,7 +361,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootDetailView">
<section id="tbDetailView">
<h2>Detail views</h2>
......@@ -389,7 +389,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootGridView">
<section id="tbGridView">
<h2>Grid views</h2>
......@@ -466,7 +466,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootThumbnails">
<section id="tbThumbnails">
<h2>Thumbnails</h2>
......@@ -494,7 +494,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootTooltip">
<section id="tbTooltip">
<h2>Tooltips</h2>
......@@ -528,7 +528,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootPopover">
<section id="tbPopover">
<h2>Popovers</h2>
......@@ -552,7 +552,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootModal">
<section id="tbModal">
<h2>Modals</h2>
......@@ -631,7 +631,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootActiveForm">
<section id="tbActiveForm">
<h2>Forms</h2>
......@@ -646,7 +646,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
<?php echo $form->textFieldRow($model, 'textField', array('class'=>'span3')); ?>
<?php echo $form->passwordFieldRow($model, 'password', array('class'=>'span3')); ?>
<?php echo $form->checkboxRow($model, 'checkbox'); ?>
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'ok', 'label'=>'Submit')); ?>
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Login')); ?>
<?php $this->endWidget(); ?>
......@@ -661,7 +661,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
<?php echo \$form->textFieldRow(\$model, 'textField', array('class'=>'span3')); ?>
<?php echo \$form->passwordFieldRow(\$model, 'password', array('class'=>'span3')); ?>
<?php echo \$form->checkboxRow(\$model, 'checkbox'); ?>
<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'ok', 'label'=>'Submit')); ?>
<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Login')); ?>
<?php \$this->endWidget(); ?>"); ?>
......@@ -674,8 +674,8 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
'htmlOptions'=>array('class'=>'well'),
)); ?>
<?php echo $form->textFieldRow($model, 'textField', array('class'=>'input-medium')); ?>
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'search', 'label'=>'Search')); ?>
<?php echo $form->textFieldRow($model, 'textField', array('class'=>'input-medium', 'prepend'=>'<i class="icon-search"></i>')); ?>
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Go')); ?>
<?php $this->endWidget(); ?>
......@@ -688,8 +688,8 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
'htmlOptions'=>array('class'=>'well'),
)); ?>
<?php echo \$form->textFieldRow(\$model, 'textField', array('class'=>'input-medium')); ?>
<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'search', 'label'=>'Search')); ?>
<?php echo \$form->textFieldRow(\$model, 'textField', array('class'=>'input-medium', 'prepend'=>'<i class=\"icon-search\"></i>')); ?>
<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Go')); ?>
<?php \$this->endWidget(); ?>"); ?>
......@@ -704,7 +704,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
<?php echo $form->textFieldRow($model, 'textField', array('class'=>'input-small')); ?>
<?php echo $form->passwordFieldRow($model, 'password', array('class'=>'input-small')); ?>
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'arrow-right', 'label'=>'Log in')); ?>
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Log in')); ?>
<?php $this->endWidget(); ?>
......@@ -719,7 +719,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
<?php echo \$form->textFieldRow(\$model, 'textField', array('class'=>'input-small')); ?>
<?php echo \$form->passwordFieldRow(\$model, 'password', array('class'=>'input-small')); ?>
<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'arrow-right', 'label'=>'Log in')); ?>
<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Log in')); ?>
<?php \$this->endWidget(); ?>"); ?>
......@@ -815,7 +815,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootButton">
<section id="tbButton">
<h2>Buttons</h2>
......@@ -1213,7 +1213,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootHero">
<section id="tbHero">
<h2>Hero unit</h2>
......@@ -1249,7 +1249,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootCarousel">
<section id="tbCarousel">
<h2>Carousel</h2>
......@@ -1279,7 +1279,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootProgress">
<section id="tbProgress">
<h2>Progress bars</h2>
......@@ -1335,7 +1335,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootTypeahead">
<section id="tbTypeahead">
<h2>Typeahead</h2>
......@@ -1369,7 +1369,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootLabel">
<section id="tbLabel">
<h2>Labels</h2>
......@@ -1393,7 +1393,7 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
</section>
<section id="bootBadge">
<section id="tbBadge">
<h2>Badges</h2>
......@@ -1434,25 +1434,25 @@ Yii::app()->user->setFlash('error', '<strong>Oh snap!</strong> Change a few thin
'scrollspy'=>array('spy'=>'.subnav', 'offset'=>50),
'items'=>array(
array('label'=>'WIDGETS'),
array('label'=>'Alert', 'url'=>'#bootAlert'),
array('label'=>'Breadcrumb', 'url'=>'#bootBreadcrumbs'),
array('label'=>'Navbar', 'url'=>'#bootNavbar'),
array('label'=>'Menu', 'url'=>'#bootMenu'),
array('label'=>'Tabbable', 'url'=>'#bootTabbable'),
array('label'=>'Detail view', 'url'=>'#bootDetailView'),
array('label'=>'Grid view', 'url'=>'#bootGridView'),
array('label'=>'Thumbnail', 'url'=>'#bootThumbnails'),
array('label'=>'Tooltip', 'url'=>'#bootTooltip'),
array('label'=>'Popover', 'url'=>'#bootPopover'),
array('label'=>'Modal', 'url'=>'#bootModal'),
array('label'=>'Forms', 'url'=>'#bootActiveForm'),
array('label'=>'Buttons', 'url'=>'#bootButton'),
array('label'=>'Hero', 'url'=>'#bootHero'),
array('label'=>'Carousel', 'url'=>'#bootCarousel'),
array('label'=>'Progress', 'url'=>'#bootProgress'),
array('label'=>'Typeahead', 'url'=>'#bootTypeahead'),
array('label'=>'Labels', 'url'=>'#bootLabel'),
array('label'=>'Badges', 'url'=>'#bootBadge'),
array('label'=>'Alert', 'url'=>'#tbAlert'),
array('label'=>'Breadcrumb', 'url'=>'#tbBreadcrumbs'),
array('label'=>'Navbar', 'url'=>'#tbNavbar'),
array('label'=>'Menu', 'url'=>'#tbMenu'),
array('label'=>'Tabbable', 'url'=>'#tbTabbable'),
array('label'=>'Detail view', 'url'=>'#tbDetailView'),
array('label'=>'Grid view', 'url'=>'#tbGridView'),
array('label'=>'Thumbnail', 'url'=>'#tbThumbnails'),
array('label'=>'Tooltip', 'url'=>'#tbTooltip'),
array('label'=>'Popover', 'url'=>'#tbPopover'),
array('label'=>'Modal', 'url'=>'#tbModal'),
array('label'=>'Forms', 'url'=>'#tbActiveForm'),
array('label'=>'Buttons', 'url'=>'#tbButton'),
array('label'=>'Hero', 'url'=>'#tbHero'),
array('label'=>'Carousel', 'url'=>'#tbCarousel'),
array('label'=>'Progress', 'url'=>'#tbProgress'),
array('label'=>'Typeahead', 'url'=>'#tbTypeahead'),
array('label'=>'Labels', 'url'=>'#tbLabel'),
array('label'=>'Badges', 'url'=>'#tbBadge'),
),
)); ?>
......
<?php
/**
* BootBaseMenu class file.
* TbBaseMenu class file.
* @author Christoffer Niska <ChristofferNiska@gmail.com>
* @copyright Copyright &copy; Christoffer Niska 2011-
* @copyright Copyright &copy; Christoffer Niska 2012-
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @package bootstrap.widgets
*/
abstract class TbBaseMenu extends CWidget
Yii::import('zii.widgets.CMenu');
abstract class TbBaseMenu extends CMenu
{
/**
* @var array the menu items.
*/
public $items = array();
/**
* @var string the item template.
*/
public $itemTemplate;
/**
* @var boolean whether to encode item labels.
*/
public $encodeLabel = true;
/**
* @var array the HTML attributes for the widget container.
*/
public $htmlOptions = array();
/**
* Initializes the widget.
*/
public function init()
{
$this->htmlOptions['id'] = $this->getId();
}
/**
* Runs the widget.
*/
public function run()
{
echo CHtml::openTag('ul', $this->htmlOptions);
$this->renderItems($this->items);
echo '</ul>';
}
/**
* Renders a single item in the menu.
* @param array $item the item configuration
* @return string the rendered item
*/
protected function renderItem($item)
{
if (!isset($item['linkOptions']))
$item['linkOptions'] = array();
if (isset($item['icon']))
{
if (strpos($item['icon'], 'icon') === false)
{
$pieces = explode(' ', $item['icon']);
/**
* Returns the divider css class.
* @return string the class name
*/
abstract public function getDividerCssClass();
/**
* Renders the menu items.
* @param array $items menu items. Each menu item will be an array with at least two elements: 'label' and 'active'.
* It may have three other optional elements: 'items', 'linkOptions' and 'itemOptions'.
*/
protected function renderMenu($items)
{
$n = count($items);
if($n > 0)
{
echo CHtml::openTag('ul', $this->htmlOptions);
$count = 0;
foreach ($items as $item)
{
$count++;
if (isset($item['divider']))
echo '<li class="'.$this->getDividerCssClass().'"></li>';
else
{
$options = isset($item['itemOptions']) ? $item['itemOptions'] : array();
$classes = array();
if ($item['active'] && $this->activeCssClass != '')
$classes[] = $this->activeCssClass;
if ($count === 1 && $this->firstItemCssClass !== null)
$classes[] = $this->firstItemCssClass;
if ($count === $n && $this->lastItemCssClass !== null)
$classes[] = $this->lastItemCssClass;
if ($this->itemCssClass !== null)
$classes[] = $this->itemCssClass;
if ($classes !== array())
{
$classes = implode(' ', $classes);
if (!empty($options['class']))
$options['class'] .= ' '.$classes;
else
$options['class'] = $classes;
}
echo CHtml::openTag('li', $options);
$menu = $this->renderMenuItem($item);
if (isset($this->itemTemplate) || isset($item['template']))
{
$template = isset($item['template']) ? $item['template'] : $this->itemTemplate;
echo strtr($template, array('{menu}' => $menu));
}
else
echo $menu;
if (isset($item['items']) && count($item['items']))
{
$this->controller->widget('bootstrap.widgets.TbDropdown', array(
'encodeLabel'=>$this->encodeLabel,
'items'=>$item['items'],
'htmlOptions'=>isset($item['submenuOptions']) ? $item['submenuOptions'] : $this->submenuHtmlOptions,
));
}
echo '</li>';
}
}
echo '</ul>';
}
}
/**
* Renders the content of a menu item.
* Note that the container and the sub-menus are not rendered here.
* @param array $item the menu item to be rendered. Please see {@link items} on what data might be in the item.
* @return string the rendered item
*/
protected function renderMenuItem($item)
{
if (!isset($item['linkOptions']))
$item['linkOptions'] = array();
if (isset($item['icon']))
{
if (strpos($item['icon'], 'icon') === false)
{
$pieces = explode(' ', $item['icon']);
$item['icon'] = 'icon-'.implode(' icon-', $pieces);
}
$item['label'] = '<i class="'.$item['icon'].'"></i> '.$item['label'];
}
if (!isset($item['header']) && !isset($item['url']))
$item['url'] = '#';
if (isset($item['url']))
return CHtml::link($item['label'], $item['url'], $item['linkOptions']);
else
return $item['label'];
}
/**
* Checks whether a menu item is active.
* @param array $item the menu item to be checked
* @param string $route the route of the current request
* @return boolean the result
*/
protected function isItemActive($item, $route)
{
if (isset($item['url']) && is_array($item['url']) && !strcasecmp(trim($item['url'][0], '/'), $route))
{
if (count($item['url']) > 1)
foreach (array_splice($item['url'], 1) as $name=>$value)
if (!isset($_GET[$name]) || $_GET[$name] != $value)
return false;
return true;
}
return false;
}
/**
* Renders the items in this menu.
* @abstract
* @param array $items the menu items
*/
abstract public function renderItems($items);
}
$item['label'] = '<i class="'.$item['icon'].'"></i> '.$item['label'];
}
if (isset($item['items']) && !empty($item['items']))
{
$item['url'] = '#';
if (isset($item['linkOptions']['class']))
$item['linkOptions']['class'] .= ' dropdown-toggle';
else
$item['linkOptions']['class'] = 'dropdown-toggle';
$item['linkOptions']['data-toggle'] = 'dropdown';
$item['label'] .= ' <span class="caret"></span>';
}
if (isset($item['url']))
return CHtml::link($item['label'], $item['url'], $item['linkOptions']);
else
return $item['label'];
}
/**
* Normalizes the {@link items} property so that the 'active' state is properly identified for every menu item.
* @param array $items the items to be normalized.
* @param string $route the route of the current request.
* @param boolean $active whether there is an active child menu item.
* @return array the normalized menu items
*/
protected function normalizeItems($items, $route, &$active)
{
foreach ($items as $i => $item)
{
if (!is_array($item))
$item = array('divider'=>true);
else
{
if (!isset($item['itemOptions']))
$item['itemOptions'] = array();
$classes = array();
if (!isset($item['url']) && $this->isVertical())
{
$item['header'] = true;
$classes[] = 'nav-header';
}
if (isset($item['items']))
$classes[] = 'dropdown';
$classes = implode($classes, ' ');
if (isset($item['itemOptions']['class']))
$item['itemOptions']['class'] .= ' '.$classes;
else
$item['itemOptions']['class'] = $classes;
}
$items[$i] = $item;
}
return parent::normalizeItems($items, $route, $active);
}
/**
* Returns whether this is a vertical menu.
* @return boolean the result
*/
protected function isVertical()
{
return $this instanceof TbDropdown || $this instanceof TbMenu && $this->type === TbMenu::TYPE_LIST;
}
}
<?php
/**
* BootDropdown class file.
* TbDropdown class file.
* @author Christoffer Niska <ChristofferNiska@gmail.com>
* @copyright Copyright &copy; Christoffer Niska 2011-
* @copyright Copyright &copy; Christoffer Niska 2012-
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @package bootstrap.widgets
* @since 0.9.10
*/
Yii::import('bootstrap.widgets.TbBaseMenu');
/**
* Bootstrap dropdown menu widget.
*/
class TbDropdown extends TbBaseMenu
{
/**
* Initializes the widget.
*/
public function init()
{
$route = $this->controller->getRoute();
$this->items = $this->normalizeItems($this->items, $route);
$classes = 'dropdown-menu';
if (isset($this->htmlOptions['class']))
$this->htmlOptions['class'] .= ' '.$classes;
else
$this->htmlOptions['class'] = $classes;
}
/**
* Renders the items in this menu.
* @param array $items the menu items
*/
public function renderItems($items)
{
foreach ($items as $item)
{
if (!is_array($item))
echo '<li class="divider"></li>';
else
{
if (!isset($item['itemOptions']))
$item['itemOptions'] = array();
$classes = array();
if (!isset($item['url']))
{
$item['header'] = true;
$classes[] = 'nav-header';
}
if ($item['active'])
$classes[] = 'active';
$classes = implode(' ', $classes);
if(isset($item['itemOptions']['class']))
$item['itemOptions']['class'] .= ' '.$classes;
else
$item['itemOptions']['class'] = $classes;
echo CHtml::openTag('li', $item['itemOptions']);
$menu = $this->renderItem($item);
if (isset($this->itemTemplate) || isset($item['template']))
{
$template = isset($item['template']) ? $item['template'] : $this->itemTemplate;
echo strtr($template, array('{menu}'=>$menu));
}
else
echo $menu;
echo '</li>';
}
}
}
/**
* Normalizes the items in this menu.
* @param array $items the items to be normalized
* @param string $route the route of the current request
* @return array the normalized menu items
*/
protected function normalizeItems($items, $route)
{
foreach ($items as $i => $item)
{
if (!is_array($item))
continue;
if (isset($item['visible']) && !$item['visible'])
{
unset($items[$i]);
continue;
}
if (!is_array($item)) {
continue;
}
if (!isset($item['label']))
$item['label'] = '';
if (isset($item['encodeLabel']) && $item['encodeLabel'])
$items[$i]['label'] = CHtml::encode($item['label']);
if (($this->encodeLabel && !isset($item['encodeLabel']))
|| (isset($item['encodeLabel']) && $item['encodeLabel'] !== false))
$items[$i]['label'] = CHtml::encode($item['label']);
if (!isset($item['active']))
$items[$i]['active'] = $this->isItemActive($item, $route);
}
return array_values($items);
}
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
if (isset($this->htmlOptions['class']))
$this->htmlOptions['class'] .= ' dropdown-menu';
else
$this->htmlOptions['class'] = 'dropdown-menu';
}
/**
* Returns the divider css class.
* @return string the class name
*/
public function getDividerCssClass()
{
return 'divider';
}
}
<?php
/**
* BootMenu class file.
* TbMenu class file.
* @author Christoffer Niska <ChristofferNiska@gmail.com>
* @copyright Copyright &copy; Christoffer Niska 2011-
* @copyright Copyright &copy; Christoffer Niska 2012-
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
* @package bootstrap.widgets
*/
Yii::import('bootstrap.widgets.TbBaseMenu');
/**
* Bootstrap menu widget.
* Used for rendering of bootstrap menus with support dropdown sub-menus and scroll-spying.
* @since 0.9.8
*/
class TbMenu extends TbBaseMenu
{
// Menu types.
const TYPE_UNSTYLED = '';
const TYPE_TABS = 'tabs';
const TYPE_PILLS = 'pills';
const TYPE_LIST = 'list';
/**
* @var string the menu type.
* Valid values are '', 'tabs' and 'pills'. Defaults to ''.
*/
public $type;
/**
* @var boolean whether to stack navigation items.
*/
public $stacked = false;
/**
* @var array the scroll-spy configuration.
*/
public $scrollspy;
/**
* @var array the HTML options for dropdown menus.
*/
public $dropdownOptions = array();
/**
* Initializes the widget.
*/
public function init()
{
$route = $this->controller->getRoute();
$this->items = $this->normalizeItems($this->items, $route);
$classes = array('nav');
$validTypes = array(self::TYPE_TABS, self::TYPE_PILLS, self::TYPE_LIST);
if (isset($this->type) && in_array($this->type, $validTypes))
$classes[] = 'nav-'.$this->type;
if ($this->type !== self::TYPE_LIST && $this->stacked)
$classes[] = 'nav-stacked';
$classes = implode(' ', $classes);
if (isset($this->htmlOptions['class']))
$this->htmlOptions['class'] .= ' '.$classes;
else
$this->htmlOptions['class'] = $classes;
if (isset($this->scrollspy) && is_array($this->scrollspy) && isset($this->scrollspy['spy']))
{
if (!isset($this->scrollspy['subject']))
$this->scrollspy['subject'] = 'body';
if (!isset($this->scrollspy['offset']))
$this->scrollspy['offset'] = null;
Yii::app()->bootstrap->spyOn($this->scrollspy['subject'], $this->scrollspy['spy'], $this->scrollspy['offset']);
}
}
/**
* Renders the items in this menu.
* @param array $items the menu items
*/
public function renderItems($items)
{
foreach ($items as $item)
{
if (!is_array($item))
{
$class = $this->type !== self::TYPE_LIST ? 'divider-vertical' : 'divider';
echo '<li class="'.$class.'"></li>';
}
else
{
if (!isset($item['itemOptions']))
$item['itemOptions'] = array();
$classes = array();
if ($item['active'] || (isset($item['items']) && $this->isChildActive($item['items'])))
$classes[] = 'active';
if ($this->type === self::TYPE_LIST && !isset($item['url']))
{
$item['header'] = true;
$classes[] = 'nav-header';
}
if (isset($item['items']))
$classes[] = 'dropdown';
$classes = implode(' ', $classes);
if(isset($item['itemOptions']['class']))
$item['itemOptions']['class'] .= ' '.$classes;
else
$item['itemOptions']['class'] = $classes;
echo CHtml::openTag('li', $item['itemOptions']);
$menu = $this->renderItem($item);
if (isset($this->itemTemplate) || isset($item['template']))
{
$template = isset($item['template']) ? $item['template'] : $this->itemTemplate;
echo strtr($template, array('{menu}'=>$menu));
}
else
echo $menu;
if(isset($item['items']) && !empty($item['items']))
{
$this->controller->widget('bootstrap.widgets.TbDropdown', array(
'encodeLabel'=>$this->encodeLabel,
'items'=>$item['items'],
'htmlOptions'=>isset($item['dropdownOptions']) ? $item['dropdownOptions'] : $this->dropdownOptions,
));
}
echo '</li>';
}
}
}
/**
* Renders a single item in the menu.
* @param array $item the item configuration
* @return string the rendered item
*/
protected function renderItem($item)
{
if (!isset($item['linkOptions']))
$item['linkOptions'] = array();
if (isset($item['items']) && !empty($item['items']))
{
if (isset($item['linkOptions']['class']))
$item['linkOptions']['class'] .= ' dropdown-toggle';
else
$item['linkOptions']['class'] = 'dropdown-toggle';
$item['linkOptions']['data-toggle'] = 'dropdown';
$item['label'] .= ' <span class="caret"></span>';
}
return parent::renderItem($item);
}
/**
* Normalizes the items in this menu.
* @param array $items the items to be normalized
* @param string $route the route of the current request
* @return array the normalized menu items
*/
protected function normalizeItems($items, $route)
{
foreach ($items as $i => $item)
{
if (!is_array($item))
continue;
if (isset($item['visible']) && !$item['visible'])
{
unset($items[$i]);
continue;
}
if (!isset($item['label']))
$item['label'] = '';
if (isset($item['encodeLabel']) && $item['encodeLabel'])
$items[$i]['label'] = CHtml::encode($item['label']);
if (($this->encodeLabel && !isset($item['encodeLabel']))
|| (isset($item['encodeLabel']) && $item['encodeLabel'] !== false))
$items[$i]['label'] = CHtml::encode($item['label']);
if (!empty($item['items']) && is_array($item['items']))
{
$items[$i]['items'] = $this->normalizeItems($item['items'], $route);
if (empty($items[$i]['items']))
unset($items[$i]['items']);
}
if (!isset($item['active']))
$items[$i]['active'] = $this->isItemActive($item, $route);
}
return array_values($items);
}
/**
* Returns whether a child item is active.
* @param array $items the items to check
* @return boolean the result
*/
protected function isChildActive($items)
{
foreach ($items as $item)
if (isset($item['active']) && $item['active'] === true)
return true;
return false;
}
// Menu types.
const TYPE_UNSTYLED = '';
const TYPE_TABS = 'tabs';
const TYPE_PILLS = 'pills';
const TYPE_LIST = 'list';
/**
* @var string the menu type.
* Valid values are '', 'tabs' and 'pills'. Defaults to ''.
*/
public $type;
/**
* @var boolean whether to stack navigation items.
*/
public $stacked = false;
/**
* @var array the scroll-spy configuration.
*/
public $scrollspy;
/**
* Initializes the widget.
*/
public function init()
{
parent::init();
$classes = array('nav');
if (isset($this->type) && in_array($this->type, array(self::TYPE_TABS, self::TYPE_PILLS, self::TYPE_LIST)))
$classes[] = 'nav-'.$this->type;
if ($this->type !== self::TYPE_LIST && $this->stacked)
$classes[] = 'nav-stacked';
$classes = implode(' ', $classes);
if (isset($this->htmlOptions['class']))
$this->htmlOptions['class'] .= ' '.$classes;
else
$this->htmlOptions['class'] = $classes;
if (isset($this->scrollspy) && is_array($this->scrollspy) && isset($this->scrollspy['spy']))
{
if (!isset($this->scrollspy['subject']))
$this->scrollspy['subject'] = 'body';
if (!isset($this->scrollspy['offset']))
$this->scrollspy['offset'] = null;
Yii::app()->bootstrap->spyOn($this->scrollspy['subject'], $this->scrollspy['spy'], $this->scrollspy['offset']);
}
}
/**
* Returns the divider css class.
* @return string the class name
*/
public function getDividerCssClass()
{
return $this->type === self::TYPE_LIST ? 'divider' : 'divider-vertical';
}
}
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