How to filter Module custom dropdown based on Component/s selection?

Lacey McDonnell October 28, 2016

We are using the JIRA Native component/s field for our components. We have a custom field called Module for the specific aspect of the component that needs attention.

We have over 100 custom modules in the entire list; only 4 or 5 at a time can apply to any one component.

Can we write a behavior to filter those 100+ values to show only those applicable to the selected component?
I took a peek at Default Values but am not savvy enough to figure it out on my own.

(Adaptavist declined to work on this issue due to staffing/time restrictions in relation to scripting queries and directed me to Atlassian Answers.)

3 answers

1 accepted

1 vote
Answer accepted
Thanos Batagiannis [Adaptavist]
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 11, 2016

Hi Lacey,

try something like the script below (assign it to Component fields)

def compForm = getFieldById(IssueFieldConstants.COMPONENTS)
def module = getFieldByName("Module")

def componentModuleMappings = [
    "Component B" : ["A", "B", "D"],
    "Component A" : ["A", "I", "L"],
    "Component C" : ["K", "M"],
]

def selectedComponents = compForm?.value as List

if (! selectedComponents) {
    // no components selected, do something
    compForm.clearError()
} else if (selectedComponents.size() > 1) {
    // more than one components selected, display an error message
    compForm.setError("Please select only one component")
} else if ( selectedComponents.size() == 1) {
    // exactly one component selected, set the available options for the module field
    compForm.clearError()

def selectedCompName = selectedComponents[0]?.name
log.debug "Selected Component : ${selectedCompName}"
def moduleOptionValues = componentModuleMappings.get(selectedCompName)
    def optionManager = ComponentAccessor.getOptionsManager()

    def moduleCFConfig = ComponentAccessor.
        getCustomFieldManager().
        getCustomFieldObjectByName("Module")?.
        getRelevantConfig(issueContext)

    def optionsForModule = optionManager.getOptions(moduleCFConfig).findAll { it.value in moduleOptionValues }
    module.setFieldOptions(optionsForModule)
}

Please let me know if this does the trick. If this does not work please let me know what kind of error you get in your logs and please let me know how you "changed the Component/s field to render as a single select"

regards, Thanos

Lacey McDonnell November 11, 2016

Well, I had removed from WEB-INF the "multiple" line but it looked stupid. So I restored the clause, restarted the instance, and now I have a global behavior instead to limit it to one choice:

def formComponent = getFieldById(getFieldChanged())
// if it's a list it has more than one value
if (formComponent.getFormValue().getClass().toString().contains('List')) {
    def List compos = []
    formComponent.getFormValue().each{obj->
        try{
            def objint = obj as int
                    compos.add(objint)
        }
        catch(e){}
         
    }
    if (compos.size() > 1){
    formComponent.with {
        setValid(false)
        String s = "Please select only one component."
        setTitle (s)
        setHelpText("<div class=\"warningBox\">$s</div>")
    }                      }
}
else {
    formComponent.with {
        setValid(true)
        setTitle ("")
        setHelpText("")
    }
}

 

Same thing for fix version only where you see "Component" it says "fixVersions"

As for MODULE:

This is closer than I got. At least it has an effect at all - unfortunately, that effect is to completely remove all values from Module smile 

It reads as an error on def selectedCompName = compForm?.value[0].name as List where it couldn't find a matching method java.lang.Object#getAt(int) ....

 

Lacey McDonnell November 11, 2016

The only line in the atlassian-JIRA log I see that is remotely related to my issue update attempt is:

 

2016-11-11 15:50:10,491 http-bio-8080-exec-2 WARN Lacey87143 950x28024x2 gk1jak 10.255.250.124 /secure/AjaxIssueAction!default.jspa 

Thanos Batagiannis [Adaptavist]
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 13, 2016

Ok, Lacey what I can propose to leave the components field as a multi-select list and display an error message if more than one component is selected (with a behaviour), 

I updated the script above. Hope that is better. 

 

Lacey McDonnell November 14, 2016

That script is what I had but applied to a separate Behavior called "Defaults" cheeky But now I see how to tie it into another rule! Thank you smile

Unfortunately, Module is still coming up blank, and it throws an error on "compForm?.value[0].name"

Thanos Batagiannis [Adaptavist]
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 14, 2016

Hi Lacey, 

The error you see is a static type checking error, ignore it. The Module will come blank if there is not the available Component - Module pair in the componentModuleMappings map. 

Just added a debug message on the script above, so enable logging and check your log files.

 

Lacey McDonnell November 14, 2016

That tipped me off - the spaces.

I had

" LOB - UK - Small Office ": [" Document ",     
    " Forms",     
    " Performance ",     
    " Premium Summary ",     
    " Rating ",     
    " Surcharges ",     
    "Tables ",     
    "Transactions ",     
    " UI "],

I took out the spaces and all is well

Have I told you lately that I love you????? :* THANK YOU

Thanos Batagiannis [Adaptavist]
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 14, 2016

Glad that helped to sort it out, and for your kind words.

0 votes
Lacey McDonnell October 9, 2020

@Thanos Batagiannis [Adaptavist]  Here's an updated version of your solution for recent Jira API

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueFieldConstants
import static com.atlassian.jira.issue.IssueFieldConstants.*
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;

def compForm = getFieldById(IssueFieldConstants.COMPONENTS)
def module = getFieldByName("Module")
def customField = customFieldManager.getCustomFieldObject(module.getFieldId())

def componentModuleMappings =
[

"Issue Data":
[
"Training",
"New Field"
],
"Projects":
[
"Training",
"Other"
]
]

def selectedComponents = compForm?.value as List

if (! selectedComponents) {
// none selected, do nothing
compForm.clearError()
}
else if (selectedComponents.size() >1) {
// more than one, throw an error
compForm.setError("To best service your request, please select only one Component. Each Component should have its own ticket. This helps us group similar incoming requests for review and approval.")
}
else if (selectedComponents.size() == 1) {
// exactly one selected, set available options for Modules field
compForm.clearError()

def selectedCompName = selectedComponents[0]?.name
log.debug "Selected Component : ${selectedCompName}"
def moduleOptionValues = componentModuleMappings.get(selectedCompName)
def optionManager = ComponentAccessor.getOptionsManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()

def moduleCFConfig = customField.getRelevantConfig(getIssueContext())

def optionsForModule = optionManager.getOptions(moduleCFConfig).findAll {it.value in moduleOptionValues}
module.setFieldOptions(optionsForModule)
}
0 votes
Lacey McDonnell November 9, 2016
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def optionsManager = ComponentAccessor.getOptionsManager()
def formModule = customFieldManager.getCustomFieldObject('Module')
def projectComponentManager = ComponentAccessor.getProjectComponentManager()
def components = projectComponentManager.findAllForProject(issueContext.projectObject.id)
def config = formModule.getRelevantConfig(getIssueContext())
def options = optionsManager.getOptions(config)
if (components == 'LOB - Classic CPP') return formModule = (options.findAll {it.value in 
['Document','Forms','Performance','Premium Summary','Rating','Surcharges','Tables','Transactions','UI']})
if (components == 'LOB - Commercial Package') return formModule = (options.findAll {it.value in 
['Document','Forms','Performance','Premium Summary','Rating','Surcharges','Tables','Transactions','UI']})

This says correct and it is definitely not working. @Thanos Batagiannis [Adaptavist] lol any ideas?

Thanos Batagiannis [Adaptavist]
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 10, 2016

Hi Lacey,

As far as I understand let's say you want when Comp A is selected the available for selection options for the Single Select Module Custom Field to be A, B, C and if the Comp B is selected then available options to be A, B.

But the components is a multi select therefore what options you expect the field Module to have when Comp A and Comp B are selected as components ?

Lacey McDonnell November 10, 2016

I changed the Compoent/s field to render as a single select smile 

Lacey McDonnell November 10, 2016

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField


def customFieldManager = ComponentAccessor.getCustomFieldManager()
def optionsManager = ComponentAccessor.getOptionsManager()
def formModule = customFieldManager.getCustomFieldObject('Module')
def projectComponentManager = ComponentAccessor.getProjectComponentManager()
def formComponent = getFieldById("components")
def config = formModule.getRelevantConfig(getIssueContext())
def options = optionsManager.getOptions(config)


Object componentFormValue = formComponent.getValue()

if (componentFormValue == 'LOB - Classic CPP')

formModule = (options.findAll {it.value in
['Document','Forms','Performance','Premium Summary','Rating','Surcharges','Tables','Transactions','UI']})


else if (componentFormValue == 'LOB - Commercial Package')

formModule = (options.findAll {it.value in
['Document','Forms','Performance','Premium Summary','Rating','Surcharges','Tables','Transactions','UI']})

 

 

still not working lol

Thanos Batagiannis [Adaptavist]
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 10, 2016

Another one question... So you want to fill the Module Select List with default options or to change the available options ? (something like a cascading select list where the right options depend on the left selected option)

Lacey McDonnell November 10, 2016

I want to change the available options like a cascading select.

(i.e. we have custom field MODULE values 1-100. if we select JIRA native field COMPONENT/S value A I want to Module dropdown to only show values 2,6,77,90), 

Vivek Lakshman
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
March 17, 2021

Hi @Thanos Batagiannis [Adaptavist] ,

You are deserving of even more love than Lacey gave you!

I love you too!

Suggest an answer

Log in or Sign up to answer