If possible you should use those, as they allow better options for validation, rendering, and so on.
Where there is a better feature to accomplish the same, that will be displayed in the text below.
Write a behaviour that converts a text field to a select or a multi-select field, on initialization of the form.
You can also specify the available options for the field, including a picker function that performs as-you-type searching.
Allow the Jira user to select any GitHub or Bitbucket repository.
Require a link to another Jira issue where they can only pick from a constrained list.
Require a link to a remote Jira issue, for instance, constraining the remote issue to just those of a Support Request type.
Pick from a list of customers, where the customer information comes from a CRM database or REST service.
Pick from a list of Confluence spaces.
We use a behaviour for list conversion as there are millions of repositories in GitHub/Bitbucket. Importing all of the item as options into Jira for regular or multi-select lists is impractical.
If you have a manageable list of options, and you can synchronize them with your select field options, this gives you a couple of additional advantages:
The ability to rename options.
The ability to disable options.
Walkthrough - Pick from Jira Issues
Link a text field to display a searchable list of issues that come from a JQL query. For example, you want to enforce the association of an end-user Incident issue type with a Root Cause issue type.
You are advised to use an Issue Picker field rather than this method.
The information below preceded the release of Issue Picker fields.
The first step is to validate that your JQL query works, e.g.:
issuetype = 'Root Cause' and resolution is emptyGROOVY
Next, create a behaviour, and add an initializer function containing something similar to the following:
Line 1: Convert a custom field called TextFieldA. This can be any short text field, even the Summary.
Line 8: Specify the JQL query - customize to suit.
Line 9: Label that appears at the top of the dropdown.
Line 10: Set to
trueto also return sub-tasks.
Line 15: When returning issues this must be
Line 17: Make the single select the same width as the multi-select.
The JQL query you provide is not validated, check it first. If it’s invalid, no issues are displayed.
Apply the behaviour to the project (and/or issue type) that you are testing with. The field to which you applied the issue picker should then look like:
You could use a post-function or listener to create this as an actual issue link.
Walkthrough - External REST Service
Create and Test Endpoint
This example deals with picking from a list that comes from an external provider, in this case GitHub.
The browser cannot make requests directly to the GitHub REST API due to anti-XSS measures, so we will write a REST endpoint that will effectively proxy the request on to GitHub. We will need to manipulate the request and response slightly.
Create a new REST endpoint, containing the following code:
Line 14: githubRepoQuery forms the final part of the REST URL
Line 24: Github API requires this header, the value is not important
Line 37: Highlight matched terms in a case-insensitive manner
We are not authenticating to the GitHub API so only public repositories will be found. You can add authentication details if you have private repositories. Note also that without authentication you are rate limited to 60 requests per hour.
- Then you need to test this API alone. In your browser, go to:
You should see a response containing the first 30 matching items, sorted by popularity. Scroll down and check the total and footer keys are also correct. You might notice that the html value of each item has <b> tags to highlight the word tetris.
Try changing tetris to another string.
If this is working properly, you can move on to hooking it up to a text field.
As in the previous example, create a behaviour and set the initializer code to:
Line 1: Concert a custom field called TextFieldB, this time to a multiselect
Line 3: The URL of the endpoint that we tested above
Line 5: Don't make any query until the user has typed four characters
Line 6: Wait 500ms after the user has stopped typing before looking for repos
Line 7: When showing arbitrary, non-issue data, this must be
Testing should produce something similar to:
Walkthrough - Choose from a Database Table
You are advised to use a Database Picker field rather than this method.
A database picker has much greater control over the rendering and validation etc.
The information below preceded the release of Database Picker fields.
In this example we’ll configure the picker to read from a database query. You would use this if you can get read-only access to the target database and there is no suitable REST API. For example, allowing the selection of a customer name where the customer list is in a CRM database.
The example worked through here reads the JiraEventType table from the current Jira. This is pointless, but is used because it’s something you will be able to test with, and is almost identical to querying any other database.
Configure a REST endpoint using the following code:
Line 29: Configure driver - see connecting to databases for more information
Line 33: The SQL statement which should use the provided search parameter. Note that ilike is specific to Postgres
Verify that it works by opening:
Connect it to a text field in your behaviour initializer:
Verify it works:
Walkthrough - Pick Issue from Remote Jira
This example demonstrates linking a remote Jira issue with the current issue, but where the remote issue must match a JQL query (performed on the remote instance).
You are advised to use a Remote Issue Picker field rather than this method.
The information below preceded the release of Remote Issue Picker fields.
You might use this if you have an internal Jira and a customer-facing Jira, and you want to enforce selecting a remote issue which has the same Customer as on the internal instance. For the walkthrough, we use Atlassian’s public-facing Jira instance, and restrict the remote issue list to issues affecting Bitbucket Server with the Enterprise component.
Set up a REST endpoint with the following code:
Line 16: Constraint query - optionally you could specify it in the
ajaxOptionscode for better reusability
Your Jira server must allow HTTP connections outwards… you may need to configure your httpProxy settings.
Verify this works by opening this URL in your browser:
- You should see the sub-list of issues from the JQL query that contain the word branch in the summary.
Configure your behaviour initializer to use this endpoint:
getFieldByName("TextFieldD").convertToMultiSelect([ ajaxOptions: [ url : getBaseUrl() + "/rest/scriptrunner/latest/custom/pickRemoteIssue", query: true, formatResponse: "issue" ] ])GROOVY
- Should result in something like:
This works because jira.atlassian.com allows anonymous querying. If you have an application link set up between the two instances you will be better off using that to execute the remote requests, as it will allow impersonation of the current user.
Pick Confluence Space
This example uses the Confluence remote API to search for a space.
You must have a working application link to Confluence for this to work.
Note that the searching uses the same logic as when you search in the Confluence space directory, and searches on space name, description and label. You need to type a complete word from any one of these to get the correct results.
REST endpoint code:
Behaviour initializer code:
Should result in something like:
Dynamically Changing the Picker Query
Advanced ScriptRunner skills required for this example.
In the first example we saw how you could turn a text field into a dropdown that allowed users to pick an issue from the results of a JQL query that we set once, in the initializer.
Great, but what if the validation query should be formed based on other inputs? That is to say, what if you needed the user to link to an issue from different JQL queries, depending on what other information was present on the form?
In this simple example we will work through, the form has a project-picker custom field, and a text field that will take the value of an issue the user selects. The JQL query needs to be of the form
project = <selectedProject> and ….
In our example, the project picker has the name
ProjectPicker, and the field that will be converted to an issue-picking single select has the name
To do this, we don’t use an initializer - instead we add an on change server-side script that will convert
TextFieldA to a single-select issue picker - the JQL query will be formed from the value of the ProjectPicker field.
Add code similar to this to the project picker field, or whatever are the inputs that should drive the JQL query:
Line 13: Build JQL query based on other field inputs
You may notice a problem… currently, the value of the issue picker is not cleared if it becomes invalid for the new JQL query. This may change in the future, but right now the best solution to this is to add an on change validator for the issue picker field. Alternatively, you could add a workflow validator if this is on a workflow function.
So, when the project picker is changed and it makes the selected issue invalid, you will see:
This is done by adding the following server-side script for the issue picker field, in our case called
Line 12: Build a query corresponding to that used for the picker
Line 13: Check the currently selected issue is found in that query