Loading Issue Tab Panels with AJAX

JIRA 5.0 changes the way in which tabs are rendered on the view issue page. Previously the module was always rendered in the same request as the View Issue screen. In JIRA 5.0, however, the HTML content of an issue tab may returned by an AJAX call and inserted into the view issue page without triggering a full page reload. This improves the perceived performance of the View Issue page and also reduces load on the JIRA server.

How do I enable AJAX loading of issue tab panels?

To enable AJAX loading for an issue tab, each <issue-tabpanel> must opt in by adding the <supports-ajax-load> element to its declaration in the atlassian-plugin.xml. Here is an excerpt of the XML file that configures the JIRA's "All" issue tab:

<issue-tabpanel key="all-tabpanel" i18n-name-key="admin.issue.tabpanels.plugin.all.name" name="All Tab Panel" class="com.atlassian.jira.issue.tabpanels.AllTabPanel">
    <!-- other stuff... -->
    <supports-ajax-load>true</supports-ajax-load>
</issue-tabpanel>

The <supports-ajax-load> element controls whether JIRA will load this issue tab using an AJAX request.

What do I need to change in my plugin?

In many cases it will be sufficient to add the <supports-ajax-load> element each issue tab's declaration in the atlassian-plugin.xml. However, there are two things that plugins may do that will prevent the AJAX loaded tabs from working correctly, namely:

  1. calling WebResourceManager.requireResource(String) from within the IssueTabPanel implementation, and
  1. defining Javascript callbacks that are registered with AJS.$(document).ready() and its variants.

If your plugin does any of these things, you should read the remainder of this section to understand the changes that are needed before enabling AJAX loading of your issue tab panel.

Uses of WebResourceManager.requireResource(java.lang.String)

Since IssueTabPanel.getActions(Issue, User) is now called in a separate request from the one that renders the view issue page, calling WebResourceManager.requireResource(java.lang.String) does not guarantee that the resource will be included on the view issue page. Plugins that rely on this behaviour will not work correctly with AJAX loading, because the Javascript and/or CSS resources will not be loaded at the time the tab is displayed.

To make sure that resources are included, use the jira.view.issue web resource context in your <web-resource> definition as in the following example.

<web-resource key="myPluginViewIssue" name="MyPlugin's JS">
    <context>jira.view.issue</context>
    <dependency>jira.webresources:viewissue</dependency>
    <resource type="download" name="myJS.js" location="script/myJS.js"/>
</web-resource>

Uses of AJS.$(document).ready()

If your plugin contains Javascript that needs to execute when the tab is loaded, it should register a callback with JIRA.ViewIssueTabs.onTabReady() instead of using AJS.$(document).ready(). For example, if a JIRA 4.4 plugin contains the following Javascript file:

myPluginViewIssue.js
AJS.$(document).ready(function () {
    AJS.$('.tab-content').find('.project-activity:gt(0)').addClass('hidden');
})

This file should be changed to the following in order to work in JIRA 5.0.

myPluginViewIssue.js
JIRA.ViewIssueTabs.onTabReady(function() {
    AJS.$('.tab-content').find('.project-activity:gt(0)').addClass('hidden');
})

What if my issue tab is already loaded asynchronously?

This section is only relevant for plugins that already implement their own AJAX loading.

Several plugins already implement some form of AJAX loading for their issue tabs. Generally this is done by returning a single action that has inline Javascript to trigger an additional AJAX request (in the code below, this would be the AjaxTabPanelAction class). These plugins will most likely want to suppress that mechanism when the issue tab is being loaded asynchronously by JIRA, so as to avoid a double AJAX request.

Issue tab panels that need this level of integration can implement the IssueTabPanel2 interface to get more information about how the tab panel is being loaded. See the documentation for the com.atlassian.jira.plugin.issuetabpanel package. The following code is an example of how the new interface can be used.

@Override
public GetActionsReply getActions(GetActionsRequest request)
{
    if (!request.isAsynchronous())
    {
        return GetActionsReply.create(new AjaxTabPanelAction(request));
    }
    
    return GetActionsReply.create(getActionsList(request));
}
Was this page helpful?

Have a question about this article?

See questions about this article

Powered by Confluence and Scroll Viewport