Skip to end of metadata
Go to start of metadata

Applicable:

This tutorial applies to JIRA 5.0.

Level of experience:

Intermediate. Our tutorials are classified as 'beginner', 'intermediate' and 'advanced'. This one is at 'intermediate' level. If you have never developed a plugin before, you may find this one a bit difficult.

Time to Complete:

1 1/4 hour

 

On this page:

Overview of the Tutorial

This tutorial shows you how to display a dialog with content from the server and have it interact with your page. In this tutorial, you will develop a dialog that sets the version in which an issue should be fixed.

This tutorial adds dialog functionality to already existing plugin that has:

  • A Webwork action for that contains the logic for scheduling an issue.
  • A Velocity template for rendering the form
  • A test for ensuring that the scheduling works.

To display this form in a dialog and have it interact with a the page we will through a few different phases:

Simplest Dialog

Adds a JavaScript resource to "slurp" the form content into a dialog using generic methods.

Standard Dialog

Create a dialog for this specific use case that will work in all circumstances.

Advanced Dialog

We will update the underlying page so that we don't need to do a page refresh.

Plugin Source

We encourage you to work through this tutorial. If you want to skip ahead or check your work when you are done, you can find the plugin source code on Atlassian Bitbucket. Bitbucket serves a public Git repository containing the tutorial's code. To clone the repository, issue the following command to get the completed tutorial code:

git clone https://bitbucket.org/atlassian_tutorial/jira-scheduler-dialog-complete.git

Alternatively, you can download the source using the get source option here: https://bitbucket.org/atlassian_tutorial/tutorial-jira-scheduler.

Required Knowledge

You should already have installed the following software:

  • An integrated development environment(IDE) such as Eclipse or IDEA.
  • Atlassian Plugin SDK 3.7 or higher.
  • Git distributed source control system

You should also understand the Java development basics including classes, interfaces, methods, how to compile source into a JAR file, and so on.

About these Instructions

Icon

You can use any supported combination of OS and IDE to construct this plugin. These instructions were written using Eclipse Classic Version 3.7.1 on a MacBook Air running Mac OS X Version 10.7.2. If you are using another combination, you should use the equivalent operations for your specific environment.

Step 1. Getting the Base Plugin Code

  1. Change directory to your Eclipse workspace.
  2. Download the basetutorial source.

  3. Change directory to the plugin's root directory (where the pom.xml files is located.
  4. Run some the tests to ensure that the starting point is working.

    The command builds the code and runs the integration tests that come with the source. Throughout this tutorial, you'll run a number of atlas-commands that automate much of the work of plugin development for you. If everything run successfully, you should see a message similar to:

    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 2 minutes 19 seconds
    [INFO] Finished at: Sat Nov 26 13:26:03 EST 2011
    [INFO] Final Memory: 70M/123M
    [INFO] ------------------------------------------------------------------------
    

Step 2. Import the Code into Eclipse

  1. Change to the tutorial-jira-scheduler directory created by the previous step.
  2. Run the command:

    atlas-mvn eclipse:eclipse
    
  3. Start Eclipse.
  4. Select File->Import.
    Eclipse starts the Import wizard.
  5. Filter for Existing Projects into Workspace (or expand the General folder tree).
  6. Press Next and enter the root directory of your workspace.
    Your Atlassian plugin folder should appear under Projects.
  7. Select your plugin and click Finish.
    Eclipse imports your project.

Step 3. Verify Your JIRA Version

The source files were compiled against the JIRA version that existed when the code was created. The version designation is in the project pom.xml file (Project Object Model definition file). This file is located in the project project and declares the project dependencies. Take a moment and examine the JIRA dependency:

  1. Open the pom.xml file.
  2. Scroll to the bottom of the file.
  3. Find for the <properties> element.
    This section lists the version of the JIRA version you selected in Step 1 and also the version of the atlas- commands you are running.
  4. Review the <jira.version> element.
    You can run this tutorial with JIRA version 4.3 or higher. If you chose to create a plugin for Shiny new JIRA 5 your <jira.version> element will have a version listed like this:

  5. Enter that version number in the <jira.version> element.

  6. Save the pom.xml file

Step 4. Update Your Project and Refresh Your IDE

If you change your Atlassian project, Eclipse is not automatically aware of the changes. Moreover, sometimes your project dependencies require an update. We need to fix that.

  1. Switch to a terminal window.
  2. Change directory to the project root.
    This is the directory with the pom.xml file.
  3. Update the on-disk project metadata with the new POM information.

    atlas-mvn eclipse:eclipse
    
  4. Back in Eclipse, refresh the plugin project to pickup the changes.

Remember to do this update and refresh step each time you edit your pom.xml or otherwise modify your plugin source with an Atlassian command.

Step 5. Test the Base Plugin in JIRA

At this point, you haven't actually written any Java code. You can however run JIRA and see the base plugin in action. In this step, you will start JIRA, create a project you'll use later, and test the servlet.

  1. Open a terminal window and navigate to the plugin root folder (where the pom.xml file is).
  2. Run the following command:

    atlas-run
    

    This command builds your plugin code, starts a JIRA instance, and installs your plugin in it. This may take several seconds or so, when the process completes you see many status lines on your screen concluding with something like the following lines:

    [INFO] jira started successfully in 71s at http://localhost:2990/jira
    [INFO] Type CTRL-D to shutdown gracefully
    [INFO] Type CTRL-C to exit
    
  3. Open your browser and navigate to the local JIRA instance started by atlas-run.
    If you followed the instructions, enter http://localhost:2990/jira in your browser.
  4. At the JIRA login, enter a username of admin and a password of admin.
    The integration steps you ran earlier created a project called TEST in your JIRA instance. You should have an existing issue called TEST-1 in the Recent Issues category.
  5. Display the TEST-1 issue.
    Between the Edit and Assign button you should see the Schedule button. This is button that launches the plugin.
  6. Experiment with the issue creation and notice how the button and the resulting dialog behave.

Now, we're ready to start writing some code!

Step 6. Creating the Simplest of Dialogs

JIRA develop has a feature that allows you to simply add a class to a link in HTML to open the contents of the target page in a dialog. Start Eclipse and do the following:

  1. Edit the atlassian-plugin.xml file.
  2. Locate the <web-item> with a key value of schedule-web-item.
  3. Add the following styleClasselement as a child element.

    When you are done, the <web-itemappears as follows:

  4. Save your changes.
  5. Return to a terminal window and navigate to the plugin directory.
  6. Enter atlas-debug at the prompt.
    Starting in the debug mode will allow you to use the Fastdev technique.
  7. Open your JIRA test instance in a browser and log in.
  8. Open an existing issue (you should have at least one).
  9. Test the Schedule button's behavior.
    Pressing the button will result in a Schedule dialog. When you press the Schedule button on this dialog it submits the dialog contents to the system. What happens to the UI when you press this Schedulebutton.

    "Not seeing the Schedule Button?"

    Icon

    Ensure the following:

    • There are issues in the system
    • There are versions in the project you issue is in
    • You have permission to edit the issue

Leave the JIRA server process running and the interface in an active browser. From here on out, we'll use the Fastdev approach to test our code changes.

Step 7. Cleaning Up the Submit Action

In the previous step, you saw that submitting the form caused the interface to look jumbled. We need to make the server tell the dialog that it can close. There is a convenience method in Webwork Actions that allow you to do this.

  1. Open Eclipse.
  2. Locate the SchedulerWebworkModuleAction.java file and open it for editing.
  3. Change the doExecute()method in the class so that it looks returns the following:

    If you are following the tutorial, you should still have JIRA up and and running.

  4. Go to the browser page and a hard refresh of the page. To do this, you can:
    • Shift+Reload in most browsers.
    • Ctrl+Reload on Windows or in Internet Explorer.
    • In Safari 5, you will need to hold down the Shift key while clicking the Reload icon in the Location bar.
      Reloading the plugin should have it working correctly with the view issue page reloading after the dialog closes.

Step 8. Learn What is Happening Behind the Scenes

This section discusses what happens behind on the scenes on the browser and the server.

In the Browser

On page load, the plugin overrides the link's click behavior. We specified this when we added the <styleClass>trigger-dialog</styleClass>. Instead of following the link, it loads the target page via Ajax and puts the contents in a dialog. We add some URL parameters to the links target to allow the server to know the contents are being rendered in a dialog and they can customize the content,
The URL parameters are:

inline=true

Specifies the content will open in a dialog.

decorator=dialog

Ensures the content uses the dialog Sitemesh decorator instead of it's usual one.

The result of any form submision or the target of any links is put into this dialog until the server returns a special response header: X-Atlassian-Dialog-Control:DONE. Any response header that contains this will close the dialog and refresh the underlying page.

On the Server

The returnComplete(url) checks to see if the content is displayed in a dialog. If it is, the systems adds the header and return an empty response. If it is not, it will behave as normal.

You can also redirect to another page when dialog is finished. To do this, instead of closing the dialog and refreshing the current page, you can redirect to another page when the dialog closes. To do this, return X-Atlassian-Dialog-Control:redirect:<url-to-redirect-to> instead of X-Atlassian-Dialog-Control:DONE.

To do this in a Webwork Action, you would edit the SchedulerWebworkModuleAction class to use returnCompleteWithInlineRedirect(<url-to-redirect-to>) instead of calling returnComplete(...).

Limitations of the Simplest Dialog

The following are the limitations when using the simplest dialog:

  • Doesn't work on links added dynamically.
    For example, when you open the available issue operations from the Issue Navigator, the Schedule operation will be there, but it wont open in a dialog. The reason for this is that we only bind the the link on page load - this should be improved to work with all links in the future.
  • Can't customize behavior on dialog close.

Step 9. Creating a Standard Dialog

For our dialog to work every time, we will need to create a specialized version of a dialog.
In this section, we add some JavaScript onto the page that will instantiate the form and bind it to the link. Additionally, we'll use the plugin module generator, part of the Atlassian Plugin SDK, to generate the stub for our web-resource.

  1. Open a command window and go to the plugin root folder (where the pom.xml is located).
  2. Run atlas-create-jira-plugin-module.
  3. Supply the following information as prompted:

    Choose Plugin Module:

    Web Resource

    Enter Plugin Module Name:

    My Web Resource

    Enter Resource Name:

    scheduler.js

    Enter Resource Type:

    download

    Enter Location:

    javascript/scheduler.js

    Add Resource Parameter?:

    Y

    param name:

    content-type

    param value:

    text/javascript

    Add Resource Parameter?:

    N

    Add Resource:

    N

    Show Advanced Setup?:

    N

    Add Another Plugin Module?:

    N

    This will have modified your atlassian-plugin.xml file to include a Web Resource.

  4. In Eclipse, create a folder called javascript in src/main/resources.
  5. Add a scheduler.js file in your new javascript folder.
  6. Edit scheduler.jsand add the following form:

  7. Save the file.
  8. Edit the atlassian-plugin.xml file.
  9. Change the styleClass element value from trigger-dialog to issueaction-schedule-issueas follows:

  10. Add a context element to the new web-resource element (to allow the new dialog to be visible from all non-administrative pages) as follows:

  11. Save the file.
  12. In eclipse, locate the SchedulerWebworkModuleAction.java file again and open it for editing.
  13. Add a requireResource() call in the includeResources()method to register the new scheduler resource:

  14. Save the file.

Step 10. Learn About the JavaScript and Test Again

Take a minute to examine the file in you examine the new a scheduler.js file you created in the last step. This code creates a form dialog by specifying the following:

JIRA.Dialogs.scheduleIssue

This is the dialog instance. Any dialogs that live in the namespace JIRA.DIALOGS automatically get bound to dynamic issue content.

new JIRA.FormDialog()

The standard form constructor this takes parameters to change it's behavior.

id

A unique DOM id for the dialog.

trigger

This is what the dialog is bound to. This is usually a jQuery selector.

ajaxOptions

Options that passed to the jQuery.ajax() method and used to retrieve content for the dialog. JIRA.Dialogs.getDefaultAjaxOptions are the defaults.

onSuccessfulSubmit

The function called after a form was submitted and come back successful.

JIRA.Dialogs.storeCurrentIssueIdOnSucessfulSubmit

Stores the current issue for later use in the message displayed on page refresh.

Test out your new code. Reload the plugin and this form should now work from not only the View Issue page, but also any of the cog menus (Dashboard, Issue Navigator, and the sub-task list). The image below shows the Schedule option in the Issue Navigator:

Step 11. Creating an Advanced Dialog

Ideally we would want avoid all page refreshes and refresh only the content that was updated. To do this we will override the default behavior of the form to write the new versions directly to the field.

  1. In Eclipse, edit scheduler.js.
  2. Remove the existing form code.
  3. Add the following form code:

  4. Save your work.

Step 12. Test the Final Version of the Dialog

Do the following to test the plugin:

  1. Switch to a terminal window.
  2. If JIRA is running, stop it.
  3. Change directory to the project root.
    This is the directory with the pom.xml file.
  4. Update the on-disk project metadata with the new POM information.

    atlas-mvn eclipse:eclipse
    
  5. Start JIRA by running atlas-debug.
  6. Login into JIRA and test the new, advanced Schedule dialog.

Congratulations

Icon

You should now have a fully working dialog.
Have a chocolate!

  • No labels

3 Comments

  1. Anonymous

    There is no "starting-point" branch. As of today, https://bitbucket.org/atlassian_tutorial/jira-scheduler-dialog-base/overview shows only one branch

    1. Good catch. If you clone the jira-schedular-dialog-base repo, no need to switch to the branch.

      There is a duplicative repo, https://bitbucket.org/atlassian_tutorial/tutorial-jira-scheduler, which does represent the "base" and "complete" versions of the tutorial code as two different branches. Will clarify.

  2. Anonymous

    This tutorial seems not to work with the current SDK (4.2.10). It always fails a step 1, point 4. Run a "$ atlas-integration-test".  Can someone confirm?