Custom Fields that use CSS or JavaScript Web Resources in JIRA 5.0

Plugin developers commonly use CSS or JavaScript web resources for custom fields, in order to modify the look and feel of these fields or provide these fields with dynamic interaction capabilities. Prior to JIRA 5.0, this would typically have been achieved using using the WebResourceManager from a custom field's "edit" HTML. However, this is no longer supported in JIRA 5.0 and any custom field types that do so will not have their requested web resources included in JIRA 5.0's new Edit Issue and Create Issue dialog boxes. Since these dialog boxes are enabled by default in JIRA 5.0, developers whose plugins use CSS or JavaScript web resources for custom fields are recommended that they update their plugins for JIRA 5.0+ (using the guidelines below), so that these custom fields will work correctly in these dialog boxes.

(info) Be aware that these JIRA 5.0+ modifications will continue to work in the form/page versions of these dialog boxes in earlier versions of JIRA.

How to Update your Plugin

There are two things custom field types need to consider to upgrade to 5.0:

  • Custom field types that want to include web resources should include their web resources in the atl.general contexts. Doing so will result in a plugin that works in 5.0+ and will also work in 4.2+.
  • Any of the JavaScript in these web resources may have been doing work on page load. For example, looking for and binding to the HTML element of the rendered custom field. Because, in the case of the Edit Issue and Create Issue dialog boxes, such HTML elements may not be on the page until after page load (until a user invokes one of these dialog boxes), plugins should use the JIRA.Events.NEW_CONTENT_ADDED as well as page-load to do this work. This event is new in JIRA 5.0.
  • For JavaScript that wants to simply bind to events, an alternative to using JIRA.Events.NEW_CONTENT_ADDED is simply use a jQuery live or delegate event. JIRA 4.4+ shipped with jQuery 1.5.2+, which supports the delegate() event. JIRA 4.2+ shipped with jQuery 1.4.2+ which supports live().

Example Problem

For example, a plugin might have had a custom field type like this.

atlassian.xml (fragment)
    <customfield-type key="textarea" name="Testing Contexts and Resources"
                      class="com.atlassian.jira.issue.customfields.impl.TextAreaCFType">
        <description>Test custom fields</description>
        <resource type="velocity" name="view" location="value.vm"/>
        <resource type="velocity" name="column-view" location="value.vm"/>
        <resource type="velocity" name="edit" location="textarea.vm"/>
        <resource type="velocity" name="xml" location="value.vm"/>
    </customfield-type>
    <web-resource name="Resources" key="resources">
        <resource name="foo.js" type="download" location="foo.js"></resource>
    </web-resource>
 
textarea.vm
$webResourceManager.requireResource("id.au.penny.jiracontexts.jira-context-plugin:resources")
<div class="myspecialfield">
    This is a text box! <input type="text" name="$customField.id" value="$!value" />
    <br>Preview: <span class="myspecialpreview"></span>
</div>
foo.js
AJS.$(function () {
    var onchange = function (e) {
        var t = AJS.$(e.target);
        var resetPreview = function () {
            var parent = t.parent();
            var preview = AJS.$(".myspecialpreview", parent);
            preview.text(t.val());
        };
        setTimeout(resetPreview, 0);
    };
    AJS.$(".myspecialfield input").bind("change keypress keydown", onchange);
});

Example Solution

To fix this plugin, the call to requireResource() should be removed, and the <web-resource> should be included in the atl.general contexts:

atlassian.xml (fragment)
    <customfield-type key="textarea" name="Testing Contexts and Resources"
                      class="com.atlassian.jira.issue.customfields.impl.TextAreaCFType">
        <description>Test custom fields</description>
        <resource type="velocity" name="view" location="value.vm"/>
        <resource type="velocity" name="column-view" location="value.vm"/>
        <resource type="velocity" name="edit" location="textarea.vm"/>
        <resource type="velocity" name="xml" location="value.vm"/>
    </customfield-type>
    <web-resource name="Resources" key="resources">
        <context>atl.general</context>
        <resource name="foo.js" type="download" location="foo.js"></resource>
    </web-resource>
 
textarea.vm
<div class="myspecialfield">
    This is a text box! <input type="text" name="$customField.id" value="$!value" />
    <br>Preview: <span class="myspecialpreview"></span>
</div>

Additionally, we need to change the JavaScript so that it listens for events on elements that might be added after the page has loaded. In this case we use live().

AJS.$(function () {
    var onchange = function (e) {
        var t = AJS.$(e.target);
        var resetPreview = function () {
            var parent = t.parent();
            var preview = AJS.$(".myspecialpreview", parent);
            preview.text(t.val());
        };
        setTimeout(resetPreview, 0);
    };
    AJS.$(".myspecialfield input").live("change keypress keydown", onchange);
});

If your custom field needs to execute JavaScript each time your field is rendered, you can use the JIRA.Events.NEW_CONTENT_ADDED event (added in JIRA 5.0):

JIRA.bind(JIRA.Events.NEW_CONTENT_ADDED, function (e, context) {
    AJS.$(".myspecialfield", context).css("background-color", "#8f8");
});

Reason for change

The reason requireResource() this is no longer supported in the "edit" velocity of custom fields: In the Create Issue and Edit Issue dialog boxes, the edithtml is parcelled into a JSON payload via an AJAX request, and displayed dynamically on a page that already has all its web resource loaded. There is no opportunity for this AJAX request to add further JS to the page.

In the future

In JIRA 5.1, calling requireResource() will not be supported for the other views of a custom field, either. Plugin authors are encouraged to put such web resoruces in the atl.general context instead of calling requireResource() from their velocity.

In future versions of JIRA, it is likely that calling requireResource() from the velocity templates of certain web items and web-panels locations may also be deprecated/unsupported, and plugin developers are encouraged to include such web resources in the appropriate contexts, instead.

Was this page helpful?

Have a question about this article?

See questions about this article

Powered by Confluence and Scroll Viewport