Scriptrunner behaviour setFormValue not working for mutiple user picker

Roland Ng June 24, 2022

Hello,

I am trying to build a behavior script that update multiple user picker field according to insight object custom field in real time including issue creation.

 

There is an user attribute known person-in-charge defined in my insight objects, let say there are 3 objects and their person-in-charge will be like this:

1. App 1: CCB1 

2. App 2: CCB2

3. App 3: CCB3

 

And when I select App 1 & App 2, CCB1 & CCB2 should be selected to the multiple user picker automatically. I managed to get the username out of the insight objects and create the list, but when I try to update the multiple user picker with the following code but  turns out it did nothing:

getFieldByName("<multiple-user-picker>").setFormValue(ArrayList)

 

The problem only exists when I am updating multiple user picker, it works when I use the following code to update single user picker field:

getFieldByName("<single-user-picker>").setFormValue("CCB1")

 

1 answer

1 accepted

1 vote
Answer accepted
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.
June 25, 2022

What is in your ArraList when you do setFormValue?

Is that an array of ApplicationUser object?

Ior an array of String values extracted directly from insight?

And what type of attribute is "known person-in-charge"?

If the "known person-in-charge" is a "User" attribute,  then it contains the user's key. Not the user's name. Where the user's name is CCB1, the user's key might be something like JIRA12345

And behaviour setformValue on a multi select user picker expects an array username strings.

So if you have alist of ApplicationUser object in your array, then you should be able to set the value with:

getFieldByName("name").setFormValue(userList*.name)

If your array contains sting user keys, then try

getFieldByName("name").setFormValue(userKeyList.collect{userManager.getUserByKey(it).name})
Roland Ng June 26, 2022

Thanks for the reply Peter. I tried all three types and setFormValue function still not working for all three types, the output as below:

Capture.PNG

FYR, please find my scriptrunner behaviour code below:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.user.ApplicationUser
import com.onresolve.jira.groovy.user.FormField

def userManager = ComponentAccessor.getUserManager() as UserManager

import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript

@BaseScript FieldBehaviours fieldBehaviours

// Access Insight Java API
Class iqlFacadeClass = ComponentAccessor.getPluginAccessor().getClassLoader().loadClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.IQLFacade")
def iqlFacade = ComponentAccessor.getOSGiComponentInstanceOfType(iqlFacadeClass)
Class objectFacadeClass = ComponentAccessor.getPluginAccessor().getClassLoader().loadClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade")
def objectFacade = ComponentAccessor.getOSGiComponentInstanceOfType(objectFacadeClass)

// Defining the Insight object information
def objectSchemaID = 1
def attributeName = "CCB Approver"
def CCBs = []
def CCB_AppUser = []
def CCB_Str = []
def count = 0

def CustFld = getFieldById("customfield_10106").getValue() // Application
FormField TarFld = getFieldByName("CCB Approver(s)") // CCB Approver(s)
FormField SingleFld = getFieldById("customfield_10109") // Single CCB Approver

def CustFldType = CustFld.getClass().name
def TarFldType = TarFld.getClass().name
def SingleFldType = SingleFld.getClass().name

def getArrType(InArr){
def ArrItemCount = 0
def outstring = "ArrType:" + InArr.getClass().name
for (ArrItem in InArr){
outstring = outstring + "<br>" + ArrItemCount + "=" + ArrItem.getClass().name
ArrItemCount = ArrItemCount + 1
}
return outstring
}

if ( !CustFld.equals([""]) ){
if (CustFldType.equals("java.lang.String")){
log.warn "Skip"
}
else {
for (app in CustFld){
// Get the matching objects from Insight. In this case we are looking for a single object by its unique object key
def insightObjects = iqlFacade.findObjectsByIQLAndSchema(objectSchemaID, "Key = \"" + app + "\"")

for (object in insightObjects) {
def ccbAttribute = objectFacade.loadObjectAttributeBean(object.getId(), attributeName)

if (ccbAttribute != null) {
def ccbAttributeValues = ccbAttribute.getObjectAttributeValueBeans()
if (ccbAttributeValues != null) {
for (CCB in ccbAttributeValues) {
def temp = CCB.getValue()
ApplicationUser user = userManager.getUserByKey(temp.toString())
CCBs.add(temp)
CCB_AppUser.add(user)
CCB_Str.add(user.name)
}
}
}
}
}

getFieldByName("CCBs (User Key)").setFormValue(CCBs)
getFieldByName("CCBs (User Key)").setDescription(CCBs.toString() + "<br>" + getArrType(CCBs))

getFieldByName("CCBs (App User)").setFormValue(CCB_AppUser)
getFieldByName("CCBs (App User)").setDescription(CCB_AppUser.toString() + "<br>" + getArrType(CCB_AppUser))

getFieldByName("CCBs (String)").setFormValue(CCB_Str)
getFieldByName("CCBs (String)").setDescription(CCB_Str.toString() + "<br>" + getArrType(CCB_Str))
}
}
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.
June 27, 2022

First a couple of tips ...

1) you can access the insight API with the @WithPlugin and @PluginModule notations provided by scriptrunner

import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.IQLFacade
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade

@WithPlugin('com.riadalabs.jira.plugins.insight') insightPlugin
@PluginModule IQLFacade iqlFacade
@PluginModule ObjectFacade objectFacade

The WithPlugin allows you to import directly. And the PluginModule is a shortcut for the  getOSGiComponentInstanceOfType()

2) To get objectBeans from a formField you can use the loadObjectBean method of objectFacade istead of using IQL search.

def objectBeans = (formField.value as List).collect{
objectFacade.loadAttachmentBeanById(it)
}

But finally, the screenshot shows that the CCBs (String) field is a single User Picker. Not a MultiUser Picker.

Your third method should work on a multi-picker. If you want to populate a single picker, you have to extract one item from your array: 

getFieldByName("CCBs (String)").setFormValue(CCB_Str[0])
Roland Ng June 27, 2022

Thanks for for the tips, but all three CCB fields are multi-picker field. I manually input CCB1 and CCB2 for all three CCB fields. Could the Search Template of the custom field affect the setFomValue function cause I find out that it is always "User Picker & Group Searcher" for both single user picker and multiple user picker.

image.png

And "Single CCB Approver" is the single user picker field which works perfectly fine with similar code:

getFieldByName("Single CCB Approver").setFormValue(CCB_Str[0]) 

  

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.
June 27, 2022

Ah... I'm on the previous LTS version of Jira 8.13.x and in my environment, this is what a multi-user picker looks like:2022-06-27 21_00_03-Create Issue - JIRA Test.png

And for me, the set form value with array of user.name works perfectly.

From this https://jira.atlassian.com/browse/JRASERVER-32092 looks like this was induced in in a non-LTS version.

Maybe Adaptavist haven't yet updated Scriptrunner to support this.

I'll have to keep that in mind when I upgrade.

One thing you can do to investigate and perhaps work around, is add a behaviour configuration for your CCBs (String) field.

Then, when you manually update the field, examine the POST that your browser makes to rest/scriptrunner/behaviours/latest/runvalidator.json.

In the payload, you will find that custom field and the data format. Then, try to replicate that format in your setFormValue call.

Roland Ng June 28, 2022

Thanks a lot, so seems like it is caused by the multiple user picker behaviour change.

I tried the format displayed in payload, "<user_1>-*-*-<user_2>-*-*-...<user_n>" but seems like it doesn't work as well, so I will probably use numbers of single user picker as workaround.

image.png

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events