ScriptRunner Field Behaviours Change Select Options for Asset Fields

Amos
Contributor
October 16, 2023

I'm aware that this is potentially achievable using asset custom fields and reference asset custom fields, however I have a unique circumstance that extends beyond this.

Context:

I have an asset model that has four object types:

  • A
  • B (with references to A)
  • C (with references to A)
  • D (with references to A)

I have exposed all these object types through custom fields like so:

  • A (asset field)
  • B (reference asset field) referenced to A
  • C (reference asset field) referenced to A
  • D (reference asset field) referenced to A.

Using ScriptRunner, I want to define a field behaviour whereby options for customfield D (which is object type D) only displays objects D1, D2 and D3 if B1 in customfield B has been selected. Otherwise, I only want D1 and D2 to be selectable. Any assistance with the groovy aspect of this would be much appreciated. I've been able to interact with assets previously using the ObjectFacade, however setting the field options is proving to be slightly more challenging.

3 answers

2 votes
Ram Kumar Aravindakshan _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
October 17, 2023

Hi @Amos

It's a bit of a tricky requirement. You won't be able to filter the Asset field using the Behaviour. This must be done using the Field's configuration and adding the IQL query.

However, for the Behaviour, you must create 2 separate Server-Side Behaviours, i.e. for both the Asset fields separately and with that you will need to use the setErrorMessage to trigger the error when a wrong option is selected.

Below are two sample codes for your reference: (it's not 100% tested)

import com.adaptavist.hapi.jira.assets.Assets
import com.onresolve.jira.groovy.user.FieldBehaviours
import com.riadalabs.jira.plugins.insight.services.model.ObjectBean
import groovy.transform.BaseScript

@BaseScript FieldBehaviours behaviours
def asset = getFieldById(fieldChanged)
def assetValue = asset.value.toString()

def subAsset = getFieldByName('Sub Asset')
def subAssetValue = subAsset.value.toString()
subAsset.clearError()

if (assetValue in ['SA-1', 'SA-8']) {
def filter = Assets.search(""""Host" IN (${assetValue})""" ).collect() as List<ObjectBean>
def filterNames = filter.objectKey as List<String>

if (subAssetValue.length() > 0) {
if (subAssetValue.contains(',')) {
def subAssetFilter = subAssetValue.replace('[','').replace(']','').trim().split(',') as List
if (!filterNames.intersect(subAssetFilter)) {
subAsset.setError('Invalid Sub-Asset Selected')
}
} else {
if (!filterNames.contains(subAssetValue)) {
subAsset.setError('Invalid Sub-Asset Selected')
}
}
}
}

and

import com.adaptavist.hapi.jira.assets.Assets
import com.onresolve.jira.groovy.user.FieldBehaviours
import com.riadalabs.jira.plugins.insight.services.model.ObjectBean
import groovy.transform.BaseScript

@BaseScript FieldBehaviours behaviours
def asset = getFieldByName('Assets')
def assetValue = asset.value

def subAsset = getFieldById(fieldChanged)
def subAssetValue = subAsset.value.toString()
subAsset.clearError()

if (assetValue in ['SA-1', 'SA-8']) {
def filter = Assets.search(""""Host" IN (${assetValue})""" ).collect() as List<ObjectBean>
def filterNames = filter.objectKey as List<String>

if (subAssetValue.length() > 0) {
if (subAssetValue.contains(',')) {
def subAssetFilter = subAssetValue.replace('[','').replace(']','').trim().split(',') as List
if (!filterNames.intersect(subAssetFilter)) {
subAsset.setError('Invalid Sub-Asset Selected')
}
} else {
if (!filterNames.contains(subAssetValue)) {
subAsset.setError('Invalid Sub-Asset Selected')
}
}
}
}

The first one is for Custom Field B and the second is for Custom Field D.

I hope this helps to answer your question. :-)

Thank you and Kind regards,

Ram

Amos
Contributor
October 22, 2023

Thanks Ram, I'm most certainly going to give this a go.

Ram Kumar Aravindakshan _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
October 25, 2023

Hi @Amos

Was the solution able to help solve your question?

Thank you and Kind regards,

Ram

1 vote
Peter-Dave Sheehan
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.
October 17, 2023

Due to the dynamic nature that the Asset Custome field load the available options, Behaviours is not going to be able to interfere.

The only thing you can do with Behaviours is to intercept the user's selection, place the form in an error state, and provide feedback to the user that the selection is invalid. You can't limit the selection itself.

But that should be possible within the Issue Scope IQL in the custom field configuration.

Amos
Contributor
October 22, 2023

Thanks Peter, we've been trying to use the Filter Issue Scope (AQL) to do this, but with very limited success. I created an outbound reference between the objects I wanted the behaviour to occur with. I then tried:

object HAVING outboundReferences(Label IN (${customfield_xxxxx}))

There error we get is <iql,Placeholder not support in current context> but this is not a very useful error message, so we're not having much luck on this front. It seems like the simple and obvious answer.

Amos
Contributor
October 22, 2023

My take on this, having just done a few hours of looking around is Filter Issue Scope (AQL) doesn't support custom fields that are asset or reference asset object fields. If it does, then the documentation leaves a lot left to be desired.

Peter-Dave Sheehan
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.
October 23, 2023

Not at all, I have several Asset Custom fields with complex cascading dependencies. Enough to give you a headache trying to understand what it does:

(Customer IN (${Customer(s)${0}}) OR object having outR(objectType = Customer AND object having inR(objectType = "Customer" and Key IN (${Customer(s)${0}}),referenceType in ("Has")))) AND "Issue Types" like ${issuetype.name} AND "Environment Type" IN (${Environment Type${0}})

In my example "Customer(s)" and "Environment Type" are both Asset fields. 

 

It's a bit difficult to consult in the abstract, if you could attach some concrete examples with screenshots, I'm sure I can help you come up with an Issue Scope IQL

Trang Ngoc Nguyen December 18, 2023

Hi @Peter-Dave Sheehan, I have a question regarding the IQL.

I have an Assets Custom Field called "Affected employees" that contain all the employee objects. This field is displayed in the customer request type, and once a ticket is created it can have multiple values, for example Name 1 (ASSET-1), Name 2 (ASSET-2), Name 3 (ASSET-3).

Now I have another Assets Field which is called "Order for" that is displayed on a transition screen. I want to limit the selection of this fieds to only employee objects that are in the "Affected employees" field. I have tried mutiple option: 

  • Name in (${Affected employees${0}})
  • object in (${Affected employees${0}})
  • label in (${Affected employees${0}})
  • object in ${customfield_XXX.key}
  • Name in ${customfield_XXX.name})

but all of them didn't work. Could you please help me with an suggestion here?

 

Thank you very much!

Trang Ngoc Nguyen December 18, 2023

I actually figured it out, I need to use Key in (${Affected employees${0}}) instead. 

Thank you for the great suggestion above though!

Like Peter-Dave Sheehan likes this
0 votes
Ann
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!
January 29, 2025

@Peter-Dave Sheehan hi

Could you help me? I need to limit the list of objects for different types of client requests on the portal.

For example:
Request 1.
Object A
Object B

Request 2.
Object C
Object D

Maybe you know if IQL can be limited in this way?

Peter-Dave Sheehan
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.
January 30, 2025

Just trying to make sure I understand your example... 

You have 1 object type with 4 objects: A, B,C,D

And 1 custom field that shows objects from the object type.

But you want the custom field to show either A,B or C,D based on the Request Type (assuming JSM request type from the customer portal).

You can't quite do that out of the box. There is no "AQL PLaceholder" that will respond to the Request Type. So you need to trick the system with another custom field.

  • Create (or reuse) a text custom field.
  • In the configuration of request 1, add that custom field (hidden) with a default value of "request 1".
  • Repeat for request 2.
  • In your object, add an attribute called "Request Types" or something along those lines
  • For object A and object B, set the Request Types value to "request 1" and "request 2" for objects C and D.
  • In the Asset custom field, set the Issue AQL  to: "Request Types" like ${customfield_1111}" where 1111 is the ID the of the text custom field that's being defaulted in the request type config.

Note that I'm recommending "Request Types" (plural) and "like" operator. This way, should you need to create another object E applicable to both Request 1 and Request 2, you can just set that object's "Request Types" attribute to "request 1, request 2".

Hope this helps.

Like Ann likes this

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
SERVER
VERSION
9.4.10
TAGS
AUG Leaders

Atlassian Community Events