Krishnan Mahadevan
Krishnan Mahadevan

Reputation: 14746

Dealing with dynamic options for SelectList in Jira issue creation

In my Jira project I have a custom field called "CASE-Environment". Its a Select List(Multiple values)

I would like this custom field to have values dynamically populated. In my actual project, I am making use of RESTFul calls wherein I get the actual values from an internal RESTFul service. But for demo purposes I am showing the values here as hard coded via an initializer.

I am making use of the Script Runner Jira plugin which lets me define behaviors, associate it with fields. I have the following in the initializer section of the behavior.

import com.onresolve.jira.groovy.user.FieldBehaviours
import com.onresolve.jira.groovy.user.FormField

Map fieldOptions = [:]
fieldOptions.put("-1","None")
fieldOptions.put("100","Dev");
fieldOptions.put("101","Staging");
fieldOptions.put("102","QA");
fieldOptions.put("103","Production");

FormField env = getFieldByName("CASE-Environment");
env.setFieldOptions(fieldOptions)

I am successfully able to see this values on the UI when I am trying to create an issue.

But when I am trying to submit the issue, I hit a Jira validation error message which reads as below

Invalid value '102' passed for customfield 'CASE-Environment'

I am guessing that Jira somehow is not recognizing the dynamically added option values for my SelectList [ multiple values ]

I even tried building a mapping for this field wherein my behavior would get triggered everytime the custom field CASE-Environment under went changes.

The mapping code is shown as below :

import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.customfields.option.Option

import com.onresolve.jira.groovy.user.FieldBehaviours
import com.onresolve.jira.groovy.user.FormField


def adddOption = {
    Issue issue,
    CustomField customField,
    String value ->
        Options l = ComponentAccessor.getOptionsManager().getOptions(customField.getRelevantConfig(issue))
        int nextSequence = l.isEmpty() ? 1 : l.getRootOptions().size() + 1;
        Option newOption = ComponentAccessor.getOptionsManager().createOption(customField.getRelevantConfig(issue), null, (Long)nextSequence, value);
        return newOption;
}

FormField environment = getFieldById(fieldChanged)

Issue issue = getUnderlyingIssue()
MutableIssue mutableIssue = ComponentAccessor.getIssueManager().getIssueObject(issue.id);

CustomField field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("CASE-Environment")
List<Option> allOptions = new LinkedList<>();
List<String> chosenValues = (List<String>) mutableIssue.getCustomFieldValue(field);

for (String eachValue : chosenValues) {
    allOptions.add(adddOption(issue, field, eachValue));
}
mutableIssue.setCustomFieldValue(field, allOptions);

But even after this I still can't get past the error message. Can someone please help me with getting this sorted out ?

For what its worth, I am using Jira : JIRA v6.3.5

Upvotes: 2

Views: 5583

Answers (2)

Jaroslav Lhotak
Jaroslav Lhotak

Reputation: 11

Thanks @Krishan just one comment, new JIRA 7/ScriptRunner have problem with static type check. Replace the definition of "newSeqID"

def newSeqId = 0

with

Long newSeqId = 0

Upvotes: 1

Krishnan Mahadevan
Krishnan Mahadevan

Reputation: 14746

So after toying around for quite sometime on this, I finally managed to crack this on my own.

The below mentioned initializer section should help get this sorted out easily.

import com.atlassian.jira.component.ComponentAccessor

def optionsManager = ComponentAccessor.getOptionsManager()
def fieldManager = ComponentAccessor.getCustomFieldManager()
def envFld = fieldManager.getCustomFieldObjectByName("CASE-Environment")
def fieldConfig = envFld.getRelevantConfig(getIssueContext())
def newSeqId = 0
//For the sake of e.g., I am using a initialized array. In real life one can
// construct this by querying a DB or hitting a RestFul service etc.,
def envs = ["QA", "Staging", "Dev", "Production"]
def issueService = ComponentAccessor.getIssueService()
def issueInputParameters = issueService.newIssueInputParameters()
for (String env : envs) {
    def option = optionsManager.createOption(fieldConfig, null, newSeqId++, env)
    issueInputParameters.addCustomFieldValue(envFld.idAsLong, option.optionId.toString())
}

Upvotes: 1

Related Questions