Dynamic Forms

Use the Dynamic Forms feature to simplify the process of adding variables to your ScriptRunner Groovy scripts. Dynamic Forms allows you to create complex scripts with flexible variables that can be shared with multiple users, allowing one script to be used for various use cases.

Inline scripts are often copied and pasted, with minor changes made for different use cases. This approach requires maintenance for each usage of the script. Using Dynamic Forms, create flexible scripts with annotated variables that can be stored as files, reducing maintenance requirements while allowing for script customization.

What's best, Dynamic Forms are everywhere! You can use them on Listeners, Jobs, and just about everywhere you can write code.

Annotate your variables to have them appear as form fields when a user edits a script. These annotations allow variable values within a script to be changed easily by those with limited code familiarity.

Dynamic forms annotations are available anywhere you can enter code in ScriptRunner, including the  Script Console, Conditions, Validators, Post Functions, Behaviours, and many more.

For example, as a power user, you have created a script to delete issues within a project with a specific assignee. This script is used across multiple locations, varying by one variable (User) for each use case. Instead of hardcoding the  User  variable, you can now use a dynamic form annotation, meaning the user can be changed without needing to re-write the script. As well as being able to edit the script quickly, you can maintain the code in one centralized location. The dynamic form annotation shows the User variable as a form field:

Image showing example of dynamic forms

The above example uses the following code:

import com.atlassian.jira.user.ApplicationUser
import com.onresolve.scriptrunner.parameters.annotation.UserPicker

@UserPicker(label = "Assignee", description = "Issues with this assignee will be permanently deleted")
ApplicationUser user

// issues returned from that JQL will get deleted
final String searchQuery = "assignee = $user.name"
Issues.search(searchQuery).each { issue ->
    issue.delete()
}
Copy


The following dynamic form field types are available:

NameDescriptionTarget Type

User Picker

Field allowing user selection.

com.atlassian.jira.user.ApplicationUser

Field Picker

Field to select any system or custom field.

com.atlassian.jira.issue.fields.Field

Short Text

Field allowing a short text input.

String

NumberField allowing an integerInteger

Select List

Single-select list field.

String

Checkbox

A checkbox field.

Boolean

Project Picker

Field allowing project selection.

com.atlassian.jira.project.Project

Priority PickerField allowing priority selection.com.atlassian.jira.issue.priority.Priority
Issue Type PickerField allowing issue type selection.com.atlassian.jira.issue.issuetype.IssueType
Issue Link Type PickerField allowing issue link type selection.com.atlassian.jira.issue.link.IssueLinkType
Project Role PickerField allowing project role selection.com.atlassian.jira.security.roles.ProjectRole
Group PickerField allowing group selection.com.atlassian.crowd.embedded.api.Group
Saved Filter PickerField allowing saved filter selection.com.atlassian.jira.issue.search.SearchRequest
Issue Status PickerField allowing status selection.com.atlassian.jira.issue.status.Status

Don't see a field you want? Contact Adaptavist Support to raise a feature request.

Create a dynamic form

  1. Navigate to ScriptRunner.

  2. Select Console.

  3. Write your new script in the Script field, annotating the variables you want users to provide (see the Examples section below). Annotating variables allows them to be edited depending on requirements when running the script. These variables show as editable fields above the  Script Console, or the Script field in other places such as Jobs or Listeners.

Transforming an existing inline script

To enable sharing of annotated scripts, all inline scripts must be saved as files.

  1. Navigate to your existing inline script, and add in required annotations.

  2. Copy the script.

  3. Use the Script Editor to open your Scripts Root folder.

  4. Select the folder in which you want to save the script, and click the Create New File icon.

  5. Enter a file name in the Add New Groovy File/Add New Groovy Folder window.

  6. Click Add.

  7. Paste your inline script into the file, and click Save. This script is now available as a file and can be shared with multiple Jira users on the same instance.

Annotations

User picker

Add a user picker field into your script.

        import com.atlassian.jira.user.ApplicationUser
        import com.onresolve.scriptrunner.parameters.annotation.*
        
        @UserPicker(label = "User", description = "Select a user")
        ApplicationUser user
Copy

User multi-pickers are also supported.

        import com.atlassian.jira.user.ApplicationUser
        import com.onresolve.scriptrunner.parameters.annotation.*
        
        @UserPicker(label = "Users", description = "Select users", multiple = true)
        List<ApplicationUser> users
Copy

Field picker

Add a field picker into your script. The field picker lets you pick from any fields (system or custom).

        import com.atlassian.jira.issue.fields.Field
        import com.onresolve.scriptrunner.parameters.annotation.*
        
        @FieldPicker(label = "Field", description = "Select a field")
        Field field
Copy

Field multi-pickers are also supported.

        import com.atlassian.jira.issue.fields.Field
        import com.onresolve.scriptrunner.parameters.annotation.*
        
        @FieldPicker(label = "Fields", description = "Select fields", multiple = true)
        List<Field> fields
Copy

Short text

Add a short text field to a script.

        import com.onresolve.scriptrunner.parameters.annotation.*

        @ShortTextInput(label = "Summary", description = "Enter a short issue summary")
        String issueSummaryTextInput
Copy

Number

Add a number field to a script.

        import com.onresolve.scriptrunner.parameters.annotation.NumberInput
        
        @NumberInput(label = 'Number of Approvals', description = 'How many approvals should be required')
        Integer requiredApprovals
Copy

Select list

Add a single-select list with configurable options.

            import com.onresolve.scriptrunner.parameters.annotation.Select
            import com.onresolve.scriptrunner.parameters.annotation.meta.Option
            
            @Select(
                label = "Color",
                description = "Select color",
                placeholder = 'Just pick any color',
                options = [
                    @Option(label = "Green", value = "green"),
                    @Option(label = "Blue", value = "blue"),
                ]
            ) 
            String value
Copy

Multi-select lists are also supported.

            import com.onresolve.scriptrunner.parameters.annotation.Select
            import com.onresolve.scriptrunner.parameters.annotation.meta.Option
            
            @Select(
                label = "Colors",
                description = "Select colors", 
                options = [
                    @Option(label = "Green", value = "green"),
                    @Option(label = "Blue", value = "blue"),
                    @Option(label = "Red", value = "red"),
                ],
                multiple = true
            ) 
            List<String> values
Copy

Checkbox

Add a checkbox to a script.

        import com.onresolve.scriptrunner.parameters.annotation.*
        
        @Checkbox(label = "Clone project", description = "Select the checkbox to clone project")
        Boolean projectShouldBeCloned
Copy

Project picker

Add a project picker to a script.

        import com.atlassian.jira.project.Project
        import com.onresolve.scriptrunner.parameters.annotation.ProjectPicker
        
        @ProjectPicker(
            label = 'Project', description = 'Pick a project', placeholder = 'Pick a project', includeArchived = false
        )
        Project project
Copy

Project multi-pickers are also supported.

        import com.atlassian.jira.project.Project
        import com.onresolve.scriptrunner.parameters.annotation.ProjectPicker
        
        @ProjectPicker(
            label = 'Projects', description = 'Pick projects', placeholder = 'Pick projects', includeArchived = false,
            multiple = true
        )
        List<Project> projects
Copy

Priority picker

Add a priority picker to a script.

        import com.atlassian.jira.issue.priority.Priority
        import com.onresolve.scriptrunner.parameters.annotation.PriorityPicker
            
        @PriorityPicker(label = 'Priority', description = 'Pick a priority', placeholder = 'Pick a priority')
        Priority priority
Copy

Priority multi-pickers are also supported.

        import com.atlassian.jira.issue.priority.Priority
        import com.onresolve.scriptrunner.parameters.annotation.PriorityPicker
            
        @PriorityPicker(
            label = 'Priorities', description = 'Pick priorities', placeholder = 'Pick priorities', multiple = true
        )
        List<Priority> priorities
Copy

Issue type picker

Add an issue type picker to a script.

        import com.atlassian.jira.issue.issuetype.IssueType
        import com.onresolve.scriptrunner.parameters.annotation.IssueTypePicker
        
        @IssueTypePicker(label = 'Issue type', description = 'Pick an issue type', placeholder = 'Select issue type')
        IssueType issueType
Copy

Issue type multi-pickers are also supported.

        import com.atlassian.jira.issue.issuetype.IssueType
        import com.onresolve.scriptrunner.parameters.annotation.IssueTypePicker
        
        @IssueTypePicker(
            label = 'Issue type', description = 'Pick issue types', placeholder = 'Select issue types',
            multiple = true
        )
        List<IssueType> issueTypes
Copy

Issue link type picker

Add an issue link type picker to a script.

        import com.atlassian.jira.issue.link.IssueLinkType
        import com.onresolve.scriptrunner.parameters.annotation.IssueLinkTypePicker
        
        @IssueLinkTypePicker(label = 'Issue link type', description = 'Pick an issue link type', placeholder = 'Pick an issue link type')
        IssueLinkType issueLinkType 
Copy

Issue link type multi-pickers are also supported.

        import com.atlassian.jira.issue.link.IssueLinkType
        import com.onresolve.scriptrunner.parameters.annotation.IssueLinkTypePicker
        
        @IssueLinkTypePicker(
            label = 'Issue link types', description = 'Pick issue link types', placeholder = 'Pick issue link types',
            multiple = true
        )
        List<IssueLinkType> issueLinkTypes 
Copy

Project role picker

Add a project role picker to a script.

        import com.atlassian.jira.security.roles.ProjectRole
        import com.onresolve.scriptrunner.parameters.annotation.ProjectRolePicker
        
        @ProjectRolePicker(label = 'Project role', description = 'Project role picker')
        ProjectRole projectRole
Copy

Project role multi pickers are also supported.

        import com.atlassian.jira.security.roles.ProjectRole
        import com.onresolve.scriptrunner.parameters.annotation.ProjectRolePicker
        
        @ProjectRolePicker(label = 'Project roles', description = 'Project role picker', multiple = true)
        List<ProjectRole> projectRoles
Copy

Group picker

Add a group Picker to a script.

        import com.atlassian.crowd.embedded.api.Group
        import com.onresolve.scriptrunner.parameters.annotation.GroupPicker
            
        @GroupPicker(label = 'Group', description = 'Pick a group', placeholder = 'Pick a group')
        Group group
Copy

Group multi-pickers are also supported.

        import com.atlassian.crowd.embedded.api.Group
        import com.onresolve.scriptrunner.parameters.annotation.GroupPicker
            
        @GroupPicker(label = 'Groups', description = 'Pick groups', placeholder = 'Pick groups', multiple = true)
        List<Group> groups
Copy

Saved filter picker

Add a saved filter to a script.

        import com.atlassian.jira.issue.search.SearchRequest
        import com.onresolve.scriptrunner.parameters.annotation.SavedFilterPicker
        
        @SavedFilterPicker(label = "Saved Filter", description = "Pick a saved filter", placeholder = "Pick a saved filter")
        SearchRequest searchRequest
Copy

Saved filter multi-pickers are also supported.

        import com.atlassian.jira.issue.search.SearchRequest
        import com.onresolve.scriptrunner.parameters.annotation.SavedFilterPicker
        
        @SavedFilterPicker(
            label = "Saved Filters", description = "Pick saved filters", placeholder = "Pick saved filters",
            multiple = true
        )
        List<SearchRequest> searchRequests
Copy

Issue status picker

Add a status to a script.

        import com.atlassian.jira.issue.status.Status
        import com.onresolve.scriptrunner.parameters.annotation.IssueStatusPicker
        
        @IssueStatusPicker(label = 'Status', description = 'Pick a status', placeholder = 'Pick a status')
        Status status
Copy

Issue status multi pickers are also supported.

        import com.atlassian.jira.issue.status.Status
        import com.onresolve.scriptrunner.parameters.annotation.IssueStatusPicker
        
        @IssueStatusPicker(
            label = 'Statuses', description = 'Pick statuses', placeholder = 'Pick statuses', multiple = true
        )
        List<Status> statuses
Copy

Custom field picker

Add a custom field picker to a script.

        import com.atlassian.jira.issue.fields.CustomField
        import com.onresolve.scriptrunner.parameters.annotation.CustomFieldPicker
        
        @CustomFieldPicker(label = 'Custom Field', description = 'Pick a custom field', placeholder='Select custom field')
        CustomField customField
Copy

Custom field multi-pickers are also supported.

        import com.atlassian.jira.issue.fields.CustomField
        import com.onresolve.scriptrunner.parameters.annotation.CustomFieldPicker
        
        @CustomFieldPicker(
            label = 'Custom Fields', description = 'Pick custom fields', placeholder='Select custom fields',
            multiple = true
        )
        List<CustomField> customFields
Copy

Resolution picker

Add a resolution to a script.

        import com.atlassian.jira.issue.resolution.Resolution
        import com.onresolve.scriptrunner.parameters.annotation.ResolutionPicker
            
        @ResolutionPicker(label = 'Resolution', description = 'Pick a resolution', placeholder = 'Pick a resolution')
        Resolution resolution
Copy

Resolution multi-pickers are also supported.

        import com.atlassian.jira.issue.resolution.Resolution
        import com.onresolve.scriptrunner.parameters.annotation.ResolutionPicker
            
        @ResolutionPicker(
            label = 'Resolutions', description = 'Pick resolutions', placeholder = 'Pick resolutions',
            multiple = true
        )
        List<Resolution> resolutions
Copy

Version picker

Add a version to a script.

        import com.atlassian.jira.project.version.Version
        import com.onresolve.scriptrunner.parameters.annotation.VersionPicker
        
        @VersionPicker(
            label = 'Version', description = 'Pick a version', 
            projectPlaceholder = 'Pick a project', placeholder = 'Pick a version'
        )
        Version version
Copy

Version multi-pickers are also supported.

        import com.atlassian.jira.project.version.Version
        import com.onresolve.scriptrunner.parameters.annotation.VersionPicker
        
        @VersionPicker(
            label = 'Versions', description = 'Pick versions', 
            projectPlaceholder = 'Pick a project', placeholder = 'Pick versions', multiple = true
        )
        List<Version> versions
Copy

Component picker

Add a component to a script.

        import com.atlassian.jira.bc.project.component.ProjectComponent
        import com.onresolve.scriptrunner.parameters.annotation.ComponentPicker
        
        @ComponentPicker(
            label = 'Component', description = 'Pick a component', 
            projectPlaceholder = 'Pick a project', placeholder = 'Pick a component'
        )
        ProjectComponent component
Copy

Component multi-pickers are also supported.

        import com.atlassian.jira.bc.project.component.ProjectComponent
        import com.onresolve.scriptrunner.parameters.annotation.ComponentPicker
        
        @ComponentPicker(
            label = 'Components', description = 'Pick components', 
            projectPlaceholder = 'Pick a project', placeholder = 'Pick components', multiple = true
        )
        List<ProjectComponent> components
Copy

On this page