Dynamic Multi-Select Fields Based on Field Selection
This script automatically updates two multi-select fields (multiSelect1 and multiSelect2) based on the value selected in the singleSelect. It ensures that only relevant options appear in these fields and removes any previously selected values that are no longer valid.
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.customfields.manager.OptionsManager
def optionsManager = ComponentAccessor.getComponent(OptionsManager)
def cfManager = ComponentAccessor.getCustomFieldManager()
// -------------------- CUSTOM FIELDS --------------------
def multiSelectFirst = cfManager.getCustomFieldObject("customfield_10204") as CustomField // Submodule
def singleSelect = cfManager.getCustomFieldObject("customfield_10206") as CustomField // Module
def multiSelectSecond = cfManager.getCustomFieldObject("customfield_10205") as CustomField // Label
// -------------------- FORM FIELDS --------------------
def multiSelectFormFirst = getFieldById("customfield_10204")
def multiSelectFormSecond = getFieldById("customfield_10205")
def singleSelectForm = getFieldById("customfield_10206")
def singleSelectValue = singleSelectForm.getValue() as String
// -------------------- IF NO MODULE SELECTED --------------------
if (!singleSelectValue) {
multiSelectFormFirst.setFieldOptions([:])
multiSelectFormFirst.setFormValue(null)
multiSelectFormSecond.setFieldOptions([:])
multiSelectFormSecond.setFormValue(null)
return
}
// -------------------- OPTION SOURCES --------------------
def multiSelectFirstOptions = optionsManager.getOptions(multiSelectFirst.getRelevantConfig(issueContext))
def multiSelectSecondOptions = optionsManager.getOptions(multiSelectSecond.getRelevantConfig(issueContext))
// -------------------- SINGLE SELECT → MULTI SELECT FIRST --------------------
def singleSelectToMultiSelectFirst = [
"Underwriting": ["New Business","Renewal Business","Medical Declaration","Standard Products"],
"Sales": ["Customers","Distributors","Leads","Basic Applications","Enhanced Applications"],
"Networks Management": ["Online Requests","Healthcare Providers","Healthcare Groups","Healthcare Partners","Clinicians","Networks","Contracts","Trainings","Reference Lists"],
"Accounts": ["Accounts","Segments","Receivables","Payable","Finance Interface"],
"Policy Administration": ["Thiqa","Basic","Enhanced","ABM","Aounak","GHQ","LPC","IPC","Travel"],
"Website": ["Thiqa Website","Daman Website"],
"Mobile App": ["Thiqa Mobile App","Daman Mobile App"],
"Person": ["Commercial","Medical"]
]
// -------------------- SINGLE SELECT → MULTI SELECT SECOND --------------------
def singleSelectToMultiSelectSecond = [
"Underwriting": ["SME NB","LG NB","ISG NB","SME RN","LG RN","ISG RN"],
"Networks Management": ["Operations","Abudhabi - Contracting","DNE - Contracting","Key Accounts"],
"Master Data": ["Medical","Commercial"],
"Accounts": ["Provider Accounts","Payables","Receivables"],
"Person": ["Person"]
]
/* =====================================================
MULTI SELECT FIRST FILTER (VALUE → ID FIXED)
===================================================== */
def allowedMultiSelectFirstValues = singleSelectToMultiSelectFirst[singleSelectValue] ?: []
def filteredMultiSelectFirstOptions = multiSelectFirstOptions.findAll { allowedMultiSelectFirstValues.contains(it.value) }
Map<String,String> multiSelectFirstOptionMap =
filteredMultiSelectFirstOptions.collectEntries { [(it.optionId.toString()): it.value] }
multiSelectFormFirst.setFieldOptions(multiSelectFirstOptionMap)
// normalize current VALUE → ID
def currentMultiSelectFirstVal = multiSelectFormFirst.getValue()
List<String> currentMultiSelectFirstValues = currentMultiSelectFirstVal instanceof List
? currentMultiSelectFirstVal.collect { it.toString() }
: currentMultiSelectFirstVal ? [currentMultiSelectFirstVal.toString()] : []
Map<String,String> multiSelectFirstValueToId =
filteredMultiSelectFirstOptions.collectEntries { [(it.value): it.optionId.toString()] }
List<String> normalizedMultiSelectFirstIds =
currentMultiSelectFirstValues.collect { multiSelectFirstValueToId[it] }.findAll { it }
if (normalizedMultiSelectFirstIds != currentMultiSelectFirstValues) {
multiSelectFormFirst.setFormValue(normalizedMultiSelectFirstIds ?: null)
}
/* =====================================================
MULTI SELECT SECOND FILTER (VALUE → ID FIXED)
===================================================== */
def allowedMultiSelectSecondValues = singleSelectToMultiSelectSecond[singleSelectValue] ?: []
def filteredMultiSelectSecondOptions = multiSelectSecondOptions.findAll { allowedMultiSelectSecondValues.contains(it.value) }
Map<String,String> multiSelectSecondOptionMap =
filteredMultiSelectSecondOptions.collectEntries { [(it.optionId.toString()): it.value] }
multiSelectFormSecond.setFieldOptions(multiSelectSecondOptionMap)
// normalize current VALUE → ID
def currentMultiSelectSecondVal = multiSelectFormSecond.getValue()
List<String> currentMultiSelectSecondValues = currentMultiSelectSecondVal instanceof List
? currentMultiSelectSecondVal.collect { it.toString() }
: currentMultiSelectSecondVal ? [currentMultiSelectSecondVal.toString()] : []
Map<String,String> multiSelectSecondValueToId =
filteredMultiSelectSecondOptions.collectEntries { [(it.value): it.optionId.toString()] }
List<String> normalizedMultiSelectSecondIds =
currentMultiSelectSecondValues.collect { multiSelectSecondValueToId[it] }.findAll { it }
if (normalizedMultiSelectSecondIds != currentMultiSelectSecondValues) {
multiSelectFormSecond.setFormValue(normalizedMultiSelectSecondIds ?: null)
}