Chamila is playing with DekiScript, and trying to use an example of the TicketForm table (for our issue tracking) that doesn’t show issues that have the status “Closed”. Currently, the page is giving the following error:
/content/body/div[3]/pre, line 299, column 20: invalid Primary (click for details)
This means, of course, that there’s something wrong with the DekiScript. The “invalid Primary” means it was looking for a number where there’s some other data type. Could be a syntax error, or it could be that a variable or literal value of the wrong type is being used where it shouldn’t. Chamila has helpfully already pointed out to me the line that he was working with:
if(param is not ["Closed"]) { "xxxxxxx" } else { "YYYYY" }
There are a couple of syntactical errors here, so these should be tackled first. One problem with this statement is with the logical test in the “if” clause:
param is not ["Closed"]
If you look in the list of DekiScript Operators, you will see that there is no “is not” operator. There actually is an “is” operator, but it tests for a match on the data type of two values, rather than for equality of their values. Furthermore, there is no “not” operator. Instead, you must indicate negation using either the “!” operator in combination with the comparator “==”, or the combined operation, “!=”:
param != ["Closed"]
Next, we have to look at what is being compared here. On the left is the param variable (more on that below). On the right is a literal, and a valid one at that. But what kind? The brackets ([ ]) indicate that the value being compared is a literal List. Contained within that list is a single value, a str (string) with the value “Closed”. My guess is that the test is trying to find parameter values that match “Closed” (the status we are looking to exclude), so in this case, the list is incorrect:
if(param != "Closed") { "xxxxxxx" } else { "YYYYY" }
Now, when I save the page, the syntax errors are resolved. Instead, we see the following error:
/content/body/div[3]/pre, reference to undefined name ‘param’: line 299, column 20 (click for details)
The problem now is just what it says: the param variable that we’re comparing hasn’t yet been defined for our scope. To see why, you have to look at the code around it:
<tr id=(p.properties.id.text) class=(class)>
if(param != "Closed") { "xxxxxxx" } else { "YYYYY" }
foreach(var param in params){
if(param.value.show && param.value.show == 'ticket') continue; // if not supposed to show in table, skip.
Notice that the param variable isn’t defined until the foreach loop in the following line. This is what’s causing the new error. When I switch the lines, the error disappears:
<tr id=(p.properties.id.text) class=(class)>
foreach(var param in params){
if(param != "Closed") { "xxxxxxx" } else { "YYYYY" }
if(param.value.show && param.value.show == 'ticket') continue; // if not supposed to show in table, skip.
Now we see the table, as follows:

The table only shows X's (there are no matches)
What’s happening? There are only x’s across the top (there were some in the table cells, too, but I removed an unrelated line of code for the purposes of this tutorial) (note also that they appear at the top of the table because we are writing the text out between a <tr> tag and a <td> tag, rather than within the <td>). As you can see from the if statement, this means that in no case is param “Closed”. Even when we have a Status column with a value of “Closed”, it’s not matching. This is because the if statement is trying to compare the param value (which is some sort of object) to the str value “Closed”. The first hint on how we might want to do things is in the line following the if statement:
if(param.value.show && param.value.show == 'ticket')
The param variable has a “value” attribute, which in turn has a “show” attribute, which can have a value of “ticket”. The whole structure and meaning of the param variables is specific to the TicketForm templates, but the point is that this is an object, and not just a simple string. Rather than try to guess where the value is that we’re testing, I’ll skip to the important part. The param here marks a type of parameter (i.e. a column in the table: Type, Urgency, Status, and so on). This is generic, and doesn’t contain the value we need, just the name of the parameter that contains the value. Looking at the next line down, we see:
var property = Map.values(map.select(p.properties, "$.key=='"..String.replace(String.toLower(param.key)," ","_").."'"))[0];
The code is grabbing a page property value with a name equal to the param.key value, and assigning it to the property variable. Further down, we see:
if(param.key =='title'){
<a href=(p.uri) style=(param.value.style.table)>property.text </a>
}else{
<span style=(param.value.style.table)>property.text</span>
}
So, it looks like we could get the value from property.text. I move out if statement to after the property declaration, and replace param with property.text:
foreach(var param in params){
if(param.value.show && param.value.show == 'ticket') continue; // if not supposed to show in table, skip.
var property = Map.values(map.select(p.properties, "$.key=='"..String.replace(String.toLower(param.key)," ","_").."'"))[0];
<td>
if(property.text != "Closed") { "xxxxxxx" } else { "YYYYY" }
I hit save on the editor, and get the following:

The Closed Status value has Y's
You can see that all the cell values now have a set of x’s before them, all except the “Status” cell with the value “Closed” (note that I also moved our if statement to within the <td> declaration so that we could see the result next to the values being tested). So, now we’re most of the way there! I leave it up to you guys to do the rest:
- Only test against the parameter value if the parameter type is “Status”
- If the row has a “Closed” status, skip the row entirely (rather than printing out test values)
- Bonus credit: print out a count of the number of issues, but don’t count tickets with a “Closed” status