How to conditionally hide a Jenkins Job parameter based on the value of another parameter

Kobi Rosenstein
4 min readFeb 10, 2025

--

This is a pretty commonly asked question, but the answer really isn’t straightforward.

The closest I could find was using Active Choices, and using HTML / Javascript to conditionally hide the parameter’s input, while not hiding the parameter name. While this is useful, it serves more a way to prevent user input than to really, truly hide a parameter — and sometimes, you just want to hide a parameter!

For example, let’s say I have a parameter called SERVER_ACTION, which returns a List of ['stop','start','restart'] , and another parameter called SERVER_STOP_GRACE_PERIOD . Assuming I selected stop , I will wait SERVER_STOP_GRACE_PERIOD for a server to gracefully shutdown before force powering off.

In the case that I selected something other than stop, I don’t want to even display the SERVER_STOP_GRACE_PERIOD parameter, since it is no longer relevant, and just presents visual clutter.

So, to fully and completely hide a parameter, we can use an Active Choices reactive Reference parameter of type ET_FORMATTED_HIDDEN_HTML , which will modify the page HTML based on the value of a referenced parameter. Naturally, I use my shared library to store this parameter, since it is pretty ugly to repeat each job, potentially multiple times.

IMPORTANT:

This code will only work if the monitor Parameter is a String , Boolean , or Choice parameter.

It can be adjusted to fit other input types by finding the relevant HTML elements from the web Inspector.

// Standalone parameter
sharedParameters.conditionalParamHider(
paramToHide: 'MY_CONDITIONAL_PARAM',
monitorParam: 'PARAM_WHOSE_VALUE_IS_CHECKED',
hideIfThisValue: 'Inputting or selecting this value in monitorParam will cause the param to be hidden.',
),
// Full example
// Jenkinsfile.groovy :
@Library('MySharedLibrary') _
AGENT_LABEL = 'linux && build'
pipeline {
agent {
label AGENT_LABEL
}
options {
timestamps()
timeout(time: 30, unit: 'MINUTES')
ansiColor('xterm')
}

stages{
stage('Setup Parameters') {
steps {
script {
println('INFO: This run will not run other stages')
currentBuild.description = "REFRESH PARAMETERS"
properties([
parameters([
sharedParameters.refreshParameters(),
sharedParameters.hiddenUsername(),
choice(name: 'SERVER_ACTION',
choices: ['stop', 'start', 'restart'],
description: 'If set to No, you must select an Environment, and then filter and choose specific resources in the Environment to delete.',
),
string(name: 'SERVER_STOP_GRACE_PERIOD'),
sharedParameters.conditionalParamHider(
paramToHide: 'SERVER_STOP_GRACE_PERIOD',
monitorParam: 'SERVER_ACTION',
hideIfThisValue: 'stop',
),
// sharedParameters.groovy:
def conditionalParamHider(Map args) {
// Required args:
// paramToHide - this is the param which we will be able to hide conditionally based on the monitor param
// monitorParam - this is the name of the param whose value will determine whether to hide a different param.
// hideIfThisValue - this is the value of the param whose value will determine whether to hide a different param.

String hiderScript = $/
return """
<style>
/* Initially hide in case it's already loaded */
input[name="name"][value="${args.paramToHide}"] { display: none; }
</style>
<script>
function update${args.paramToHide}() {
var monitorNameField = document.querySelector('input[name="name"][value="${args.monitorParam}"]');
var field = document.querySelector('input[name="name"][value="${args.paramToHide}"]');

if (monitorNameField && field) {
var tbody = field.closest('tbody');

// Get the value field (works for text inputs, dropdowns, and checkboxes)
var monitorValueField = monitorNameField.closest('div[name="parameter"]').querySelector('input[name="value"], select[name="value"], input[type="checkbox"]');

if (tbody && monitorValueField) {
var monitorValue = "";

// Handle checkboxes separately
if (monitorValueField.type === "checkbox") {
monitorValue = monitorValueField.checked ? "yes" : "no"; // Convert checkbox state to yes/no
} else {
monitorValue = monitorValueField.value.trim().toLowerCase();
}

console.log("${args.monitorParam} detected value:", monitorValue);

if (monitorValue === "${args.hideIfThisValue}".toLowerCase()) {
tbody.style.display = 'none';
console.log("${args.paramToHide} is hidden because ${args.monitorParam} is '${args.hideIfThisValue}'.");
} else {
tbody.style.display = '';
console.log("${args.paramToHide} is visible.");
}
}
} else {
console.log("${args.monitorParam} or ${args.paramToHide} parameter not found.");
}
}

// Run immediately in case the element is already present
update${args.paramToHide}();

// Observe for dynamic changes (Jenkins UI updates)
var observer = new MutationObserver(function(mutations, obs) {
update${args.paramToHide}();
});

observer.observe(document.body, { childList: true, subtree: true });

// Listen for changes to the monitor parameter input, dropdown, or checkbox
document.addEventListener('change', function(event) {
if (event.target && (event.target.name === "value" || event.target.tagName === "SELECT" || event.target.type === "checkbox")) {
update${args.paramToHide}();
}
});
</script>
"""
/$.stripIndent().trim()

return activeChoices.hiddenScriptParam(
name: "${args.paramToHide.toUpperCase()}_HIDER",
script: hiderScript,
referencedParameters: "${args.monitorParam},${args.paramToHide}",
choiceType: 'ET_FORMATTED_HIDDEN_HTML',
)
}

If you DO want the one that hides only the value, it’s set like this: (I have not bothered to wrap it like my other params, since I don’t use this form)

[$class: 'DynamicReferenceParameter',
choiceType: 'ET_FORMATTED_HTML',
referencedParameters: 'MY_REFERENCED_VAR',
omitValueField: true,
name: 'MY_CONDITIONAL_VAR',
script: [
$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: false,
script: ""
],
script: [
classpath: [],
sandbox: false,
script: '''\
if (MY_REFERENCED_VAR?.contains('value to check by')) {
// put whatever groovy you want. It needs to define a list:
List myList = []

// this is the part that returns the dropdown list
input_string = "<select name='value'>"
myList.each{
input_string = input_string + "<option >${it}</option>"
}
input_string += "</select>"
return input_string
} else {
// Hide the input list by setting display none via HTML, and setting an ID we can target
return """
<style>
#dynamic-my-conditional-var { display: none; }
</style>
<div id="dynamic-my-conditional-var"></div>
"""
}
'''.stripIndent()
]
]
]

--

--

Kobi Rosenstein
Kobi Rosenstein

Written by Kobi Rosenstein

Devops engineeer. This blog chronicles my “gotcha” moments — Each post contains an answer I would have like to have found when trawling google.

No responses yet