Custom Picker

Use a Custom Picker field to set up a field that allows users to pick values from a list. It is similar to the Database, LDAP, and Issue Picker script fields, but it is not specialized for any particular case.

For example, you can set up a custom picker to pick a Jira object such as a Version, User, or Component when you want custom selection criteria that are not available when using the native field types. Or you may want to utilize it when picking from a list that can be searched using a REST API.

At a minimum, you need to provide code for handling the following:

  1. Returning a list of objects when the user opens the drop-down, and when they type text for searching.
  2. Converting from the "object" to an option in the drop-down. This is where you select the object's unique ID that is stored in the Jira database.
  3. Given the ID that is stored, convert back to the "object".
  4. Rendering the "object".

The "object" in the above example differs depending on what type of structure this field represents. In the case of a version picker, it will be a com.atlassian.jira.project.version.Version. For a user, it should be a com.atlassian.jira.user.ApplicationUser etc. When picking from a rest resource, it will generally be a Map.

Example

Country Picker

In this example, users can select a country from a REST resource that provides geographical data.

We use https://restcountries.com/ as our example resource for this scenario.

Before starting the implementation of a REST resource picker, the following needs to be established:

  1. That we can search by name. For example, https://restcountries.com/v2/name/united.
  2. That we can get the first number of records for when the user opens the drop-down and does not type anything. In this case, we can use https://restcountries.com/v2/all
  3. That each object has a unique identifier, and that we can look up the object by this unique identifier. For example, countries have a unique 3-character ID, e.g. GBR, and we can get this country from the ID. For example, https://restcountries.com/v2/alpha/GBR to retrieve the United Kingdom. 

Once we have tested all the above in the browser, we can start coding. 

The following example can be accessed from the Snippets menu under the configuration script.

We recommend you start with one of the working examples and adjust it before implementing your own.

An error occured

There is a problem with the file path provided or a failure to connect with Bitbucket. Check the File Path provided, Application Link for Bitbucket Data Center or the permissions of the app password for Bitbucket Cloud. Contact your system administrator.


https://restcountries.com is not related to Adaptavist and we cannot guarantee its uptime. This example is just for instructive and testing purposes. In practice, it does not make sense to use this as a country picker, as ~200 countries could be handled by a Select List. Choosing from a REST resource is most useful when the number of selections is too large for a select list, or subject to change, or have multiple attributes that you might want to display.

Caching

Retrieving information from REST resources can be expensive. Each time the issue is viewed, the code making the REST request is called in order to get the item; hence it is advisable to cache responses.

As always, with caching, there is a balance between the cache size (limiting the memory consumed by the cached objects), the staleness of objects in the cache, and the cost of reloading new ones.

Because of all these variables, caching is left to the script author. In general, we recommend using either com.google.common.cache.CacheBuilder (Google Guava), or com.atlassian.cache.CacheManager, which is a wrapper over the Guava cache.

In the case of the country picker example above, we could set the size to around 250, as there are only ~200 countries in the world. Although it happens, it's not common for countries to be deleted or for them to change names, so we don't need to worry about expiring countries from the cache. 

Cache Loader Method

The example below is similar to the previous country picker example, except that fetching from the REST resource has been moved from getItemFromId into the cache loader method.

The other notable change is that, because Guava cache does not allow null keys or values, the actual value is wrapped in an Optional. This avoids failures if a country has been deleted. Using the web UI, it is not possible for a user to enter a country code that does not exist; however, they could do it using Jira's REST API.

In this case, it would make sense to cache all the countries and search in memory; however, in most cases, it's not practical to load all possible options.

An error occured

There is a problem with the file path provided or a failure to connect with Bitbucket. Check the File Path provided, Application Link for Bitbucket Data Center or the permissions of the app password for Bitbucket Cloud. Contact your system administrator.

Disabled vs. Non-Existent

Some thought must be given to what constitutes a valid selection in a custom picker.

In this user picker example, we only want to allow users who are members of either of the jira-administrators or  jira-system-administrators groups.

If an administrator is selected in the picker, and then at a later date removed from the administrator group, that option is disabled in the picker list. This should make that option "disabled." In this case, the issue can be edited with this disabled value without errors, but new issues cannot be created with this disabled value.

In the case of a selected user being "deleted," getItemFromId should return null

The following example introduces a final closure validate. This checks the "object" matches the required selection criteria.

Note that search should only return items that are valid. In this case, we use UserSearchService to filter on only users in those groups. 

An error occured

There is a problem with the file path provided or a failure to connect with Bitbucket. Check the File Path provided, Application Link for Bitbucket Data Center or the permissions of the app password for Bitbucket Cloud. Contact your system administrator.

Further Examples

The following additional examples are available in the Snippets drop-down under the Configuration Script section.

Version Picker

This example allows users to pick a non-archived Jira version across projects. This a further example of using validate to ensure only the selection of a non-archived Version.

Additionally, we customize the display using a lozenge to show the Version Status:

GitHub Repository Picker

This uses the GitHub REST API to allow the selection of a repository in the Adaptavist organization. This is not a practical example due to the Rate Limiting on the GitHub API. Even when authenticated, you are only allowed a minimal number of calls to the search resource.

Customizing the Displayed Value

As with the Issue Picker, HTML can be provided for each selected item in a multi-picker. 

As well as renderItemViewHtmlrenderItemColumnViewHtml can be used to display an abbreviated value when used in the Issue Navigator, along with renderItemTextOnlyValue for the plain text value which is used in History Tab, email notifications and CSV exports.

For rendering multiple values in a table, use renderViewHtmlrenderColumnHtml, or renderTextOnlyValue, in which case a Collection of all selected items will be passed to the closure. renderItemViewHtml does not need to be implemented if using this approach.

For example, rendering multiple Versions in a table:

An error occured

There is a problem with the file path provided or a failure to connect with Bitbucket. Check the File Path provided, Application Link for Bitbucket Data Center or the permissions of the app password for Bitbucket Cloud. Contact your system administrator.

Definitions

The following script contains all closures with all possible parameters that you can use and other variables you can set.

Note that when an Issue is provided, this is a "live" issue - it reflects changes made in the form during editing. This allows you to change possible selection values based on issue attributes, or indeed the current user roles and groups etc.

An error occured

There is a problem with the file path provided or a failure to connect with Bitbucket. Check the File Path provided, Application Link for Bitbucket Data Center or the permissions of the app password for Bitbucket Cloud. Contact your system administrator.