Making Nice Menus Responsive In Drupal 8

PROBLEM
I highly recommend Nice Menus for Drupal. I’ve been using it for years and it makes things pretty simple. It’s easy to style over to what you need plus it’s keyboard accessible (which is the huge one)!

Anyway, as far as mobile-friendly/responsive goes, Nice Menus is not. It lacks in that department.

So how do we style it? How do we make it a hamburger menu?

SOLUTION
Turn off nice menus! It kinda sucks, but you need to do it in order to put things into your menu template and create mobile-friendly design.

First, to turn off nice menus, put something like this in a JS file (which DOES use JQuery so be careful; that’s another post for another day):

// we only need to do stuff if it's on mobile
if ($(window).width() < 770) {
	// let's remove the nice menus on resolutions that are 768 and lower
	$("ul.office_main_top_level").removeClass("nice-menu");
	$("ul.office_main_top_level").removeClass("nice-menu-acf-main-navigation");
	$("ul.office_main_top_level").removeClass("nice-menu-down");
	$("ul.office_main_top_level").removeClass("sf-js-enabled");
	$("ul.office_main_top_level").removeClass("sf-arrows");
	$("ul.office_main_top_level").removeClass("nice-menus-processed");
}

Removing those classes will turn off the JavaScript that’s happening with Nice Menus for keyboard accessibility, styles, etc.

Now add something like this to your template at the top (but outside the first ul):

<a href="javascript: void(0);" id="office_main_nav_hamburger"><i class="fa fa-bars"></i><span class="hide">Expand</span></a>

(I’m using Font Awesome for icons.)

Add this after the links in the lis (only if they have children):

<a href="javascript: void(0);" class="expand_link"><i class="fa fa-angle-down"></i><span class="hide">Expand</span></a>

Add some more stuff to your JS file (I did it inside the if window statement above):

$("#office_main_nav_hamburger", context).click(function() {
	$("ul.office_main_top_level").toggle();
	$("#office_main_nav_hamburger i").toggleClass("fa-times fa-bars");
});

$(".expand_link", context).click(function() {
	$(this).closest("li").children("ul.office_main_sub_level").toggleClass("expand_sub_level_mobile");
	$(this).children("i").toggleClass("fa-angle-down fa-angle-up");
});

I won’t walk you through all the CSS but at least now you may have a understanding of how to make Nice Menu’s responsive.

jQuery Is Not Defined In Pattern Lab

PROBLEM
I’ve been tasked with something very tedious. I’m to migrate Drupal 7 to Drupal 8. However, for the theme in Drupal 8 it has been decided we are going to use Pattern Lab. Specifically, using the Emulsify theme as a start.

I got lots of JavaScript errors on the Pattern Lab site to start. I needed to uncomment and create syslinks. Basically, follow the instructions in the \web\themes\custom\acf_enterprise\components\_meta\_01-foot.twig file.

After I got all that working, I proceeded to add jQuery to my branding bar file (located at \web\themes\custom\acf_enterprise\components\_patterns\02-molecules\menus\branding-bar\branding-bar.js).

Per the instructions, I uncommented the JavaScript so that it’s using Drupal behaviors as well. Ex.

(function ($, Drupal) {

    Drupal.behaviors.branding_bar = {
        attach: function (context) {

        }
    }
})(jQuery, Drupal);

Also make sure to include jQuery in the library for your theme on the Drupal 8 side… For example, my branding bar library (\web\themes\custom\my_theme\my_theme.libraries.yml) looks like this:

branding-bar:
  js:
    dist/02-molecules/menus/branding-bar/branding-bar.js: {}
  dependencies:
    - core/drupal
    - core/jquery

It works in Drupal 8! However, it does not in Pattern Lab (i.e. on /themes/custom/my_theme/pattern-lab/public/?p=viewall-molecules-menus).

Soooo… that’s the jist. And I’m getting a jQuery not defined error.

SOLUTION
Try googling this. NOTHING HELPFUL.

What they forget to mention is that you need to include jQuery in the footer of Pattern Lab. I.E in that \web\themes\custom\my_theme\components\_meta\_01-foot.twig file you have to muck around with to get other things to work.

My file now looks like this:

<!--DO NOT REMOVE-->
{{ patternLabFoot | raw }}

<!-- Drupal-specific usage -->
<!-- example using symlinking -->
<!-- cd web/themes/custom/emulsify/components/js -->
<!-- ln -s ../../../../../core/assets/vendor/domready/ready.min.js ./ -->
<!-- ln -s ../../../../../core/misc/drupal.js ./ -->

<!-- need to include jQuery!!! -->
<script src="../../js/jquery-2.0.0b2.js"></script>

<!-- UNCOMMENT AS NECESSARY -->
<script src="../../js/ready.min.js"></script>
<script src="../../js/drupal.js"></script>
<script src="../../js/debounce.js"></script>

<script src="../../../../dist/scripts-styleguide.js"></script>

<!-- If using Drupal.behaviors, uncomment for them to work in Pattern Lab -->
<script>Drupal.attachBehaviors();</script>

</body>
</html>

Notice the include of jquery-2.0.0b2.js. They forgot to mention to put that in there. JQuery now works on it so I should be good to go for about twenty minutes until I run into the next problem.

Also to note that their version of JQuery may not be the same one you’re used to. You may need to include the REAL version of JQuery in this footer file.

… I feel like I’m going to be updating this blog a lot since this theme and the impossible task of Pattern Lab has fallen entirely on my plate.

Strip White Space From Element Using JQuery

PROBLEM
I don’t think I’m going to explain this very well. Here’s a short story long.

So what I was trying to do was kind of confusing as it is. I’ll try to explain… In Drupal 7 there is a cool module called field group table. I needed this module to display data in a table format. However, one of the limitations of this module is that it doesn’t display the label in the th for grouped elements. So say you have an address that you’d like to display in a table. You can use this module but it won’t display the group name in the th. It’ll go above the information.

The "location" text and "CRS Coordinator" text is above the data and not in the t h

I used some slick JQuery to move the “Location” text inside the empty th like so:

$(".table_site_map_info .group_table td #site_map_location_th div span").first().appendTo(".table_site_map_info .group_table th.field-label-hidden:eq(0)");

That did the trick. However I noticed that there was a space added and the “Location” and “CRS Coordinator” didn’t line up correctly with the “Phone” (which isn’t a group).

The "location" and "CRS coordinator" were moved to the t h but there was a space before them which doesn't align

SOLUTION
Unfortunately the JQuery trim function needs a parameter and all the examples on JQuery and around the web always had it using a JavaScript variable. I just needed to trim elements; not variables.

So in other words, I wanted to do something like $(“.table_site_map_info .group_table th”).trim() . However that didn’t work.

I had to go back tho the drawing board kind of. I first got it out of its span (which I thought initially was the spacing problem). I used:

$(".table_site_map_info .group_table th span").contents().unwrap();

This didn’t work. It got rid of the span but it still had the space. After looking at the HTML in FireBug, I saw an added space in the th. I needed to remove the space. Unfortunately, like I said earlier, the trim function was useless. I had to individually set each HTML element to its trimmed self.

So, here’s my code:

$(".table_site_map_info .group_table th.field-label-hidden:eq(0)").text($.trim($(".table_site_map_info .group_table th.field-label-hidden:eq(0)").text()));

Sorry that this is a long post and it’s mostly useless but I hope it can help someone. I wanted to post this to remember it.

a screen shot of what it's supposed to look like

If anyone has a more efficient way to do all the above using JQuery or Drupal, I’d love to hear it.