JavaScript Not Working On Second Modal Open

PROBLEM
I was having issues when I opened a second, third, fourth, etc modal. Here’s what was happening:

I open different modals when the user clicks on different buttons. These modals produce a different form depending on what button the user clicked.

However, if the user clicks out of the modal, it would close. If they clicked into a second modal, none of the JQuery would work in the modal. The JQuery I had was a date popup and other functionality. I thought it might have been an issue with datepicker JQuery initially but then I realized other JQuery in the modal wasn’t working either.

I finally realized that since I was appending a div onto the body, that div was never getting destroyed upon modal close. All that was left was to destroy the div when the modal closed.

Easy, right?

WRONG!

After googling such things like “remove modal that’s been appended to body jquery”, “destroy modal on close jquery”,  “on modal hide jquery” “jquery not working on second modal”, etc. I couldn’t find a solution. Everything I tried from
.on("hidden.bs.modal"...) stuff like that wouldn’t work.

SOLUTION
I finally thought outside the box!

Since all my HTML that I use to produce a modal had the same ID (hence the issue, duplicate IDs being added to the HTML), I would simply remove that upon another click. So in my JS when I’m clicking on a link to open a modal it’s:

$(".modal_ajax").click(function(event) {
	$("#ajax_wrapper").remove(); // remove any other modals
	event.preventDefault();
	this.blur();
	$.get(this.href, function(html) {
		$(html).appendTo("body").modal({
			fadeDuration: 700,
			fadeDelay: 0.20
		});
	});
});

Adding the $("#ajax_wrapper").remove(); did the trick!

Drupal Not Picking Up Theme Suggestion

PROBLEM
When I go to create a theme suggestion like this:

function my_theme_theme_suggestions_related_content_alter(&$suggestions, &$vars, $hook) {
  if (isset($vars["plugin_id"])) {
    $suggestions[] = $hook . "--" . $vars["plugin_id"];
  }
}

Drupal isn’t picking up on the file when I do a cache clear. The theme suggestion was not working.

It says the correct FILE NAME SUGGESTIONS in the commented HTML but the template isn’t being displayed. The older one still is.

SOLUTION
Get rid of the dashes!

function my_theme_theme_suggestions_related_content_alter(&$suggestions, &$vars, $hook) {
  if (isset($vars["plugin_id"])) {
    $suggestions[] = $hook . "__" . $vars["plugin_id"];
  }
}

It now picks up it fine! That was simple but took a few minutes to find the answer.

Attached JS Libraries Not Working When Caching Turned Off On Block

PROBLEM
Came across a weird one yesterday. I had just finished touches on a HighCharts block. I noticed that it wasn’t refreshing with updated content. Well I know what to do about that.

I added the getCacheMaxAge(). But then! Oh no!

I got a JS error saying HighCharts wasn’t defined. What the? And viewing the source, the two libraries I was including in the block were not included. What happened?

SOLUTION
I’m not fully sure why this happened the way it did. I tried several other things like adding the kill switch (\Drupal::service("page_cache_kill_switch")->trigger();) and adding "#cache" => array("max-age" => 0) to the returned array in the build method.

I then just decided to try a shot in the dark and instead of making the cached age 0, I made it 1 (as in one second)… So just this in the build method:

return array(
	...
	"#cache" => array(
		"max-age" => 1
	),
	...

So… whatever Drupal. It works… until it doesn’t.

Why Won’t If “Drupal\node\NodeForm” Work?

PROBLEM
I need to determine what kind of object a form is. When I dpm the class, it says Drupal\node\NodeForm . So, the following should work:

if (get_class($form_state->getFormObject()) == "Drupal\node\NodeForm") {

But it does not! I’ve been forced to do stupid things like this:

if (get_class($form_state->getFormObject()) != "Drupal\node\Form\DeleteMultiple") {

SOLUTION
DUH MOMENT! I finally figured it out today. VS code highlighted this out of the above first line of code:

\n

DUH! PHP is reading this as a new line! Wow.

New code that works is:

if (get_class($form_state->getFormObject()) == "Drupal\\node\NodeForm") {

This does make sense now that I think about it!

Used Drupal 8 Functions That Don’t Work In Drupal 9

Not really a problem/solution post.

We’re upgrading to Drupal 9! Let me tell you, what a crock that Upgrade Status module is. It’s a trap! It does so little it’s almost laughable. It primarily told me that all my .info.yml files just needed core_version_requirement: ^8.8 || ^9 and they were good.

That’s not true. It’s a scam. We upgraded to D9 and things broke all over the place. Symphony has been giving us the most trouble. Sometimes the error will tell you what to change it to, most of the times not.

Anyway, here’s a blog post of stuff I had to figure out how to change on my own since simply googling for it won’t yield the fix you’re looking for.

\Drupal::service(“path.alias_storage”)->aliasExists

If you’re trying to check if an alias exists like this:

if (\Drupal::service("path.alias_storage")->aliasExists($node_path, "en")) {

That function doesn’t exist anymore. It takes more to figure this out now; especially since the return of this isn’t true or false; it’s the fucking path.

Your new code for this is:

$possible_node_alias = \Drupal::service("path_alias.manager")->getPathByAlias($node_path);
// is this path a node path? if so, it's the equivalent of aliasExists returning true
if (str_starts_with($possible_node_alias, "/node/") && is_numeric(str_replace("/node/", "", $possible_node_alias))) {

In the if, that’s where it would be true if the alias is in use.

\Drupal::service(“path_alias.manager”)->save

This one was a little easier to track down.

Before it was:

\Drupal::service("path_alias.manager")->save("/node/" . $node_id, $archive_url, "en");

Now it’s:

$path_alias = \Drupal\path_alias\Entity\PathAlias::create(array("path" => "/node/" . $nid, "alias" => $archive_url));
$path_alias->save();

Yay for more lines of code that do the same fucking thing as before!

I’ll update this blog post if there are any more I get stuck on and google doesn’t have the answer.

Installing Library Using Drupal & Composer

PROBLEM
The instructions on drupal.org on how to install a library using composer suck. Or maybe I’m just doing it wrong? I don’t know. But it happened again. I need another library from some outside source.

I thought I just needed to modify my composer.json file and run composer install and it was good but I forgot the other step.

SOLUTION
You also need to run composer require and whatever you named your library.

Here’s the code from my composer.json:

		{
			"type": "package",
			"package": {
				"name": "addon/youtube",
				"version": "2.1.18",
				"type": "drupal-library",
				"dist": {
					"url": "https://download.ckeditor.com/youtube/releases/youtube_2.1.18.zip",
					"type": "zip"
				}
			}
		},

Save the file. Then run:

$ composer require addon/youtube

That should do it. Maybe run another $ composer install so everything is good.

Background Opacity Affecting Text Opacity

PROBLEM
Why do I always forget this? Hopefully I’ll remember why this happens this time with a simple blog post!

When you add opacity to a div, it affects the text opacity as well. Ex.

Your CSS is something like this:

.header_background {
	opacity: .8;
	color: #FFFFFF;
	background-color: #475260;
}

SOLUTION
Do not just use opacity like that. Use it like this:

.header_background {
	color: #FFFFFF;
	background: rgba(47, 52, 60, .8);
}

Now it’s nice:

Get Human-Readable Name Of Media Bundle In Drupal 8

PROBLEM
I need to get the label/name of the bundle of a media entity for a preprocess. Unfortunately, the following code to get the label of the bundle does not work for media:

$current_entity->type->entity->label()

I’ve tried to google various things but nothing came up that was helpful. The code $current_entity->bundle() works to get the machine name of the bundle; but how can we get the human-readable name of the bundle?

SOLUTION
The solution requires something really stupid. If anyone has a method I can call instead, more than welcome to comment!

\Drupal\media\Entity\MediaType::load($current_entity->bundle())->label()

That’s really stupid!

By the way, just to remember, how to get the entity type you can use:

$current_entity->getEntityTypeId()

I think this ticket could possibly make the solution easier: https://www.drupal.org/project/drupal/issues/969180. All entities should use the same methods to get the type, bundle, label, etc. Also, label shouldn’t be ambiguous. It should either be for the title of the entity or for what the entity actually is.

Change Theme To Admin For Custom Module Page

I’ll forgo the PROBLEM/SOLUTION in this one since it’s so quick.

I wanted to make the pages (forms) of a custom module I was creating use the admin theme instead of the public facing theme. Turns out it was really easy.

In the .routing.yml file, add the following:

  options:
    _admin_route: TRUE

So a cleaned-up example of the yml looks like this:

whatever_your_form_is.form:
  path: '/whatever/your/path/is'
  defaults:
    _form: '\Drupal\module_name\Form\WhateverYourFormIs'
    _title: 'Page/Form Title'
  requirements:
    _role: 'authenticated'
  options:
    _admin_route: TRUE

Need this in my arsenal.

Unexpected Error With Form Controller

This is going to be a stupid one but I’m going to blog about it anyway.

PROBLEM
While setting up a new custom module for Drupal 8, I need to set up a form. Since I’ve done this many times before, I copied and pasted stuff from another module which worked.

While renaming things and putting things in the right spot, when I went to test the form I got the following error:

TypeError: Argument 2 passed to Symfony\Component\HttpKernel\Event\FilterControllerEvent::__construct() must be callable, object given, called in /var/www/docroot/vendor/symfony/http-kernel/HttpKernel.php on line 138 in Symfony\Component\HttpKernel\Event\FilterControllerEvent->__construct() (line 32 of /var/www/docroot/vendor/symfony/http-kernel/Event/FilterControllerEvent.php)

Google was completely useless! It seems I was the only one in history to get this.

SOLUTION
Considering how fucking burnt out I am without having a break in more than a year, I completely missed it. The solution was so simple.

I guess I had renamed my file wrong in the /module_name/src/Form/ folder. After renaming everything again to bullshit, I found I guess that was my issue.

I’m filling this under silly mistakes that I hope I never make again! #stupidjanny