Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Scriptrunner Custom Script field Multi-picker

Matt Donagan October 26, 2022

Creating a Jira screen for new users requests. I need to create a field that is multi-picker that lists the current Jira projects, so the person requesting the account can pick which projects they need access to, and populate the ticket accordingly.

I am certainly not a programmer and I can't find anything out there like this.

Any help appreciated

Thanks,

Matt

1 answer

1 accepted

1 vote
Answer accepted
PD 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 26, 2022

You can create a scriptrunner script field using the "Custom Picker" option.

Using the "Show Snippet", I grabbed the example for Version picker, and converted the suggested configuration code to make it work as a project picker:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.Project
import com.onresolve.scriptrunner.canned.jira.fields.model.PickerOption
import org.apache.commons.lang3.StringUtils

def projectManager = ComponentAccessor.projectManager

validate = { Project project ->
!project.archived
}

search = { String inputValue ->
projectManager.projectObjects.findAll {
!it.archived && (StringUtils.containsIgnoreCase(it.name, inputValue) | StringUtils.containsIgnoreCase(it.key, inputValue))
}
}

getItemFromId = { String id ->
projectManager.getProjectObj(id.toLong())
}

toOption = { Project project, Closure highlight ->
new PickerOption(
value: project.id.toString(),
label: "$project.name ($project.key)",
html: "${highlight(project.name, false)} (${project.key}) ${getLozenge(project)}",
)
}

renderItemViewHtml = { Project project ->
"$project.name ($project.key) ${getLozenge(project)}"
}

renderItemTextOnlyValue = { Project project ->
"$project.name ($project.key)"
}

String getLozenge(Project project) {
if (project.isArchived()) {
'<span class="aui-lozenge aui-lozenge-subtle">Archived</span>'
} else {
'<span class="aui-lozenge aui-lozenge-current aui-lozenge-subtle">Active</span>'
}
}

You can find more details in the documentation: https://docs.adaptavist.com/sr4js/6.58.1/features/script-fields/built-in-script-fields/custom-picker?utm_source=product-help

Matt Donagan October 27, 2022

Thank you

Oskar Austegard
Contributor
August 18, 2023 edited

Thanks for this, Peter.  Do you know of any concise documentation that clearly communicates the functions that are expected to be implemented in a configuration script?

The ? button for the configuration screen shows that the following are accessible, but it is not clear which may be required for an implementation

log
multiValueDelimiter
allowJavaScript
maxRecordsForSearch
highlightMatchesWordPrefixesOnly
disableTextIndexing
getPlaceholderString
renderViewHtml
renderColumnHtml
renderTextOnlyValue
search
validate
getItemFromId
toOption
renderItemViewHtml
renderItemColumnViewHtml
renderItemTextOnlyValue


Notably absent is `issue` which is available in a simple scripted field.

My use case is to access (a subset of) Components in the current project, which would be doable if I could find a way to refer to the current issue/project/component list

I find the Adaptivist documentation to be frantically dispersed... 

PD 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.
August 21, 2023

I'm not aware of any documentation other than the page I shared above.

But based on that, the "issue" variable is only defined in the context of the search method you see in the '?' popup.

So if you want to get a filtered subset of components, you can set the configuration script to:

search = {String inputValue, Issue issue->
  def projectComponents = ComponentAccessor.projectComponentManager.findAllForProject(issue.project.id)
  return projectComponents.findAll{ <filter criteria for your subset>}
}
Nanda Hareesh Kumar February 2, 2024

Hi @PD Sheehan,

I have created a component picker field as shown below. But it doesn't work. Can you please help me in that regard.

 


import com.atlassian.jira.issue.fields.ComponentsField
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.Project
import com.atlassian.jira.issue.Issue
import com.onresolve.scriptrunner.canned.jira.fields.model.PickerOption
import org.apache.commons.lang3.StringUtils

def search = {String inputValue, Issue issue->
  def componentManager = ComponentAccessor.projectComponentManager.findAllForProject(issue.project.id)
   return projectComponents.findAll(componentManager)
}

def getItemFromId = { String id ->
   componentManager.getComponent(id.toLong())
}
def toOption = { ComponentsField component, Closure highlight ->
   new PickerOption(
       value: component.id.toString(),
       label: component.name,
       html: "${highlight(component.name, false)} ${getLozenge(component)} (${component.project.key})",
       renderItemViewHtml: { ComponentsField comp ->
           "$component.name ${getLozenge(comp)} (${comp.project.key})"
       },
       renderItemTextOnlyValue: { ComponentsField comp ->
           comp.name
       }
   )
}

String getLozenge(ComponentsField component) {
     {
        '<span class="aui-lozenge aui-lozenge-current aui-lozenge-subtle">component</span>'
    }
}
PD 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.
February 3, 2024

I'm not sure what you were trying to do with that code, but it was a bit of a mess.

This here should get you something that works and you can adjust the render options:

import com.atlassian.jira.bc.project.component.ProjectComponent
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.project.Project
import com.onresolve.scriptrunner.canned.jira.fields.model.PickerOption

def componentManager = ComponentAccessor.projectComponentManager


search = { String inputValue, Issue issue ->
def components = componentManager.findAllForProject(issue.projectObject.id)
return components
}

getItemFromId = { String id ->
componentManager.getProjectComponent(id.toLong())
}

toOption = { ProjectComponent component, Closure highlight ->
new PickerOption(
value: component.id.toString(),
label: component.name,
html: "${highlight(component.name, false)}"
)
}

renderItemViewHtml = { ProjectComponent component ->
getLozenge(component)
}

renderItemTextOnlyValue = { ProjectComponent component ->
component.name
}

String getLozenge(ProjectComponent component) {
{
"""<span class="aui-lozenge aui-lozenge-current aui-lozenge-subtle">$component.name</span>"""
}
}

Project getProject(ProjectComponent component) {
def projectManager = ComponentAccessor.projectManager
projectManager.getProjectObj(component.projectId)
}
Like 2 people like this
Nanda Hareesh Kumar February 4, 2024

@PD Sheehan Thank you very much. It works.

Suggest an answer

Log in or Sign up to answer
TAGS
atlassian, atlassian government cloud, fedramp, webinar, register for webinar, atlassian cloud webinar, fedramp moderate offering, work faster with cloud

Unlocking the future with Atlassian Government Cloud ☁️

Atlassian Government Cloud has achieved FedRAMP Authorization at the Moderate level! Join our webinar to learn how you can accelerate mission success and move work forward faster in cloud, all while ensuring your critical data is secure.

Register Now
AUG Leaders

Atlassian Community Events