ScriptRunner showing a specific customfield's value(s) based on multiple other customfields

Michael
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.
May 19, 2023

Hello all,

I'm trying to figure out how to script a server side behavior using ScriptRunner which checks the values of multiple customfields to determine the values of a separate customfield.

What makes this difficult is that I will/may already have a behavior set for one or more of the customfields I'm trying to compare the values of in order to display the correct values within the separate field.

For example:

Within the "Create screen" I currently have 5 fields:

Client (Field #1 - single select customfield) {Client 1, Client 2, Client 3}

  • Currently has the following behaviors scripted within it:
    • (by default) The following fields are automatically hidden:
      • Brand, Request Type, Due Date, & Team fields
    • If Client 1 is Selected:
      • Un-hides Brand, Request Type, & Team fields
      • Only allows Brand 1 option to show in Brand field

    • If Client 2 is Selected:
      • Un-hides Brand, Request Type, & Due Date fields
      • Only allows Brand 1 & Brand 2 options to show in Brand field

    • If Client 3 is Selected:
      • Unhides Brand, Request Type, Team, & Due Date fields
      • Allows all options to show in Brand field (Brand 1, Brand 2, Brand 3)

Brand (Field #2 - multi-select customfield) {Brand 1, Brand 2, Brand 3}

  • Currently doesn't have any behavior scripts within it.

Request Type (Field #3 - single select customfield) {Request Type 1, Request Type 2, Request Type 3}

  • Currently doesn't have any behavior scripts within it.

Due Date (Field #4 - System field)

  • Currently doesn't have any behavior scripts within it.

Team (Field #5 - single select customfield) {Team 1, Team 2, Team 3}

  • Currently doesn't have any behavior scripts within it.

 

Main Goal:

Within the example above, I'd like to script a behavior within the Request Type field which checks the values selected within the Client and Brand field to provide specific values accordingly:

  • If Client 1 and Brand 1 are selected; Only show Request Type 1
  • If Client 2 and Brand 1 are selected; Only show Request Type 1 & 2
  • If Client 2 and Brand 2 are selected; Only show Request Type 2
  • If Client 3 and Brand 3 are selected; Only Show Request Type 1 & 3
  • If Client 3 and Brand 1 or 3 are selected; Only show Request Type 2

 

If there is anyone that can help, I'd greatly appreciate it!

~Mike

 

1 answer

1 accepted

1 vote
Answer accepted
Graham Twine
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.
May 19, 2023

Hello @Michael ,

If I am understanding you correctly then you want this behavior on the portal.

By request types do you do  not refer to request types?

 

Create a new Behaviour with the correct project and issue type mapping

The version of Scriptrunner you have installed is going to mean a bit here.

Select lists are Options implemented in Jira so there can be two things to consider, the id and the value.

One has no need to do anything in the 'Request Type' field it will be manipulated.

Only the fields doing the manipulation need custom behavior.

What happens if the form is changed?

i.e. I choose Client 1 from the Client field then Brand 2, then I change Client to Client n

 

Client (single select customfield)


def client = getFieldByName('Client').value
def brand =getFieldByName('Brand').value



//Keep existing logic for Brand

if(!client || !brand) return

def validRequestTypes = []

if(client == 'client1' && brand == 'brand1') {
validRequestType= ['Request Type1']

} else if (client == 'client2' && brand == 'brand1') {
validRequestTypes = ['Request Type1', 'Request Type2']

//One could use client in ['client1', 'client3']&& brand in ['b1','b2','b3']
// think about the relationship between client and brand value though
} else if ((client == 'client2' && brand == 'brand2')
|| client == 'client3' && (brand in ['brand1', 'brand3'])) {
validRequestTypes = ['Request Type2']

} else if (client == 'client3' && brand == 'brand3') {
validRequestTypes = ['Request Type1', 'Request Type2']
}

if(validRequestTypes.isEmpty()) {
// One could even set the field value here if it makes sense to do so
getFieldByName('RequestType')
.setFieldOption(validRequestTypes)
.setFormValue(-1)
}

 

Brand (multi select customfield)


def client = getFieldByName('Client').value
def brand =getFieldByName('Brand').value


if(!client || !brand) return

def validRequestTypes = []

if(client == 'client1' && brand == 'brand1') {
validRequestType= ['Request Type1']

} else if (client == 'client2' && brand == 'brand1') {
validRequestTypes = ['Request Type1', 'Request Type2']

//One could use client in ['client1', 'client3']&& brand in ['b1','b2','b3']
// think about the relationship between client and brand value though
} else if ((client == 'client2' && brand == 'brand2')
|| client == 'client3' && (brand in ['brand1', 'brand3'])) {
validRequestTypes = ['Request Type2']

} else if (client == 'client3' && brand == 'brand3') {
validRequestTypes = ['Request Type1', 'Request Type2']
}

if(validRequestTypes.isEmpty()) {
// One could even set the field value here if it makes sense to do so
getFieldByName('RequestType')
.setFieldOption(validRequestTypes)
.setFormValue(-1)
}

 

The above will  update the Options  available in the Request Type.

Whenever the options are updated clear out the existing value as it may no longer be correct. One  could also check the existing value is in the permissible values and just leave it.

Please note that above is not tested just my thoughts on  what needs to be considered when people start clicking around on the form.

 

In short, you need to extend Client logic and implement Brand logic.
The rest can stay as they are to meet the requirement.

Michael
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.
May 22, 2023

Hello @Graham Twine

Sorry for the delayed reply; we are using Jira Data Center, not Portal or any other service that Atlassian provides.

We have the latest version of ScriptRunner installed, and I already have the behavior mapped to the specific issue type that we are creating behaviors for.

As for the Request Type customfield, this is just a normal customfield that is a single select drop down like most others.

It sounds like we need to do all behaviors within the field that is doing the manipulation which seems like it can get tricky if I'm trying to use something like the Client customfield in conjunction with several other fields. Do I understand you correctly?

We would like to use the resulting script in multiple situation which lays out the relationship between the fields in an efficient way.

For example, the current behavior script we have for the above described "previously enabled" behavior is below: (This is all in the client field, which according to your previous post sounds like we need to add the Request Type behavior to as well)

//Start of "Options available within another field" script.
import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.jira.groovy.user.FieldBehaviours
import com.onresolve.jira.groovy.user.FormField
import groovy.transform.BaseScript

@BaseScript FieldBehaviours fieldBehaviours

def ClientField = getFieldById("customfield_33221")
def ClientFieldValue = ClientField.value.toString()

def SelectBrandsField = getFieldByName("Select Brand(s)")

def optionManager = ComponentAccessor.optionsManager
def customFieldManager = ComponentAccessor.customFieldManager

def SelectBrandsFieldCustomField = customFieldManager.getCustomFieldObject(SelectBrandsField.fieldId)
def SelectBrandsFieldConfig = SelectBrandsFieldCustomField.getRelevantConfig(issueContext)
def SelectBrandsFieldOptions = optionManager.getOptions(SelectBrandsFieldConfig)

def allAppOptions = [
"Client 1": ["Brand 1"],
"Client 2": ["Brand 1","Brand 2"],
"Client 3": ["Brand 1","Brand 2", "Brand 3"],
]

if (allAppOptions[ClientFieldValue]) {
SelectBrandsField.setFieldOptions(allAppOptions[ClientFieldValue])
} else {
SelectBrandsField.setFieldOptions([])
}

 

//Start of "Auto-hiding fields" script
def EnableField(FormField f) {
f.setHidden(false)
f.setRequired(true)
}

def DisableField(FormField f) {
f.setHidden(true)
f.setRequired(false)
}

def DueDateField = getFieldById("duedate")
def SelectBrandsField = getFieldById("customfield_12345")
def RequestTypeField = getFieldById("customfield_54321")
def TeamField = getFieldById("customfield_11223")

switch (ClientField.getValue()) {
case "Client 1":
EnableField(BrandField)
EnableField(RequestTypeField)
DisableField(DueDateField)
EnableField(TeamField)
break;

case "Client 2":
EnableField(BrandField)
EnableField(RequestTypeField)
DisableField(DueDateField)
EnableField(TeamField)
break;

case "Client 3":
EnableField(BrandField)
EnableField(RequestTypeField)
EnableField(DueDateField)
EnableField(TeamField)
break;

default:
DisableField(BrandField)
DisableField(RequestTypeField)
DisableField(DueDateField)
DisableField(TeamField)

break;
}

 Is there a way to manipulate the current code in order to add the Request Type field behavior to it?

Thanks,

Mike

Graham Twine
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.
May 22, 2023

Hello Mike,

 

You need to extend the logic in the Client field to include the new requirement.

You need to implement some logic in the Brand field as well.

 

From your use case:

  • If Client 1 and Brand 1 are selected; Only show Request Type 1
  • If Client 2 and Brand 1 are selected; Only show Request Type 1 & 2
  • If Client 2 and Brand 2 are selected; Only show Request Type 2
  • If Client 3 and Brand 3 are selected; Only Show Request Type 1 & 3
  • If Client 3 and Brand 1 or 3 are selected; Only show Request Type 2

 

Consider if I chose Client2 from the drop down

Then the logic is show Brand and only permit Brands 1 & 2 as values.

When I select Brand 1 from the Brands list then show Request Type and permit values 1&2

Or:

If I select Brand 2 from the list then only show Request Type 2

This means you need logic in Brand field as well.

 

As you already have a mapping and some logic in Client, just add the Brand field to the mapping and include the logic for this field.

 

Error Case:

More accurately real world humans that do things / change their minds / have selected the wrong Client and correct the selection while reviewing the form for submission.

Consider this series of events:

1. Select Client 1

2. Select Brand 1

3. Select Client 3

4. ....

 

How will the form handle step 4 because the Brand (step 2) is no longer a valid option so the form is in an invalid state?

Possible solution is to clear out the brand form value and reset the brand field with the permitted values

Michael
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.
May 22, 2023

Hi again @Graham Twine

Thanks for all the help!

Suggest an answer

Log in or Sign up to answer