The module includes a dropdown trigger and menu items. Menu items can be
**link** - An link item.
**group** - A group item to create a logical grouping of menu items
for sorting purposes, and/or to create a heading.
**divider** - A dividing line.
Each item must have a unique key. If not supplied, the class will generate
one in the format: 'item*', where * is an auto incrementing number.
Keys can be used for sorting purposes and for adding links to a group.
For example, you could set the sort property to an item to array('before'=>'key1')
and it would place the item before another item with the key of 'key1'.
If you have a group with the key of 'key2', you can add to this group by
setting the key of a new item to 'key2.newItemKey'.
The sort property can also be an integer, indicating the item's position in the menu.
Here is an example menu creation:
$dropdown = new DropdownModule('my-dropdown');
$dropdown->setTrigger('A New Name')
->addLink('Link 1', '#') // automatically creates key: item1
->addDivider() // automatically creates key: item2
->addLink('Link 2', '#', 'link2', 'danger') // creates item with key: link2
->addLink('Link 3', '#') // automatically creates key: item3
->addLink('Link 4', '#') // automatically creates key: item4
->addGroup('', 'group1') // creates group with no header
->addGroup('Group 3', 'group3') // creates group with header: 'Group 3', empty so will not display
->addGroup('Group 2', 'group2') // creates group with header: 'Group 2'
->addLink('Link 5', '#', '', '', array('before', 'link2'), array('badge' => '4')) // automatically creates key: item5. Inserts before Link 2
->addLink('Link 6', '#') // automatically creates key: item6
->addLink('Link 7', '#') // automatically creates key: item7
->addLink('Link 8', '#', 'group2.link8', '', array(), array('icon' => 'flame')) // adds to Group 2
->addLink('Link 9', '#', 'group1.link9') // adds to Group 1
->addLink('Link 10', '#', 'group1.link10'); // adds to Group 1
echo $dropdown;
Which results in a menu:
Trigger Name
Link 1
------------
Link 5
Link 2
Link 3
Link 4
Link 9
Link 10
Group 2
Link 8
Link 6
Link 7
/** * Render options that the user has for this category. Returns an empty string if the session isn't valid. * * @param $category The category to render the options for. * @return DropdownModule|string A dropdown with the category options or an empty string if the session is not valid. * @throws Exception */ function getOptions($category) { if (!Gdn::session()->isValid()) { return ''; } $sender = Gdn::controller(); $categoryID = val('CategoryID', $category); $dropdown = new DropdownModule(); $tk = urlencode(Gdn::session()->TransientKey()); $hide = (int) (!val('Following', $category)); $dropdown->addLink(t('Mark Read'), "/category/markread?categoryid={$categoryID}&tkey={$tk}", 'mark-read'); $dropdown->addLink(t($hide ? 'Unmute' : 'Mute'), "/category/follow?categoryid={$categoryID}&value={$hide}&tkey={$tk}", 'hide'); // Allow plugins to add options $sender->EventArguments['CategoryOptionsDropdown'] =& $dropdown; $sender->EventArguments['Category'] =& $category; $sender->fireEvent('CategoryOptionsDropdown'); return $dropdown; }
/** * * * @param array $category */ function writeCategoryOptions($category) { $cdd = new DropdownModule('', '', 'dropdown-category-options', 'dropdown-menu-right'); $cdd->setTrigger(displayAsSymbol($category['DisplayAs']), 'button', 'btn'); $cdd->setView('dropdown-twbs'); $cdd->setForceDivider(true); $cdd->addGroup('', 'edit')->addLink(t('View'), $category['Url'], 'edit.view')->addLink(t('Edit'), "/vanilla/settings/editcategory?categoryid={$category['CategoryID']}", 'edit.edit'); $cdd->addGroup(t('Display as'), 'displayas'); foreach (CategoryModel::getDisplayAsOptions() as $displayAs => $label) { $cssClass = strcasecmp($displayAs, $category['DisplayAs']) === 0 ? 'selected' : ''; $icon = displayAsSymbol($displayAs); $cdd->addLink(t($label), '#', 'displayas.' . strtolower($displayAs), 'js-displayas ' . $cssClass, [], ['icon' => $icon, 'attributes' => ['data-displayas' => strtolower($displayAs)]], false); } $cdd->addGroup('', 'actions')->addLink(t('Add Subcategory'), "/vanilla/settings/addcategory?parent={$category['CategoryID']}", 'actions.add'); $cdd->addGroup('', 'delete')->addLink(t('Delete'), "/vanilla/settings/deletecategory?categoryid={$category['CategoryID']}", 'delete.delete', 'js-modal'); echo $cdd->toString(); }
/** * Returns an array of dropdown menus with the data from the filters array or an array containing an empty string * to make it safe for echoing out. * * @return array An array of dropdown menus or an array containing an empty string. */ protected function getFilterDropdowns() { if (!$this->filters) { return ['']; } $dropdowns = []; foreach ($this->filters as $filterSet) { // Check to see if there's a category restriction. if ($categories = val('categories', $filterSet)) { if (!in_array($this->categoryID, $categories)) { continue; } } $setKey = val('key', $filterSet); $dropdown = new DropdownModule('discussions-filter-' . $setKey, val('name', $filterSet), 'discussion-filter'); // Override the trigger text? $selectedValue = val($setKey, $this->selectedFilters); if ($selectedValue && $selectedValue != 'none') { $selected = val('name', $filterSet['filters'][$selectedValue]); $dropdown->setTrigger($selected); } $dropdown->setView($this->dropdownView); $dropdown->setForceDivider(true); // Adds dividers between groups in the dropdown. // Add the filters to the dropdown foreach (val('filters', $filterSet) as $filter) { $key = val('group', $filter, '') . '.' . val('key', $filter); $queryString = DiscussionModel::getSortFilterQueryString($this->selectedSort, $this->selectedFilters, '', [$setKey => val('key', $filter)]); $pathAndQuery = $this->getPagelessPath() . $queryString; if (empty($pathAndQuery)) { $pathAndQuery = '/'; } $url = url($pathAndQuery); $dropdown->addLink(val('name', $filter), $url, $key, '', array(), false, array('rel' => 'nofollow')); } $dropdowns[] = $dropdown; } return $dropdowns; }
/** * Constructs an options dropdown menu for a discussion. * * @param object|array|null $discussion The discussion to get the dropdown options for. * @return DropdownModule A dropdown consisting of discussion options. * @throws Exception */ function getDiscussionOptionsDropdown($discussion = null) { $dropdown = new DropdownModule(); $sender = Gdn::controller(); $session = Gdn::session(); if ($discussion == null) { $discussion = $sender->data('Discussion'); } $categoryID = val('CategoryID', $discussion); if (!$categoryID && property_exists($sender, 'Discussion')) { trace('Getting category ID from controller Discussion property.'); $categoryID = val('CategoryID', $sender->Discussion); } $discussionID = $discussion->DiscussionID; $categoryUrl = urlencode(categoryUrl(CategoryModel::categories($categoryID))); $permissionCategoryID = val('PermissionCategoryID', $discussion, val('PermissionCategoryID', $discussion)); // Permissions $canEdit = DiscussionModel::canEdit($discussion, $timeLeft); $canAnnounce = $session->checkPermission('Vanilla.Discussions.Announce', true, 'Category', $permissionCategoryID); $canSink = $session->checkPermission('Vanilla.Discussions.Sink', true, 'Category', $permissionCategoryID); $canClose = $session->checkPermission('Vanilla.Discussions.Close', true, 'Category', $permissionCategoryID); $canDelete = $session->checkPermission('Vanilla.Discussions.Delete', true, 'Category', $permissionCategoryID); $canMove = $canEdit && $session->checkPermission('Garden.Moderation.Manage'); $canRefetch = $canEdit && valr('Attributes.ForeignUrl', $discussion); $canDismiss = c('Vanilla.Discussions.Dismiss', 1) && $discussion->Announce == '1' && $discussion->Dismissed != '1' && $session->isValid(); if ($canEdit && $timeLeft) { $timeLeft = ' (' . Gdn_Format::seconds($timeLeft) . ')'; } $dropdown->addLinkIf($canDismiss, t('Dismiss'), "vanilla/discussion/dismissannouncement?discussionid={$discussionID}", 'dismiss', 'DismissAnnouncement Hijack')->addLinkIf($canEdit, t('Edit') . $timeLeft, '/post/editdiscussion/' . $discussionID, 'edit')->addLinkIf($canAnnounce, t('Announce'), '/discussion/announce?discussionid=' . $discussionID, 'announce', 'AnnounceDiscussion Popup')->addLinkIf($canSink, t($discussion->Sink ? 'Unsink' : 'Sink'), '/discussion/sink?discussionid=' . $discussionID . '&sink=' . (int) (!$discussion->Sink), 'sink', 'SinkDiscussion Hijack')->addLinkIf($canClose, t($discussion->Closed ? 'Reopen' : 'Close'), '/discussion/close?discussionid=' . $discussionID . '&close=' . (int) (!$discussion->Closed), 'close', 'CloseDiscussion Hijack')->addLinkIf($canRefetch, t('Refetch Page'), '/discussion/refetchpageinfo.json?discussionid=' . $discussionID, 'refetch', 'RefetchPage Hijack')->addLinkIf($canMove, t('Move'), '/moderation/confirmdiscussionmoves?discussionid=' . $discussionID, 'move', 'MoveDiscussion Popup')->addLinkIf($canDelete, t('Delete Discussion'), '/discussion/delete?discussionid=' . $discussionID . '&target=' . $categoryUrl, 'delete', 'DeleteDiscussion Popup'); // DEPRECATED $options = []; $sender->EventArguments['DiscussionOptions'] =& $options; $sender->EventArguments['Discussion'] = $discussion; $sender->fireEvent('DiscussionOptions'); // Backwards compatability $dropdown = discussionOptionsToDropdown($options, $dropdown); // Allow plugins to edit the dropdown. $sender->EventArguments['DiscussionOptionsDropdown'] =& $dropdown; $sender->EventArguments['Discussion'] = $discussion; $sender->fireEvent('DiscussionOptionsDropdown'); return $dropdown; }