How to call AJS.$() from a Jira Cloud plugin?

Ilya Kaminsky September 20, 2018

Hello,

Having followed this guide on how to create a Jira plugin, I have successfully installed a plugin to my instance of Jira Cloud. After a substantial amount of boilerplate, I was able to successfully inject AP in order to be able to make JQL calls, such as AP.require(...) and even handle the response by showing the issues as expected and styling them with AUI.

However, I've hit a snag. I want to listen to the user's click event and show a dialog when that happens. According to the documentation for dialog2, it needs to be done by setting a listener with AJS like so: AJS.$("#button").click(...). The problem is that "AJS is not defined." No matter how I try to inject it, be it via a <script> tag, or simply by waiting for it to load with a setTimeout function, it is never available.

The documentation and solutions that I found talk about configuring atlassian-plugin.xml or adding resources in Java. I don't have any of that. In my case, I've simply exposed my local development instance to the public web via ngrok (as suggested in the tutorial) and have installed the plugin using the "Manage add-ons" feature of the Jira Cloud instance.

Here's how I've imported AP:

<script id="connect-loader" async data-options="sizeToParent:true;">
  (function() {
    var getUrlParam = function(param) {
      var codedParam = (new RegExp(param + '=([^&]*)')).exec(window.location.search)[1];
      return decodeURIComponent(codedParam);
    };
 
    var baseUrl = getUrlParam('xdm_e') + getUrlParam('cp');
    var options = document.getElementById('connect-loader').getAttribute('data-options');
 
    var script = document.createElement("script");
    script.src=baseUrl + '/atlassian-connect/all.js';
    script.id = 'all';
 
    if (options) {
      script.setAttribute('data-options', options);
    }
 
    document.getElementsByTagName("head")[0].appendChild(script);
  })();  
</script>

<script type="text/javascript">
  var allScript = document.querySelector('#all');

  function init() {
    // ...
  }

  allScript.addEventListener('load', init);
</script>

Here's how I've imported AUI:

<link href="//cdnjs.cloudflare.com/ajax/libs/aui/7.6.0/aui/css/aui.min.css" media="all" rel="stylesheet" type="text/css">
<script async src="//cdnjs.cloudflare.com/ajax/libs/aui/7.6.0/aui/js/aui.min.js" type="text/javascript"></script>

And this is what I'm trying to accomplish:

AJS.$('.aui-page-panel').click(function(event) {
  event.preventDefault();

  AJS.dialog2('#dialog').show();
});

I can provide more relevant code if necessary.

AJS.$ is undefined while the page is loading. How would I fix that?

2 answers

0 votes
Ilya Kaminsky October 25, 2018

A month later, this is still an issue. I've been making some progress, albeit painfully slowly.

  1. According to this page, 7.9.9 is the latest stable version of AUI
  2. Though the Getting Started page only lets you download a zip of version 7.7.0, by changing the URL to this, it is possible to download version 7.9.9

There seems to be a discrepancy between AUI 7.9.9 that's hosted on the documentations page and the one that I'm supposed to self-host for the plugin. The biggest difference lies in the fact that the former contains AJS.dialog2 while the latter does not.

I've created a quick demonstration of the issue by starting an HTML project on Codepen: https://codepen.io/ilyakam/project/editor/DdzLnm#0 This project includes the JS and CSS files exactly as they appear in the zip above. If you follow the short instructions in the Codepen, you could see the discrepancies for yourself.

Again, my question is, what am I doing wrong? I'm simply trying to invoke a modal with AJS.dialog2, as documented here.

Ilya Kaminsky October 25, 2018

Turns out that in order to get AJS.dialog2 to be exposed correctly, referencing aui.js is not enough. aui-experimental.js and aui-soy.js also need to be referenced.

This is an odd design choice at best, especially because there is no experimental label next to Dialog 2 under "Other Components:"

aui-dialog2-docs.png

0 votes
Ilya Kaminsky September 23, 2018

While trying to go back to the basics, I found more recent versions of AUI, which is important because AJS comes with it. Here's how I added them to the head tag of the plugin's index.html page:

<link href="//cdnjs.cloudflare.com/ajax/libs/aui/7.6.0/aui/css/aui.min.css" media="all" rel="stylesheet" type="text/css">
<script async src="//cdnjs.cloudflare.com/ajax/libs/aui/7.6.0/aui/js/aui.min.js" type="text/javascript"></script>

However still, while the plugin is loading, AJS.$ is not available. It is available in the browser's console after the page is loaded though.

Note how I said AJS.$? That's because when I use the debugger statement at the spot where I need AJS.$, I can call AJS() but I cannot call AJS.$() because AJS.$ is undefined.

Suggest an answer

Log in or Sign up to answer