For anyone who is familiar with the Jelly tags for Jenkins plugins, you know that there is a specific getter/setter format used for the @checked value for the tag.
My plugin parses an XML with interface values, and I need to dynamically create checkboxes for each of the values in the XML on the project page (via floatingBox.jelly). I have the XML file being input from the config page, the plugin action parsing the xml and passing a list of strings to the jelly, wherein it currently generates checkboxes based on the list.
My dilemma is structuring my java/jelly relationship in a way that allows the plugin to communicate the @checked value to 1) pass the checked value to some unique dynamically created java boolean variable 2) hold the value in said variable and return.
I'm currently using a Hashtable to store my key,value pairs but am not able to set values and return values using a single method call successfully.
My floatingBox.jelly:
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt" xmlns:local="local">
<div class="test-trend-caption" style="color:red;text-align:center" >Select Build Interfaces</div>
<div>
<j:forEach var="i" items="${it.getActions().get(0).getInterfaces()}">
<div style="text-align:left">
<f:checkbox title="${i}" checked="${it.getActions().get(0).getCheckedInterfaces(i)}"/>
</div>
<br/>
</j:forEach>
</div>
My Plugin Action code:
public boolean getCheckedInterfaces(String name) {
for (Map.Entry entry : checkedInterfaces.entrySet()) {
if (entry.getValue().equals(name)) {
return (Boolean)entry.getKey();
}
}
return false;
}
public void setCheckedInterfaces(String name) {
checkedInterfaces.put(name, true);
}
public void parseInterfaces() throws IOException, InstantiationException, IllegalAccessException {
if (getInterfacesPath()!=null || getInterfacesPath()!="") {
GroovyClassLoader loader = new GroovyClassLoader();
Class groovyClass = loader.parseClass(new File("C:\\...\\src\\main\\groovy\\xmlTest.groovy"));
GroovyObject groovyObj = (GroovyObject)groovyClass.newInstance();
final Object args = (Object)getInterfacesPath();
ArrayList<String> temp = (ArrayList<String>)groovyObj.invokeMethod("parseXML", args);
if (interfaces.isEmpty())
interfaces.addAll(temp);
else {
interfaces.clear();
interfaces.addAll(temp);
}
}
Is there another paradigm that I could try to initialize and manage these values so they operate like an explicitly declared boolean for the checkbox-java relationship?
I did eventually solve this issue. I created a JavaScript function that read the table checkbox values and assigned the output to a hidden input, which was made available to my Java code via @QueryParameter. See below.
Jelly/HTML form to call the JS function and post Java:
<form style="float:right" method="post" action="forcePromotion?name=${p.name}" onsubmit="saveChecksForce()">
<f:submit value="${%Force promotion}" />
<input id="ServerList" name="serverList" type="hidden" />
</form>
And the JS function:
function saveChecksForce() {
var c = window.document.getElementById("ServerChecklist").rows;
var checkedservers = "";
for (var i = 0; i & lt; c.length; i++) {
if (c[i].cells[1] != null) {
if (c[i].cells[1].children[0] != null) {
if (c[i].cells[1].children[0].checked == true) {
checkedservers = checkedservers + c[i].cells[0].innerHTML + ",";
}
}
}
}
window.document.getElementById('ServerList').value = checkedservers;
}
Where "ServerChecklist" is my table Id with the checkboxes in a single column. Then the form executes the action, and calls the Java code:
public HttpResponse doForcePromotion(@QueryParameter("name") String name, @QueryParameter("serverList") String serverList) throws IOException, InterruptedException {
setEnvVars(serverList);
this.getProject().checkPermission(Promotion.PROMOTE);
...
}