Issue with solution to: how to restrict field values based on another field values selection

Dianne M Fry-Bolton January 28, 2021

I am hoping someone can help me understand what is happening and if there is anything that can be done to stop it.

I used this (https://community.atlassian.com/t5/Marketplace-Apps-Integrations/how-to-restrict-field-values-based-on-another-field-values/qaq-p/1094323) question to find the solution to restrict field values based on another field values selection. 

I want the CM Deployment Type to vary depending on the CM Classification selected.  The solution provided worked great when an issue is created.  However, if the user needs to edit the issue using the edit screen, the CM Deployment Type selection appears to change.  e.g., If I select CM Classification as Patch, I expect the values Standard and Hotfix for the CM Deployment Type which is what happens.  However, if Hotfix is selected and then the issue is edited, the CM Deployment Type changes (appears to change) to the first option in the list which is Standard.  The options are the ones I want, I just don't want the selection to change.  If the user doesn't notice the selection changed, they could inadvertently change the selection.

Does anyone know why the value appears to change?  And how to make it stop?

Jira v8.5.7, Scriptrunner 6.6.0

This is the script I am using and have it mapped to the CM Deployment Classification field.

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript

@BaseScript FieldBehaviours fieldBehaviours


// CM Deployment Classification
int classificationId = 13901 //test 14000 prd 13901
def classification = getFieldById("customfield_" + classificationId)
def classificationValue = classification.getValue()

// CM: Deployment Type
int deployTypeId = 15601 //test 16003 prd 15601
def deployType = getFieldById("customfield_" + deployTypeId)

def deployTypeOptionsManager = ComponentAccessor.getOptionsManager()
def deployTypeCustomField = ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_" + deployTypeId)
def deployTypeConfig = deployTypeCustomField.getRelevantConfig(getIssueContext())
def deployTypeOptions = deployTypeOptionsManager.getOptions(deployTypeConfig)

 


if (classificationValue == "Patch"){

def deployTypeMap = ["Standard","Hotfix"]
def deployTypeOptionsMap = deployTypeOptions.findAll {
it.value in deployTypeMap // list of options you want to show
}.collectEntries {
[
(it.optionId.toString()) : it.value
]
}
deployType.setFieldOptions(deployTypeOptionsMap)

}

else if (classificationValue == "Minor"){

def deployTypeMap = ["Standard"]
def deployTypeOptionsMap = deployTypeOptions.findAll {
it.value in deployTypeMap // list of options you want to show
}.collectEntries {
[
(it.optionId.toString()) : it.value
]
}
deployType.setFieldOptions(deployTypeOptionsMap)


}

else if (classificationValue == "Major"||classificationValue == "Major - Initial Production Deployment"){

def deployTypeMap = ["Standard"]
def deployTypeOptionsMap = deployTypeOptions.findAll {
it.value in deployTypeMap // list of options you want to show
}.collectEntries {
[
(it.optionId.toString()) : it.value
]
}
deployType.setFieldOptions(deployTypeOptionsMap)


}
else {
deployType.setFieldOptions(deployTypeOptions)

}

 

1 answer

0 votes
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 28, 2021

Hi

Let me see if I can repeat your challenge...

When editing, you want to be able to change the CM Class field and when it triggers the current value for CM Deploy to no longer be valid, this current value should still be visible in the field. 

Questions: Should the user be able to save the issue with the new CM Class while that non-valid CM Deploy is still selected? Or should the user be forced to make a new selection?

If you want to force a new value, depending on if you have some mechanism to make this required or not already, it could be as simple as including a ['':'None'] option in your map. This will force a blank selection when the value becomes invalid (instead of the first new valid option.

If you want to allow the old value to remain, then you must add that valid to the list of options.

Here is your script this second option. I took the liberty of simplifying it:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueImpl
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript

@BaseScript FieldBehaviours fieldBehaviours


// CM Deployment Classification
int classificationId = 13901 //test 14000 prd 13901
def classification = getFieldById("customfield_" + classificationId)
def classificationValue = classification.getValue()

// CM: Deployment Type
int deployTypeId = 15601 //test 16003 prd 15601
def deployType = getFieldById("customfield_" + deployTypeId)

def optionsManager = ComponentAccessor.optionsManager
def deployTypeCustomField = ComponentAccessor.customFieldManager.getCustomFieldObject("customfield_" + deployTypeId)
def deployTypeConfig = deployTypeCustomField.getRelevantConfig(getIssueContext())
def deployTypeOptions = optionsManager.getOptions(deployTypeConfig)

//left side is the classification value, right is the list of options allowed
def classDeployMap =[
Patch: ["Standard","Hotfix"],
Minor: ["Standard"],
Major: ["Standard"],
'Major - Initial Production Deployment':["Standard"]
]

def currentDeploy = deployType.value

if(callDeployMap[classificationValue]){
def validDeployList = classDeployMap[classificationValue]
if(currentDeploy && issueContext instanceof IssueImpl){
validDeployList = validDeploy + currentDeploy
}
def validDeployOptionsMap = deployTypeOptions.findAll{it.value in validDeploy}.collectEntries{ ["$it.optionId":it.value]}
deployType.setFieldOptions(validDeployOptionsMap)
} else {
deployType.setFieldOptions(deployTypeOptions)
}

 

For the option to include an empty/None entry try this line instead:

def validDeployOptionsMap = deployTypeOptions.findAll{it.value in validDeploy}.
inject(['':'None']){ map, option->
map[option.otionId as String] = option.value
map
}
Dianne M Fry-Bolton January 29, 2021

Thank you, Pete-Dave.  I appreciate your response. I don't think it is quite addressing what is happening.  I attached some screen shots to try to help explain the situation.

Steps

Create an issue, select Classification Patch and Deployment Type Hotfix.
Save issue.
Edit issue.  Classification still shows Patch and Deployment Type still shows Hotfix.
Within 2-3 seconds, the Deployment Type changes to Standard which happens to be the first option of the Deployment Type list I am specifying with the Behavior.

Since nothing is being changed, I am not sure why the Deployment Type is changing.  Hotfix is still in desired options so I expect it to stay with Hotfix unless Classification is changed.

 

1_CreateIssue.png2_EditIssue.png3_EditIssue_2-3Sec.png

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 29, 2021

Okay, a few questions ...

1) Do you have any code in the initializer server-side script?

2) Do you have any code in the server-side script for CM Deployment Type?

My guess is that when the fields are initially populated from the DB when the edit screen is opening, one of your scripts is firing and causing the deployment type available values to be limited to "Standard" only so that forces the field to be updated.

I've had similar situation.

The way I've worked around it is, when editing and exiting issue, to try to only react to real changes. I.e. if there is an underlying issue, only run the script if the current form value is different from the underlying issue

Something like:

if(issueContext instanceof IssueImpl){
if(formValue != underlyingIssue.getCustomFieldValue(customField).value){
//do the rest of the code to limit options in the other field
}
}

This has the limitation that if, while editing, you change the classification ... select a new deployment then change the classification back to what it used to be (what it still is in the db) then the script will not fire this second time.

All of this is because, when you open any screen other than the Create screen, the initializer server-side code runs once, but also, upon opening, each field server-side code runs as the form is getting populated by jira from db values.

Dianne M Fry-Bolton February 1, 2021

Thank you, again, Peter-Dave.  I do not have any initializer server-side script and to ensure there were no other server-side scripts for CM Deployment Type, I disabled all the other Behaviours for this Project and Issue Type.  I am still seeing the symptoms I listed above.

I haven't had a chance to try out the workaround you provided.  I will see if that will help my situation.

I appreciate all your time and comments.  i will let you know how things go.

Suggest an answer

Log in or Sign up to answer