Behaviours
Description
The behaviours functionality allows an administrator to create one more or behaviours. A behaviour defines how fields behave for issues in a given project or issue context. Some examples of behaviours are:
-
Making a field mandatory depending on other data entered on the issue screen (i.e during an issue creation or an issue transition)
-
Making a field read-only dependent on user role or group
-
Doing server-side validation of field data, before the issue screen is submitted
-
Setting a field value dependent on other issue screen data
Once you’ve created the behaviour, apply it to a test project so you can test it works as expected. Then apply it to a real project.
Examples
Setting a default Description
This simple example can be used as a tutorial. Further worked examples can be found in the Recipes section - Behaviours Examples.
To create a new Behaviour. Go the Administration sceen, and click the Behaviours link in the Behaviours section, or press gg
or .
and type Behaviours.

Click on Fields:

Click the Create Initialiser link:

Enter the following in the Script section (leave the first two fields blank):
def desc = getFieldById("description")
def defaultValue = """h2. How to reproduce
* step 1
* step 2
h2. Expected Result
The widget should appear
h2. Actual Result
The widget doesn't appear""".replaceAll(/ /, '')
if (! underlyingIssue.description) { (1)
desc.setFormValue(defaultValue)
}
1 | don’t overwrite the description if it already exists |
Then click on the Update
button.
Now click the Add One now
link to map this behaviour to a project:

Select one or more projects, then click Add Mapping:

This is a very simple configuration and should be used to check everything is working.
Create a new issue in the project that you have associated with this behaviour. You should see the default description. (If it doesn’t, see trouble-shooting below).

Using a server-side validator to set the Fix Versions required
A common scenario is that, when you mark an issue as resolved with the resolution of Fixed, you want the developer to specify the Fix Version. However, it doesn’t make sense to require a fix version when the resolution is Won’t Fix.
We solve that by using a server-side validator to mark the fix versions field as required, but only when the resolution is Fixed.
Create a new behaviour, or edit your current sample one. Click Add Field, and add the Resolution field.
Our server-side script, when written, will be called the first time this field appears, and any time the user changes it in the dialog.

Now click Add serverside script as we did previously. The script to enter is:
import com.atlassian.jira.issue.resolution.Resolution
def resolutionField = getFieldById("resolution")
def fixVersionsField = getFieldById("fixVersions")
def resolution = resolutionField.getValue() as Resolution
if (resolution.name == "Fixed") {
fixVersionsField.setRequired(true)
fixVersionsField.setHidden(false)
}
else {
fixVersionsField.setRequired(false)
fixVersionsField.setHidden(true)
}
This example sets the fix versions field to required and shown if the resolution is Fixed, and to optional and hidden if the resolution is anything else.
Now, Resolve an issue. Experiment with changing the resolution value. The fix versions field should change accordingly:

A good experiment now would be to modify the script so that instead of hiding the field it’s made read-only. To do, change setHidden
to setReadOnly
.
If you have created a new behaviour do not forget to map it to a project, or project/issue type combination. |
You might want to do something similar whereby if the Duplicate resolution is selected, the Linked Issues field is shown, if there not already a duplicate link for that issue |
Live Editing
Using an inline script can be painful as you have to keep clicking buttons and saving. It’s more productive to point to a file, then you can just modify that. It will be reloaded automatically.

Note that if you have a groovy script as opposed to a class, as in the previous examples, the method name should be run
.
When configured like this you can modify your code without even leaving the Resolve Issue dialog, let alone doing a page refresh.
The path to the script can be relative to a script root. |
Tip for IDE users
If using an IDE you can get code completion by adding the following lines at the beginning of your script:
|
Hidden Fields
Hidden fields are fields that can be hidden from the REST API and various other methods of retrieving them… usage of hidden fields is in beta. Let me know your experiences. A field will only be truly hidden if the behaviour marks it as hidden, and it’s of a hideable type. It’s best to avoid these, and hide fields just for the purpose of focusing end-users attention on the fields that they are interested in, and removing irrelevant fields.
Fields that are marked as hidden will be hidden when the record is viewed, in the issue navigator, and elsewhere. (See below for caveats). To get this behaviour though the field type must be one of the types provided by the plugin, currently only Hideable Free Text Field (unlimited text) and Hideable Text Field (< 255 characters). If you need any other let me know.
As far as I know, this is secure when used properly. However, there is one way where it is possible to get information from a hidden field. If a user suspects that a field has a particular string, and they construct a filter having that parameter, the issue will be returned. Although they won’t see the value, it would confirm that the issue did indeed have that value in its hidden field. If this is a concern set the Searcher to None.
The Change Log value for hidden fields are disabled for hidden fields, for all users.
Converting Normal to Hidden Fields
If you have existing fields that you want to make hideable you can convert the type following the Changing Custom Field Types procedure, using the new keys below.
CF Type |
Default Type Key |
Hideable Type Key |
New Searcher Key |
Short Text |
com.atlassian.jira.plugin.system.customfieldtypes:textfield |
com.onresolve.jira.plugin.Behaviours:hideable-textfield |
com.onresolve.jira.plugin.Behaviours:hideable-textsearcher |
Unlimited Text |
com.atlassian.jira.plugin.system.customfieldtypes:textarea |
com.onresolve.jira.plugin.Behaviours:hideable-textarea |
com.onresolve.jira.plugin.Behaviours:hideable-textsearcher |
It is not actually necessary to reindex as the searcher class is the same (although the key is different).
Example - Setting up a Hidden Field
Create (or convert) a new field of type Hideable Text Field (< 255 characters).
Create a behaviour as in the other examples. Add the above field and then set it to be hidden. Now add an exception to this, and choose project role developers. Apply the behaviour to the project. You should see something like this:

The field will now be hidden for any user who is not in the developers project role of the current project.
It may be helpful to use the JIRA SU plugin when testing schemes based on user name/group/role.
Do not use Shown When type logic. You must use Hidden When or Hidden Except instead.
Troubleshooting
Nothing happens at all
Enable logging (see below) and check the logs.
Limitations
Javascript-based
This relies on client-side javascript. In most environments users are free to disable javascript in their browser, so no good if security is critical. However, my use case is generally to prompt the user that they should be entering another field depending on some condition, so it’s generally good enough for me - no worse off than if you didn’t use this anyway.. If you’ve made a field read-only, you can always look at the history to see if your rules have been subverted.
However, one of the intentions of this plugin is to provide a more structured way for customisation than enter javascript in a field description, so you’re no worse off than if you had used that method.
Bulk Edit
No support for bulk edits, at the moment. This could be added, however, all issues part of the bulk edit would need to have the same behaviour associated for it to be doable.
Latency
The field behaviours are retrieved from the server after the form has loaded in the browser. In my environment this takes approximately 80 ms so is not noticeable by humans. Over the public internet this may be a lot worse, and so the delay in the styling being applied may be appreciable for the users.
Remote API
Due to limitation 1, i.e. JavaScript based, the behaviours are not enforced when using the remote API.
Getting help
If you have any problems, please include in your bug report:
-
server logs. You can switch these on by using the enable logging link from the Behaviours Admin screen.

To do so permanently, include these lines in your log4j.properties file:
log4j.category.com.onresolve.jira.groovy = DEBUG, console, filelog
log4j.additivity.com.onresolve.jira.groovy = false
-
For the problematic behaviour, click Edit, and include the XML snippet you see there.
-
Description of any custom field types involved, eg their type.