Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in
It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

minQueryLength and keyInputPeriod being ignored for Select List Conversion

Edited

 

Hello All,

I am using a select list conversion with the following initializer function in my behavior:

getFieldById(myFieldId).convertToSingleSelect([
    ajaxOptions: [
        url: getBaseUrl() + "/rest/scriptrunner/latest/custom/myFunction",
        query: true,
        minQueryLength: 4, 
        keyInputPeriod: 500,
        formatResponse: "general"
    ]
]);

 The problem is whenever I click on the custom field in the view/edit screen, it immediately starts querying, ignoring the minQueryLength parameter of 4 and the keyInputPeriod parameter as well.

I also noticed that as I type into the field, it thinks for a while, clears out the text from the form, and returns an empty list.  Looking at the network traffic, I see that every time I make a key input, it fires off another request to the AJAX url, eventually cancelling the previous requests, but every time it cancels, it also clears the form and the results.  This creates a really clunky and almost unusable user experience.

1 answer

I can't seem to reproduce this issue you have in the latest version of ScriptRunner. It seems to respect the min query length.

Have you tried the example here? What do you get with that?

Do you have the code for your custom endpoint?

What version of JIRA and ScriptRunner are you using?

I upgraded to ScriptRunner 5.0.1 and am running JIRA Software 7.2.6.

Here is the code for the custom REST endpoint.  The endpoint fetches a list of assignment groups from ServiceNow and the idea is the user will select one of those groups from a drop-down in a JIRA issue (hence the select list conversion).

import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript

import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

import groovy.json.JsonBuilder
import groovyx.net.http.HTTPBuilder
import org.apache.http.HttpRequest
import org.apache.http.HttpRequestInterceptor
import org.apache.http.protocol.HttpContext

import static groovyx.net.http.ContentType.JSON
import static groovyx.net.http.Method.GET

@BaseScript CustomEndpointDelegate delegate

// === BEGIN PARAMETERS ===

def username = "USERNAME"
def password = "PASSWORD"
def snBaseUrl = "SN_BASE_URL"

// === END PARAMETERS ===

def getResponse = { output ->
    return Response.ok(
        new JsonBuilder(output).toString()
    ).build();
}

def getError = { message ->
    return Response.ok(new JsonBuilder([
        items: [
            value: "None",
            html: "None",
            label: "None"
        ],
        footer: message
    ]).toString()).build();
}

servicenowassignmentgroups(httpMethod: "GET") { MultivaluedMap queryParams, String body -> 
    def query = queryParams.getFirst("query") as String
    if(!query) {
        query = ""
    }
    
    def http = new HTTPBuilder(snBaseUrl)
    http.client.addRequestInterceptor(new HttpRequestInterceptor() {
        void process(HttpRequest httpRequest, HttpContext httpContext) {
            httpRequest.addHeader("Authorization", "Basic " + "$username:$password".bytes.encodeBase64().toString())
        }
    })
    
    def response = http.request(GET, JSON) { req ->
        uri.path = "/api/now/table/sys_user_group"
        uri.query = [ sysparm_query: "nameLIKE$query" ]
        headers.Accept = "application/json"

        response.success = { resp, json -> 
            return json
        }

        response.failure = { resp ->
            return null
        }
    }
    
    if(response == null) {
        return getError("Unable to retrieve ServiceNow assignment groups")
    }
    
 def output = response.result.collect { group ->
        def html = group.name
        if (query) {
            html = html.replaceAll(/(?i)$query/) { 
                "<b>${it}</b>" 
            }
        }
        
        [
            value: group.sys_id,
            html: html,
            label: group.name
        ]
    }
    
    return getResponse(
        [ 
            items: output,
            total: output.size(),
            footer: "Choose Assignment Group..."
        ]
    )
}

I tried the example to create a github repo query from the select list conversions page.

The options for minQueryLength and keyInputPeriod do indeed work.

Okay, I don't know why, but I think I figured it out.

In my custom rest endpoint, I moved the getResponse and getError functions INSIDE the servicenowassignmentgroups function, and it works!

Why is that?

I've noticed sometimes there is odd behavior when you have code sitting outside the actual REST endpoint function.  For example, I had a similar endpoint where I defined the "output" variable outside of REST endpoint function, and every call to the endpoint would take the output from the previous run of the endpoint and concatenate the new result.

Hi @Irtiza Rizvi 

 

Can you help me on my rest endpoint below? I'm trying to get the u_display_name from affected CI in ServiceNow. 

ServiceNow Rest endpoint: working in Postman

https://manulifedev.service-now.com/cmdb_ci_list.do?JSONv2&sysparm_query=sys_class_name%3Dcmdb_ci_appl%5Eu_status%3DActive&sysparm_view=application

 

 

import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript

import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

import groovy.json.JsonBuilder
import groovyx.net.http.HTTPBuilder
import org.apache.http.HttpRequest
import org.apache.http.HttpRequestInterceptor
import org.apache.http.protocol.HttpContext

import static groovyx.net.http.ContentType.JSON
import static groovyx.net.http.Method.GET

@BaseScript CustomEndpointDelegate delegate

// === BEGIN PARAMETERS ===

def username = "USERNAME"
def password = "PASSWORD"
def snBaseUrl = "SN_BASE_URL"

// === END PARAMETERS ===

def getResponse = { output ->
return Response.ok(
new JsonBuilder(output).toString()
).build();
}

def getError = { message ->
return Response.ok(new JsonBuilder([
items: [
value: "None",
html: "None",
label: "None"
],
footer: message
]).toString()).build();
}

servicenowaffectedci(httpMethod: "GET") { MultivaluedMap queryParams, String body ->
def query = queryParams.getFirst("query") as String
if(!query) {
query = ""
}

def http = new HTTPBuilder(snBaseUrl)
http.client.addRequestInterceptor(new HttpRequestInterceptor() {
void process(HttpRequest httpRequest, HttpContext httpContext) {
httpRequest.addHeader("Authorization", "Basic " + "$username:$password".bytes.encodeBase64().toString())
}
})

def response = http.request(GET, JSON) { req ->
uri.path = "/cmdb_ci_list.do?JSONv2&sysparm_query=sys_class_name%3Dcmdb_ci_appl%5Eu_status%3DActive&sysparm_view=application"
uri.query = [ sysparm_query: "nameLIKE$query" ]
headers.Accept = "application/json"

response.success = { resp, json ->
return json
}

response.failure = { resp ->
return null
}
}

if(response == null) {
return getError("Unable to retrieve ServiceNow affected CI")
}

def output = response.result.collect { group ->
def html = u_number
if (query) {
html = html.replaceAll(/(?i)$query/) {
"<b>${it}</b>"
}
}

[
value: u_display_name,
html: html,
label: u_number
]
}

return getResponse(
[
items: output,
total: output.size(),
footer: "Choose Affected CI name.."
]
)
}

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Apps & Integrations

Marketplace Partner Spotlight: Fine Software

Happy New Year, everybody! What better way to kick off 2022 than with a new Marketplace Partner Spotlight ✨ This month, we're getting to know Daniel Franz, co-founder of Fine Software. Fine Software ...

379 views 2 15
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you