Dropdown.php 3.31 KB
Newer Older
Antonio Ramirez committed
1 2 3 4 5 6 7 8 9 10
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\bootstrap;

use yii\base\InvalidConfigException;
11
use yii\helpers\ArrayHelper;
Antonio Ramirez committed
12 13 14
use yii\helpers\Html;

/**
15
 * Dropdown renders a Bootstrap dropdown menu component.
Antonio Ramirez committed
16
 *
MarsuBoss committed
17
 * @see http://getbootstrap.com/javascript/#dropdowns
Antonio Ramirez committed
18 19 20 21 22
 * @author Antonio Ramirez <amigo.cobos@gmail.com>
 * @since 2.0
 */
class Dropdown extends Widget
{
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
    /**
     * @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;
Antonio Ramirez committed
42 43


44 45 46 47 48 49 50 51 52
    /**
     * 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');
    }
Antonio Ramirez committed
53

54 55 56 57 58 59 60 61
    /**
     * Renders the widget.
     */
    public function run()
    {
        echo $this->renderItems($this->items);
        $this->registerPlugin('dropdown');
    }
Antonio Ramirez committed
62

63 64
    /**
     * Renders menu items.
65 66
     * @param array $items the menu items to be rendered
     * @return string the rendering result.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
     * @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);
        }
Antonio Ramirez committed
95

96 97
        return Html::tag('ul', implode("\n", $lines), $this->options);
    }
98
}