Class yii\bootstrap5\Dropdown
| Inheritance | yii\ |
|---|---|
| Uses Traits | yii\ |
| Source Code | https://github.com/yiisoft/yii2-bootstrap5/blob/master/src/Dropdown.php |
Dropdown renders a Bootstrap dropdown menu component.
For example,
<div class="dropdown">
<a href="#" data-bs-toggle="dropdown" class="dropdown-toggle">Label <b class="caret"></b></a>
<?php
echo Dropdown::widget([
'items' => [
['label' => 'DropdownA', 'url' => '/'],
['label' => 'DropdownB', 'url' => '#'],
],
]);
?>
</div>
See also https://getbootstrap.com/docs/5.1/components/dropdowns/.
Public Properties
| Property | Type | Description | Defined By |
|---|---|---|---|
| $clientEvents | array | The event handlers for the underlying Bootstrap JS plugin. | yii\ |
| $clientOptions | array|false | The options for the underlying Bootstrap JS plugin/component. | yii\ |
| $encodeLabels | boolean | Whether the labels for header items should be HTML-encoded. | yii\ |
| $items | array | List of menu items in the dropdown. | yii\ |
| $options | array | The HTML attributes for the widget container tag. | yii\ |
| $submenuOptions | array|null | The HTML attributes for sub-menu container tags. | yii\ |
Public Methods
| Method | Description | Defined By |
|---|---|---|
| init() | yii\ |
|
| run() | Renders the widget. | yii\ |
Protected Methods
| Method | Description | Defined By |
|---|---|---|
| registerClientEvents() | Registers JS event handlers that are listed in $clientEvents. | yii\ |
| registerPlugin() | Registers a specific Bootstrap plugin/component and the related events. | yii\ |
| renderItems() | Renders menu items. | yii\ |
Property Details
Whether the labels for header items should be HTML-encoded.
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.
- encode: bool, optional, whether to HTML-encode item label.
- url: string|array, optional, the URL of the item link. This will be processed by \
yii\ . If not set, the item will be treated as a menu header when the item has no sub-menu.helpers\ Url::to() - visible: bool, optional, whether this menu item is visible. Defaults to true.
- disabled: bool, optional, whether this menu item is disabled. Defaults to false.
- linkOptions: array, optional, the HTML attributes of the item link.
- options: array, optional, the HTML attributes of the item.
- active: bool, optional, whether the item should be on active state or not.
- 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.
- submenuOptions: array, optional, the HTML attributes for sub-menu container tag. If specified it will be merged with $submenuOptions.
To insert divider use -.
Method Details
| public void init ( ) |
public function init(): void
{
parent::init();
Html::addCssClass($this->options, [
'widget' => 'dropdown-menu',
]);
}
Defined in:
yii\
Registers JS event handlers that are listed in $clientEvents.
| protected void registerClientEvents ( ?string $name = null ) | ||
| $name | ?string | |
protected function registerClientEvents(?string $name = null): void
{
if (!empty($this->clientEvents)) {
$id = $this->options['id'];
$js = [];
$appendix = ($name === 'dropdown') ? '.parentElement' : '';
foreach ($this->clientEvents as $event => $handler) {
$js[] = "document.getElementById('$id')$appendix.addEventListener('$event', $handler);";
}
$this->getView()->registerJs(implode("\n" , $js));
}
}
Defined in:
yii\
Registers a specific Bootstrap plugin/component and the related events.
| protected void registerPlugin ( string $name ) | ||
| $name | string |
The name of the Bootstrap plugin |
protected function registerPlugin(string $name): void
{
/**
* @see https://github.com/twbs/bootstrap/blob/v5.2.0/js/index.esm.js
*/
$jsPlugins = [
'alert',
'button',
'carousel',
'collapse',
'dropdown',
'modal',
'offcanvas',
'popover',
'scrollspy',
'tab',
'toast',
'tooltip',
];
if (in_array($name, $jsPlugins, true)) {
$view = $this->getView();
BootstrapPluginAsset::register($view);
// 'popover', 'toast' and 'tooltip' plugins not activates via data attributes
if ($this->clientOptions !== false || in_array($name, ['popover', 'toast', 'tooltip'], true)) {
$name = ucfirst($name);
$id = $this->options['id'];
$options = empty($this->clientOptions) ? '{}' : Json::htmlEncode($this->clientOptions);
$view->registerJs("(new bootstrap.$name('#$id', $options));");
}
$this->registerClientEvents($name);
}
}
Renders menu items.
| protected string renderItems ( array $items, array $options = [] ) | ||
| $items | array |
The menu items to be rendered |
| $options | array |
The container HTML attributes |
| return | string |
The rendering result. |
|---|---|---|
| throws | \ |
if the label option is not specified in one of the items. |
| throws | Exception | |
protected function renderItems(array $items, array $options = []): string
{
$lines = [];
foreach ($items as $item) {
if (is_string($item)) {
$lines[] = ($item === '-')
? Html::tag('hr', '', [
'class' => 'dropdown-divider',
])
: $item;
continue;
}
if (isset($item['visible']) && !$item['visible']) {
continue;
}
if (!array_key_exists('label', $item)) {
throw new InvalidConfigException("The 'label' option is required.");
}
$encodeLabel = $item['encode'] ?? $this->encodeLabels;
$label = $encodeLabel ? Html::encode($item['label']) : $item['label'];
$itemOptions = ArrayHelper::getValue($item, 'options', []);
$linkOptions = ArrayHelper::getValue($item, 'linkOptions', []);
$active = ArrayHelper::getValue($item, 'active', false);
$disabled = ArrayHelper::getValue($item, 'disabled', false);
Html::addCssClass($linkOptions, [
'widget' => 'dropdown-item',
]);
if ($disabled) {
ArrayHelper::setValue($linkOptions, 'tabindex', '-1');
ArrayHelper::setValue($linkOptions, 'aria.disabled', 'true');
Html::addCssClass($linkOptions, [
'disable' => 'disabled',
]);
} elseif ($active) {
ArrayHelper::setValue($linkOptions, 'aria.current', 'true');
Html::addCssClass($linkOptions, [
'activate' => 'active',
]);
}
$url = array_key_exists('url', $item) ? $item['url'] : null;
if (empty($item['items'])) {
if ($url === null) {
$content = Html::tag('h6', $label, [
'class' => 'dropdown-header',
]);
} else {
$content = Html::a($label, $url, $linkOptions);
}
$lines[] = $content;
} else {
$submenuOptions = $this->submenuOptions;
if (isset($item['submenuOptions'])) {
$submenuOptions = array_merge($submenuOptions, $item['submenuOptions']);
}
Html::addCssClass($submenuOptions, [
'widget' => 'dropdown-submenu dropdown-menu',
]);
Html::addCssClass($linkOptions, [
'toggle' => 'dropdown-toggle',
]);
$lines[] = Html::beginTag('div', array_merge_recursive([
'class' => ['dropdown'],
'aria' => [
'expanded' => 'false',
],
], $itemOptions));
$lines[] = Html::a($label, $url, array_merge_recursive([
'data' => [
'bs-toggle' => 'dropdown',
],
'aria' => [
'expanded' => 'false',
],
'role' => 'button',
], $linkOptions));
$lines[] = static::widget([
'items' => $item['items'],
'options' => $submenuOptions,
'submenuOptions' => $submenuOptions,
'encodeLabels' => $this->encodeLabels,
]);
$lines[] = Html::endTag('div');
}
}
return Html::tag('div', implode("\n" , $lines), $options);
}