Drupal 7: How to Add Bootstrap Multi-level Dropdown Submenu

Submitted by admin on Mon, 04/11/2016 - 10:57

Download and install a Bootstrap theme. Modify the following at
vi bootstrap/templates/menu/system/form-element.func.php

 
/**
* Overrides theme_form_element().
*/
function bootstrap_form_element(&$variables) {
$element = &$variables['element'];
$name = !empty($element['#name']) ? $element['#name'] : FALSE;
$type = !empty($element['#type']) ? $element['#type'] : FALSE;
$checkbox = $type && $type === 'checkbox';
$radio = $type && $type === 'radio';

// Create an attributes array for the wrapping container.
if (empty($element['#wrapper_attributes'])) {
$element['#wrapper_attributes'] = array();
}
$wrapper_attributes = &$element['#wrapper_attributes'];

// This function is invoked as theme wrapper, but the rendered form element
// may not necessarily have been processed by form_builder().
$element += array(
'#title_display' => 'before',
);

// Add wrapper ID for 'item' type.
if ($type && $type === 'item' && !empty($element['#markup']) && !empty($element['#id'])) {
$wrapper_attributes['id'] = $element['#id'];
}

// Check for errors and set correct error class.
if ((isset($element['#parents']) && form_get_error($element)) || (!empty($element['#required']) && bootstrap_setting('forms_required_has_error'))) {
$wrapper_attributes['class'][] = 'has-error';
}

// Add necessary classes to wrapper container.
$wrapper_attributes['class'][] = 'form-item';
if ($name) {
$wrapper_attributes['class'][] = 'form-item-' . drupal_html_class($name);
}
if ($type) {
$wrapper_attributes['class'][] = 'form-type-' . drupal_html_class($type);
}
if (!empty($element['#attributes']['disabled'])) {
$wrapper_attributes['class'][] = 'form-disabled';
}
if (!empty($element['#autocomplete_path']) && drupal_valid_path($element['#autocomplete_path'])) {
$wrapper_attributes['class'][] = 'form-autocomplete';
}

// Checkboxes and radios do no receive the 'form-group' class, instead they
// simply have their own classes.
if ($checkbox || $radio) {
$wrapper_attributes['class'][] = drupal_html_class($type);
}
elseif ($type && $type !== 'hidden') {
// change
$wrapper_attributes['class'][] = 'form-group form-inline';
}

// Create a render array for the form element.
$build = array(
'#theme_wrappers' => array('container__form_element'),
'#attributes' => $wrapper_attributes,
);

// Render the label for the form element.
$build['label'] = array(
'#markup' => theme('form_element_label', $variables),
);

// Increase the label weight if it should be displayed after the element.
if ($element['#title_display'] === 'after') {
$build['label']['#weight'] = 10;
}

// Checkboxes and radios render the input element inside the label. If the
// element is neither of those, then the input element must be rendered here.
if (!$checkbox && !$radio) {
$prefix = isset($element['#field_prefix']) ? $element['#field_prefix'] : '';
$suffix = isset($element['#field_suffix']) ? $element['#field_suffix'] : '';
if ((!empty($prefix) || !empty($suffix)) && (!empty($element['#input_group']) || !empty($element['#input_group_button']))) {
if (!empty($element['#field_prefix'])) {
$prefix = '<span class="input-group-' . (!empty($element['#input_group_button']) ? 'btn' : 'addon') . '">' . $prefix . '</span>';
}
if (!empty($element['#field_suffix'])) {
$suffix = '<span class="input-group-' . (!empty($element['#input_group_button']) ? 'btn' : 'addon') . '">' . $suffix . '</span>';
}

// Add a wrapping container around the elements.
$input_group_attributes = &_bootstrap_get_attributes($element, 'input_group_attributes');
$input_group_attributes['class'][] = 'input-group';
$prefix = '<div' . drupal_attributes($input_group_attributes) . '>' . $prefix;
$suffix .= '</div>';
}

// Build the form element.
$build['element'] = array(
'#markup' => $element['#children'],
'#prefix' => !empty($prefix) ? $prefix : NULL,
'#suffix' => !empty($suffix) ? $suffix : NULL,
);
}

// Construct the element's description markup.
if (!empty($element['#description'])) {
$build['description'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array('help-block'),
),
'#weight' => 20,
0 => array('#markup' => filter_xss_admin($element['#description'])),
);
}

// Render the form element build array.
return drupal_render($build);
}

Modify the following at
vi bootstrap/templates/menu/menu-link.func.php

 
/**
* Overrides theme_menu_link().
*/
function bootstrap_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';

if ($element['#below']) {
// Prevent dropdown functions from being added to management menu so it
// does not affect the navbar module.
if (($element['#original_link']['menu_name'] == 'management') && (module_exists('navbar'))) {
$sub_menu = drupal_render($element['#below']);
}
// change == 1 to >= 1
elseif ((!empty($element['#original_link']['depth'])) && ($element['#original_link']['depth'] >= 1)) {
// Add our own wrapper.
unset($element['#below']['#theme_wrappers']);
$sub_menu = '<ul class="dropdown-menu">' . drupal_render($element['#below']) . '</ul>';
// Generate as standard dropdown.
// change
// $element['#title'] .= ' <span class="caret"></span>';
// $element['#attributes']['class'][] = 'dropdown';
$element['#attributes']['class'][] = 'dropdown-submenu';
$element['#localized_options']['html'] = TRUE;

// Set dropdown trigger element to # to prevent inadvertant page loading
// when a submenu link is clicked.
$element['#localized_options']['attributes']['data-target'] = '#';
$element['#localized_options']['attributes']['class'][] = 'dropdown-toggle';
// $element['#localized_options']['attributes']['data-toggle'] = 'dropdown';
}
}
// On primary navigation menu, class 'active' is not set on active menu item.
// @see
" title="https://drupal.org/node/1896674
">https://drupal.org/node/1896674
if (($element['#href'] == $_GET['q'] || ($element['#href'] == '<front>' && drupal_is_front_page())) && (empty($element['#localized_options']['language']))) {
$element['#attributes']['class'][] = 'active';
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}

Add the following into the theme
vi bootstrap/css/overrides.css

 
.container-inline {
margin-bottom: 10px;
}

.btn-default,
.btn-info {
color: white;
background-color: #428bca;
border-color: #ccc;
}

.btn-default:focus,
.btn-default.focus,
.btn-info:focus,
.btn-info.focus {
color: white;
background-color: #195cad;
border-color: #8c8c8c;
}

.btn-default:hover,
.btn-info:hover{
color: white;
background-color: #195cad;
border-color: #adadad;
}

.btn-default:active,
.btn-default.active,
.btn-default:info,
.btn-default.info,
.open > .dropdown-toggle.btn-default {
color: white;
background-color: #195cad;
border-color: #adadad;
}

.btn-default:active:hover,
.btn-default.active:hover,
.open > .dropdown-toggle.btn-default:hover,
.btn-default:active:focus,
.btn-default.active:focus,
.open > .dropdown-toggle.btn-default:focus,
.btn-default:active.focus,
.btn-default.active.focus,
.open > .dropdown-toggle.btn-default.focus,
.btn-default:active:hover,
.btn-default.active:hover,
.open > .dropdown-toggle.btn-info:hover,
.btn-info:active:focus,
.btn-info.active:focus,
.open > .dropdown-toggle.btn-info:focus,
.btn-info:active.focus,
.btn-info.active.focus,
.open > .dropdown-toggle.btn-info.focus {
color: white;
background-color: #d4d4d4;
border-color: #8c8c8c;
}

.btn-default:active,
.btn-default.active,
.btn-info:active,
.btn-info.active,
.open > .dropdown-toggle.btn-default {
background-image: none;
}

button[disabled],
button.disabled,
.btn-default.disabled,
.btn-default[disabled],
fieldset[disabled] .btn-default,
.btn-default.disabled:hover,
.btn-default[disabled]:hover,
fieldset[disabled] .btn-default:hover,
.btn-default.disabled:focus,
.btn-default[disabled]:focus,
fieldset[disabled] .btn-default:focus,
.btn-default.disabled.focus,
.btn-default[disabled].focus,
fieldset[disabled] .btn-default.focus,
.btn-default.disabled:active,
.btn-default[disabled]:active,
fieldset[disabled] .btn-default:active,
.btn-default.disabled.active,
.btn-default[disabled].active,
fieldset[disabled] .btn-default.active,

.btn-info.disabled,
.btn-info[disabled],
fieldset[disabled] .btn-info,
.btn-info.disabled:hover,
.btn-info[disabled]:hover,
fieldset[disabled] .btn-info:hover,
.btn-info.disabled:focus,
.btn-info[disabled]:focus,
fieldset[disabled] .btn-info:focus,
.btn-info.disabled.focus,
.btn-info[disabled].focus,
fieldset[disabled] .btn-info.focus,
.btn-info.disabled:active,
.btn-info[disabled]:active,
fieldset[disabled] .btn-info:active,
.btn-info.disabled.active,
.btn-info[disabled].active,
fieldset[disabled] .btn-info.active {
color: #ccc;
background-color: #fff;
border-color: #ccc;
}

.btn-success.disabled,
.btn-success[disabled],
fieldset[disabled] .btn-success,
.btn-success.disabled:hover,
.btn-success[disabled]:hover,
fieldset[disabled] .btn-success:hover,
.btn-success.disabled:focus,
.btn-success[disabled]:focus,
fieldset[disabled] .btn-success:focus,
.btn-success.disabled.focus,
.btn-success[disabled].focus,
fieldset[disabled] .btn-success.focus,
.btn-success.disabled:active,
.btn-success[disabled]:active,
fieldset[disabled] .btn-success:active,
.btn-success.disabled.active,
.btn-success[disabled].active,
fieldset[disabled] .btn-success.active {
color: white;
}

#edit-stop-all-servers,
#edit-terminate {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}

#edit-stop-all-servers:focus,
#edit-stop-all-servers.focus,

#edit-terminate:focus,
#edit-terminate.focus {
color: #fff;
background-color: #c9302c;
border-color: #761c19;
}

#edit-stop-all-servers:hover,
#edit-stop-all-servers:active,
#edit-stop-all-servers.active,
.open > .dropdown-toggle #edit-stop-all-servers,

#edit-terminate:hover,
#edit-terminate:active,
#edit-terminate.active,
.open > .dropdown-toggle #edit-terminate {
color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}

#edit-stop-all-servers:active:hover,
#edit-stop-all-servers.active:hover,
#edit-stop-all-servers:active:focus,
#edit-stop-all-servers:active.focus,

#edit-terminate:active:hover,
#edit-terminate.active:hover,
#edit-terminate:active:focus,
#edit-terminate:active.focus,

.open > .dropdown-toggle #edit-stop-all-servers:hover,
.open > .dropdown-toggle #edit-stop-all-servers:focus,
.open > .dropdown-toggle #edit-stop-all-servers.focus,

.open > .dropdown-toggle #edit-terminate:hover,
.open > .dropdown-toggle #edit-terminate:focus,
.open > .dropdown-toggle #edit-terminate.focus {
color: #fff;
background-color: #ac2925;
border-color: #761c19;
}

#edit-stop-all-servers:active,
#edit-stop-all-servers.active,
.open > .dropdown-toggle #edit-stop-all-servers,

#edit-terminate:active,
#edit-terminate.active,
.open > .dropdown-toggle #edit-terminate {
background-image: none;
}

#edit-stop-all-servers.disabled,
#edit-stop-all-servers[disabled],
fieldset[disabled] #edit-stop-all-servers,
#edit-stop-all-servers.disabled:hover,
#edit-stop-all-servers[disabled]:hover,
fieldset[disabled] #edit-stop-all-servers:hover,
#edit-stop-all-servers.disabled:focus,
#edit-stop-all-servers[disabled]:focus,
fieldset[disabled] #edit-stop-all-servers:focus,
#edit-stop-all-servers.disabled.focus,
#edit-stop-all-servers[disabled].focus,
fieldset[disabled] #edit-stop-all-servers.focus,
#edit-stop-all-servers.disabled:active,
#edit-stop-all-servers[disabled]:active,
fieldset[disabled] #edit-stop-all-servers:active,
#edit-stop-all-servers.disabled.active,
#edit-stop-all-servers[disabled].active,
fieldset[disabled] #edit-stop-all-servers.active,

#edit-terminate.disabled,
#edit-terminate[disabled],
fieldset[disabled] #edit-terminate,
#edit-terminate.disabled:hover,
#edit-terminate[disabled]:hover,
fieldset[disabled] #edit-terminate:hover,
#edit-terminate.disabled:focus,
#edit-terminate[disabled]:focus,
fieldset[disabled] #edit-terminate:focus,
#edit-terminate.disabled.focus,
#edit-terminate[disabled].focus,
fieldset[disabled] #edit-terminate.focus,
#edit-terminate.disabled:active,
#edit-terminate[disabled]:active,
fieldset[disabled] #edit-terminate:active,
#edit-terminate.disabled.active,
#edit-terminate[disabled].active,
fieldset[disabled] #edit-terminate.active {
background-color: #d9534f;
border-color: #d43f3a;
}

/* warning */

#edit-reboot {
color: #fff;
background-color: #f0ad4e;
border-color: #eea236;
}

#edit-reboot:focus {
color: #fff;
background-color: #ed9c28;
border-color: #d58512;
}

#edit-reboot:hover,
#edit-reboot:active,
#edit-reboot.active,
.open > .dropdown-toggle #edit-reboot.active {
color: #fff;
background-color: #ed9c28;
border-color: #d58512;
}

#edit-reboot:active:hover,
#edit-reboot.active:hover,
#edit-reboot:active:focus,
#edit-reboot:active.focus,

.open > .dropdown-toggle #edit-reboot:hover,
.open > .dropdown-toggle #edit-reboot:focus,
.open > .dropdown-toggle #edit-reboot.focus {
color: #fff;
background-color: #ed9c28;
border-color: #d58512;
}

#edit-reboot:active,
#edit-reboot.active,
.open > .dropdown-toggle #edit-reboot {
background-image: none;
}

#edit-reboot.disabled,
#edit-reboot[disabled],
fieldset[disabled] #edit-reboot,
#edit-reboot.disabled:hover,
#edit-reboot[disabled]:hover,
fieldset[disabled] #edit-reboot:hover,
#edit-reboot.disabled:focus,
#edit-reboot[disabled]:focus,
fieldset[disabled] #edit-reboot:focus,
#edit-reboot.disabled.focus,
#edit-reboot[disabled].focus,
fieldset[disabled] #edit-reboot.focus,
#edit-reboot.disabled:active,
#edit-reboot[disabled]:active,
fieldset[disabled] #edit-reboot:active,
#edit-reboot.disabled.active,
#edit-reboot[disabled].active,
fieldset[disabled] #edit-reboot.active {
background-color: #f0ad4e;
border-color: #eea236;
}

.img-responsive {
display: inline;
margin-left: 3px;
}

.menu.nav > li {
display: inline-block;
vertical-align: top;
margin: 12px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}

.menu.nav.navbar-nav.secondary {
margin: -5px 0px 0px 0px;
}

.nav li a {
color: white;
/*
background-color: black;
*/
margin: 0px 0px 2px 0px;
}

.nav-tabs > li > a {
color: #428bca;
border-color: white;
}

.dropdown-menu > li > a {
color: #428bca;
background-color: white;
}

.menu.nav > li a:active,
.menu.nav > li a:hover,
.menu.nav > li.dropdown.active.open > a,
.menu.nav > li.dropdown-submenu.active.open > a {
color: white;
background-color: #195cad;
}

/* comment out if selected item can be colored */
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
color:#428bca;
background-color: white;
}

/* change navbar dropdown color */
.menu.nav .open .dropdown-menu,
.menu.nav .open .dropdown-menu > li > a,
.menu.nav .open .dropdown-submenu,
.menu.nav .open .dropdown-submenu > li > a {
color:#428bca;
background-color: white;
}

.menu.nav .open .dropdown-menu > li > a:hover {
color: white;
background-color: #428bca;
}

.region.region-navigation {
float: left;
}

ul.dropdown-menu,
ul.dropdown-submenu {
padding: 5px 0px;
margin: 0px;
color: black;
background-color: white;
}

.navbar-header img {
height: 50px;
}

.navbar-header {
/* width: 800px; */
height: 50px;
background-color: black;
}

.navbar {
background-color: black;
}

h1.page-header {
font-size: medium;
margin-bottom: 10px
}

h2.block-title {
margin-bottom: 0px;
}

.container-inline .form-inline {
margin: 0px 7px;
float: left; /* Tips: this is important! */
}

.container-inline fieldset .form-inline {
margin: 0px 7px;
float: left; /* Tips: this is important! */
}

.container-inline fieldset label {
margin-top: 7px;
margin-bottom: 0px;
display: inline-block;
}

fieldset .form-inline {
margin: 0px 7px;
float: none; /* Tips: this is important! */
}

.table > thead > tr > th,
.table > tbody > tr > th,
.table > tfoot > tr > th,
.table > thead > tr > td,
.table > tbody > tr > td,
.table > tfoot > tr > td {

vertical-align: middle;
}

.form-submit {
margin: 0px 7px;
}

.panel-body {
/* display: inline-block; */
}

/** dropdown-submenu 2015/05/10 */

/*
.dropdown-submenu {position:relative;}
.dropdown-submenu>.dropdown-menu {top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;}
.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;}
.dropdown-submenu:hover>a:after{border-left-color:#555;}
.dropdown-submenu.pull-left{float:none;}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;}
*/

.dropdown-submenu {
position: relative;
}
.dropdown-submenu>.dropdown-menu {
top: 0;
left: 100%;
margin-top: 5px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
/*
color:#428bca;
background-color: white;
*/
}

.dropdown-submenu:hover>.dropdown-menu {
display: block;
}
.dropdown-submenu>a:after {
display: block;
content: " ";
float: right;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
border-left-color: #cccccc;
margin-top: 5px;
margin-right: -10px;
}
.dropdown-submenu:hover>a:after {
border-left-color: #ffffff;
}

.dropdown-submenu.pull-left {
float: none;
}

.dropdown-submenu.pull-left>.dropdown-menu {
left: -100%;
margin-left: 10px;
-webkit-border-radius: 6px 0 6px 6px;
-moz-border-radius: 6px 0 6px 6px;
border-radius: 6px 0 6px 6px;
}

Tags