Forums

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

Make Other Custom Fields Required Based On Checkbox Selected Options

Luis Basilio _Siemens_
Contributor
November 19, 2020

Dear community,

I'm starting with Groovy, and I have a request from our business to make some fields required based on select options of a checkbox custom field.

I'm using ScriptRunner's behaviours feature to do it, but I'm struggling with some exceptions.

Here's my code:

// options/ Agile Team Capacity Impact is a checkbox custom field whith 4 available options
//Agile/Project Team Expansion - Start Date
//Existing Agile / Project Team - Scrum Master and Security Champion Required
//if New Agile /Project Team Staffing - Start Date
//if Non-SI IT Impact: Only 3rd Party/Other Siemens Unit is selected - Nothing to do
import com.onresolve.jira.groovy.user.FieldBehaviours
import org.apache.log4j.Logger
import org.apache.log4j.Level
import groovy.transform.BaseScript

@BaseScript FieldBehaviours fieldBehaviours

// Get the logger and set the log level
def log = Logger.getLogger(getClass())
log.setLevel(Level.DEBUG)

// The name of the field to populate base on the value selected in the checkbox field associated with the script
final firstOptionFieldName = 'Start Date'
final secondOptionFieldName = 'Scrum Master'
final thirdOptionFieldName = 'Security Champion'

// Get the fields
def firstOptionField = getFieldByName(firstOptionFieldName)
def secondOptionField = getFieldByName(secondOptionFieldName)
def thirdOptionField = getFieldByName(thirdOptionFieldName)
def checkBoxField = getFieldById("Agile Team Capacity Impact")
def checkBoxFieldValue = checkBoxField.value

// Collect the selected checkbox values
log.debug("The checkbox field value: '${checkBoxFieldValue}' of type '${checkBoxFieldValue.class.simpleName}'")
def chosenValuesList = []
if (checkBoxFieldValue in String) {
chosenValuesList.add(checkBoxFieldValue)
} else if (checkBoxFieldValue in ArrayList) {
chosenValuesList.addAll(checkBoxFieldValue)
}

// If the user has selected "Agile/Project Team Expansion" force to populate the 'Start Date' field:
if (("Agile/Project Team Expansion" in chosenValuesList) && chosenValuesList.size() == 1) {
checkBoxField.clearError()
firstOptionField.setRequired(true)
log.error "Agile/Project Team Expansion is selected, force to populate the Start Date"


// If the user has selected "Agile/Project Team Expansion" and another value, show an error:
} else if (("Existing Agile / Project Team" in chosenValuesList) && chosenValuesList.size() > 1) {
checkBoxField.setError('If Existing Agile / Project Team is selected Scrum Master and Security Champion are required')
secondOptionField.setRequired(true)
thirdOptionField.setRequired(true)
log.error "MESSAGE:If Existing Agile / Project Team is selected Scrum Master and Security Champion are required"

} else if (("New Agile /Project Team" in chosenValuesList) && chosenValuesList.size() > 1) {
checkBoxField.setError('If New Agile /Project Team is selected "Start Date" is required"')
firstOptionField.setRequired(true)
log.error "MESSAGE:If New Agile /Project Team is selected Start Date is required"

// If the user didn't select any value, or has selected some values, but NOT the "None" value, force to populate the other field:
} else {
checkBoxField.clearError()
firstOptionField.setRequired(false)
secondOptionField.setRequired(false)
thirdOptionField.setRequired(false)
log.error "MESSAGE:First Field attempt"
}
/ options/ Agile Team Capacity Impact is a checkbox custom field whith 4








I would appreciate it if you could help me to troubleshoot the errors below:

2020-11-19 12:33:45,585+0100 http-nio-8080-exec-17 INFO MyUser 753x23698x1 18lz4dl 165.225.92.214,10.130.95.73 /secure/QuickEditIssue.jspa [c.a.j.p.webhooks.matcher.JqlEventMatcher_SLOW] JQL query '{project = "TEST"} AND {key in ("SIITLPM-51")}' produced lucene query and took '251' ms to run.
2020-11-19 12:33:45,903+0100 http-nio-8080-exec-23 WARN MyUser 753x23699x1 18lz4dl 165.225.92.214,10.130.95.73 /secure/AjaxIssueAction!default.jspa [c.a.j.p.webfragment.conditions.EntityPropertyEqualToCondition] Deprecation Warning: EntityPropertyEqualToCondition was not equivalent by JSON comparison but was by String comparison. Please ensure that the entity property values and the condition 'value' are of the same json type. Type coercion has made the actual value: '"false"' be equivalent to the expected value'false'. Please update the expected 'value' in the entity property conditionto match the actual value. This web fragment has the location: NO_LOCATION_AVAILABLE
2020-11-19 12:33:45,981+0100 http-nio-8080-exec-23 WARN MyUser 753x23699x1 18lz4dl 165.225.92.214,10.130.95.73 /secure/AjaxIssueAction!default.jspa [c.a.j.p.webfragment.conditions.EntityPropertyEqualToCondition] Deprecation Warning: EntityPropertyEqualToCondition was not equivalent by JSON comparison but was by String comparison. Please ensure that the entity property values and the condition 'value' are of the same json type. Type coercion has made the actual value: '"false"' be equivalent to the expected value'false'. Please update the expected 'value' in the entity property conditionto match the actual value. This web fragment has the location: NO_LOCATION_AVAILABLE
2020-11-19 12:33:46,432+0100 http-nio-8080-exec-36 ERROR MyUser 753x23704x2 18lz4dl 165.225.92.214,10.130.95.73 /rest/scriptrunner/behaviours/latest/validators.json [c.o.jira.behaviours.BehaviourManagerImpl] *************************************************************************************
2020-11-19 12:33:46,434+0100 http-nio-8080-exec-36 ERROR MyUser 753x23704x2 18lz4dl 165.225.92.214,10.130.95.73 /rest/scriptrunner/behaviours/latest/validators.json [c.o.jira.behaviours.BehaviourManagerImpl] Script function failed on issue: issue: SIITLPM-51, user: MyUser, fieldId: __init__, file: <inline script>
java.lang.NullPointerException: Cannot get property 'class' on null object
at 673a3bfc595c4843a816e61033b81779.run(673a3bfc595c4843a816e61033b81779.groovy:25)
at com.onresolve.jira.behaviours.BehaviourManagerImpl$_runValidator_closure2.doCall(BehaviourManagerImpl.groovy:194)
at com.onresolve.jira.behaviours.BehaviourManagerImpl.runValidator(BehaviourManagerImpl.groovy:141)
at com.onresolve.jira.behaviours.restservice.BehavioursEndpoint.getBehavioursAndRunInitialiser(BehavioursEndpoint.groovy:207)
at com.onresolve.jira.behaviours.restservice.BehavioursEndpoint$_getValidatorsFromIssueId_closure1.doCall(BehavioursEndpoint.groovy:85)
at com.onresolve.jira.behaviours.restservice.BehavioursEndpoint$_getValidatorsFromIssueId_closure1.doCall(BehavioursEndpoint.groovy)
at com.sun.proxy.$Proxy4749.get(Unknown Source)
at com.onresolve.jira.behaviours.restservice.BehavioursEndpoint.withServletThreadLocal(BehavioursEndpoint.groovy:222)
at com.onresolve.jira.behaviours.restservice.BehavioursEndpoint.getValidatorsFromIssueId(BehavioursEndpoint.groovy:77)
... 19 filtered
at com.atlassian.plugins.rest.module.RestDelegatingServletFilter$JerseyOsgiServletContainer.doFilter(RestDelegatingServletFilter.java:160)
... 1 filtered
at com.atlassian.plugins.rest.module.RestDelegatingServletFilter.doFilter(RestDelegatingServletFilter.java:70)
... 32 filtered
at com.atlassian.servicedesk.internal.web.ExternalCustomerLockoutFilter.doFilter(ExternalCustomerLockoutFilter.java:55)
... 8 filtered
at com.atlassian.jira.plugin.mobile.web.filter.MobileAppRequestFilter.doFilter(MobileAppRequestFilter.java:37)
... 4 filtered
at com.atlassian.jira.plugin.mobile.login.MobileLoginSuccessFilter.doFilter(MobileLoginSuccessFilter.java:54)
... 3 filtered
at com.atlassian.diagnostics.internal.platform.monitor.http.HttpRequestMonitoringFilter.doFilter(HttpRequestMonitoringFilter.java:55)
... 8 filtered
at com.atlassian.web.servlet.plugin.request.RedirectInterceptingFilter.doFilter(RedirectInterceptingFilter.java:21)
... 46 filtered
at com.resolution.atlasplugins.samlsso.servlet.RedirectToSsoFilter.doFilter(RedirectToSsoFilter.java:60)
... 14 filtered
at com.atlassian.jira.security.JiraSecurityFilter.lambda$doFilter$0(JiraSecurityFilter.java:66)
... 1 filtered
at com.atlassian.jira.security.JiraSecurityFilter.doFilter(JiraSecurityFilter.java:64)
... 16 filtered
at com.atlassian.plugins.rest.module.servlet.RestSeraphFilter.doFilter(RestSeraphFilter.java:38)
... 19 filtered
at com.atlassian.jira.servermetrics.CorrelationIdPopulatorFilter.doFilter(CorrelationIdPopulatorFilter.java:30)
... 5 filtered
at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.lambda$invokeFilterChain$0(CustomerContextSettingFilter.java:216)
at com.atlassian.servicedesk.internal.api.util.context.ReentrantThreadLocalBasedCodeContext.rteInvoke(ReentrantThreadLocalBasedCodeContext.java:136)
at com.atlassian.servicedesk.internal.api.util.context.ReentrantThreadLocalBasedCodeContext.runOutOfContext(ReentrantThreadLocalBasedCodeContext.java:89)
at com.atlassian.servicedesk.internal.utils.context.CustomerContextServiceImpl.runOutOfCustomerContext(CustomerContextServiceImpl.java:47)
at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.outOfCustomerContext(CustomerContextSettingFilter.java:207)
at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.doFilterImpl(CustomerContextSettingFilter.java:135)
at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.doFilter(CustomerContextSettingFilter.java:124)
... 9 filtered
at com.atlassian.jwt.internal.servlet.JwtAuthFilter.doFilter(JwtAuthFilter.java:37)
... 3 filtered
at com.atlassian.web.servlet.plugin.request.RedirectInterceptingFilter.doFilter(RedirectInterceptingFilter.java:21)
... 4 filtered
at com.atlassian.web.servlet.plugin.LocationCleanerFilter.doFilter(LocationCleanerFilter.java:36)
... 26 filtered
at com.atlassian.jira.servermetrics.MetricsCollectorFilter.doFilter(MetricsCollectorFilter.java:25)
... 25 filtered
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)




Behaviours.pngCustomFields.png

Best Regards
Luis

2 answers

2 accepted

0 votes
Answer accepted
Luis Basilio _Siemens_
Contributor
January 13, 2021
import com.onresolve.jira.groovy.user.FieldBehaviours
import org.apache.log4j.Logger
import org.apache.log4j.Level
import groovy.transform.BaseScript

@BaseScript FieldBehaviours fieldBehaviours

// Get the logger and set the log level
def log = Logger.getLogger(getClass())// Get the logger and set the log level
//def log = Logger.getLogger(getClass())
log.setLevel(Level.DEBUG)

// The name of the field to populate base on the value selected in the checkbox field associated with the script
final staffingDateFieldName = 'Start Date'
final scrumMasterFieldName = 'Scrum Master'
final securityChampionFieldName = 'Security Champion'

// Get the fields
def staffingDateField = getFieldById("customfield_11700")
def scrumMasterField = getFieldById("customfield_13002")
def securityChampionField = getFieldById("customfield_13006")
def checkBoxField = getFieldById("customfield_12610")
def checkBoxFieldValue = checkBoxField.value
def checkBoxFieldName = checkBoxField.label
def value = checkBoxField.getValue()

// Collect the selected checkbox values
//log.debug("The checkbox field value: '${checkBoxFieldValue}' of type '${checkBoxFieldValue.class.simpleName}'")
def chosenValue = checkBoxFieldValue

// Clear any "cache" data from the issue
checkBoxField.clearError()
staffingDateField.setRequired(false)
scrumMasterField.setRequired(false)
securityChampionField.setRequired(false)

//if (checkBoxFieldValue) {
// log.debug("The checkbox field value: '${checkBoxFieldValue}' of type '${checkBoxFieldValue.class.simpleName}'")
//} else {
// log.debug("No value from checkbox :${checkBoxField} is selected")
// log.debug("No value from checkbox :${staffingDateField} is selected")
//}

switch(chosenValue) {
case "Agile Team Expansion":
checkBoxField.clearError()
// if(staffingDateField.value==""){
// checkBoxField.setError('"Existing Agile / Project Team" is selected "Scrum Master " and " Security Champion " are required')
// }
checkBoxField.setError('"Agile/Project Team Expansion" is selected, " Start Date " is required')
staffingDateField.setRequired(true)
scrumMasterField.setRequired(false)
securityChampionField.setRequired(false)
checkBoxField.clearError()
if (value.getClass().getName().toString() != "java.lang.String") {
def values = value as ArrayList
if(values.size() > 1){
checkBoxField.setError("Only one value is allowed for this field: " + values.size() + " currently selected")
}
} else {
checkBoxField.clearError()
}

break
case "Existing Team":
checkBoxField.clearError()
// if(scrumMasterField.value=="" && securityChampionField.value==""){
// checkBoxField.setError('"Existing Agile / Project Team" is selected " Scrum Master " and " Security Champion " are required')
// }
staffingDateField.setRequired(false)
scrumMasterField.setRequired(true)
securityChampionField.setRequired(true)
checkBoxField.clearError()
if (value.getClass().getName().toString() != "java.lang.String") {
def values = value as ArrayList
if(values.size() > 1){
checkBoxField.setError(" Only one value is allowed for this field: " + values.size() + " currently selected")
}
} else {
checkBoxField.clearError()
}
break
case "New Agile Team":
checkBoxField.clearError()
// if(staffingDateField.value==""){
// checkBoxField.setError('"New Agile /Project Team Staffing" selected, " Start Date " is required')
// }
staffingDateField.setRequired(true)
scrumMasterField.setRequired(false)
securityChampionField.setRequired(false)
checkBoxField.clearError()
break
default:
checkBoxField.clearError()
staffingDateField.setRequired(false)
scrumMasterField.setRequired(false)
securityChampionField.setRequired(false)
checkBoxField.clearError()
if (value.getClass().getName().toString() != "java.lang.String") {
def values = value as ArrayList
if(values.size() > 1){
checkBoxField.setError("Only one value is allowed for this field: " + values.size() + " currently selected")
}
} else {
checkBoxField.clearError()
}
}

 This code matched all of my requirements. 

0 votes
Answer accepted
Guilhem Dupuy
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.
November 19, 2020

Hi Luis,

Have you tried the Dynamic Forms option of the Extension for Jira Service Management Add-On ? I've implemented such a solution in an instance, it works perfectly and it's really easy to configure and maintain.

You'll find it here .

Let me know if it helped,

Guilhem

Luis Basilio _Siemens_
Contributor
November 19, 2020

Hi @Guilhem Dupuy ,

Thanks for your tip. Unfortunately, we don't have this app. 
We have ScriptRunner, and JWME. Do you think that it would be possible by using them?

Best Regards
Luis

Guilhem Dupuy
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 13, 2021

I know that this is probably doable using ScriptRunner but I am not a ScriptRunner expert, I don't know how, sorry :/

Suggest an answer

Log in or Sign up to answer