Scriptrunner custom picker. Access current issue/issue not binded

Antoine _Klee Group_ March 2, 2023

Hello.

I am trying to recreate a sort of cascading list within scriptrunner. So basically creating two custom picker fields with the second one needed the value of the first one in order to show proper results. Eventually, both fields will be fed with an API request but for current step in developpment I am just using typical raw json responses.

The structure is as follows. For the first field.

def jsonBody_parent = """

[

    {

        "id": "1",

        "name": "Hello"

    }, {

        "id": "2",

        "name": "HYUNDAI"

    }, {

        "id": "3",

        "name": "Toyota"

    }, {

        "id": "4",

        "name": "Demo"

    },

    {

        "id": "42",

        "name": "The response to the universe"

    }

]

"""

The second level is as follows:

def jsonBody_child = """

[

    {

        "id": "1",

        "name": "specialized",

        "parent_name": "HYUNDAI",

        "parent_id": "2"

    }, {

        "id": "2",

        "name": "rockrider",

        "parent_name": "HYUNDAI",

        "parent_id": "2"

    }, {

        "id": "3",

        "name": "toto",

        "parent_name": "Toyota",

        "parent_id": "3"

    }, {

        "id": "4",

        "name": "tata",

        "parent_name":"Demo",

        "parent_id": "4"

    }

]

"""

So you can easily see that each first level entry has an id. The second level has a name and an id and a reference to the level one (I was testing both by id and name, for now I will filter by name but this does not really matter overall).

The ID of the Parent level is stored in customfield_19000 whereas the child is stored in customfield_19001

 

The issue I have is that I need to read the issue and gather the customfield_19000 value in order to further filter the second json before proposing it into the field.

importing com.atlassian.jira.issue.Issue

and then using the component accessor to get the customfield value does not work. 
groovy.lang.MissingPropertyException: No such property: issue for class is thrown.
How to workaround this issue?
Thanks.

2 answers

0 votes
wangfanggang
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!
April 7, 2023

According to https://docs.adaptavist.com/sr4js/6.57.0/features/script-fields/built-in-script-fields/custom-picker.

When an Issue is provided, this is a "live" issue - it reflects changes made in the form during editing. This allows you to change possible selection values based on issue attributes, or indeed the current user roles and groups etc.

so for your code, you can just  move codes related to:

// (this does not work)

def chantierId = issue.getCustomFieldValue(chantier_field)

to your search closure:

search = { String inputValue, Issue issue ->

    // get the name of the chantier based on its id.

    def chantierId = issue.getCustomFieldValue(chantier_field)
    def chantierName = parsedResponse_chantier.find {

        it.id == chantierId

    }?.name

This works  for me

0 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.
March 11, 2023

Hi @Antoine _Klee Group_

Could you please share the full configuration of your custom picker fields?

I will review it and try to provide you with a solution.

Thank you and Kind regards,
Ram

Antoine _Klee Group_ March 13, 2023

Hi @Ram Kumar Aravindakshan _Adaptavist_ thanks for your help.

There is the code I use

 

import com.onresolve.scriptrunner.canned.jira.fields.model.PickerOption

import groovyx.net.http.ContentType

import groovyx.net.http.HTTPBuilder

import groovyx.net.http.Method

import groovy.json.*

import com.atlassian.jira.issue.Issue

import com.atlassian.jira.component.ComponentAccessor

// Get the custom field chantier

def customFieldManager = ComponentAccessor.getCustomFieldManager()

def chantier_field = customFieldManager.getCustomFieldObject("customfield_10900")

// (this does not work)

def chantierId = issue.getCustomFieldValue(chantier_field)

// Get the name of the chantier corresponding to the chantierId - typical json response for the "chantiers" API

def jsonBody_chantier = """

[

    {

        "id": "1",

        "name": "mon Chantier"

    }, {

        "id": "2",

        "name": "HYUNDAI"

    }, {

        "id": "3",

        "name": "Toyota"

    }, {

        "id": "4",

        "name": "Demo"

    },

    {

        "id": "42",

        "name": "test id de la mort"

    }

]

"""

def parsedResponse_chantier = new JsonSlurper().parseText(jsonBody_chantier)

// typical response for the "velo" API

def jsonBody_velo = """

[

    {

        "id": "1",

        "name": "speciallized",

        "chantier": "HYUNDAI",

        "chantier_id": "2"

    }, {

        "id": "2",

        "name": "rockrider",

        "chantier": "HYUNDAI",

        "chantier_id": "2"

    }, {

        "id": "3",

        "name": "toto",

        "chantier": "Toyota",

        "chantier_id": "3"

    }, {

        "id": "4",

        "name": "tata",

        "chantier":"Demo",

        "chantier_id": "4"

    }

]

"""

def parsedJson = new JsonSlurper().parseText(jsonBody_velo)

search = { String inputValue, Issue issue ->

    // get the name of the chantier based on its id.

    def chantierName = parsedResponse_chantier.find {

        it.id == chantierId

    }?.name

    // Filter the velo list based on the selected chantier

    def filteredList = parsedJson.findAll {

        it.chantier == chantierName

    }

    filteredList.findAll {

        it.name.toLowerCase().contains(inputValue.toLowerCase())

    }

}

toOption = { Map<String, String> map, Closure<String> highlight ->

    new PickerOption(

        value: map.id,

        label: map.name,

        html: highlight(map.name, false),

        icon: "https://www.svgrepo.com/show/493739/bike.svg"

    )

}

getItemFromId = { String id ->

    def selectedOption = parsedJson.find { it.id == id }

   

    if (selectedOption) {

        [id: selectedOption.id, name: selectedOption.name]

    } else {

        null

    }

}

renderItemViewHtml = { Map chantier ->

    "<p style='color:DodgerBlue;'>(chantierId = ${chantierId}, chantierName = ${chantierName}) Le vélo construit est&nbsp;: <b><u>${chantier.name}</u></b></p>"

}

renderItemTextOnlyValue = { Map chantier ->

    chantier.name.toString()

}

Suggest an answer

Log in or Sign up to answer