Attribute Customization JavaScript Calculated Value - Can I Return without Changing the Value?
I am developing an Attribute Customization JavaScript that will modify the Summary of the work item. However, the modification should only happen some of the time. Most of the time, I want no change to be made. The way I was trying to handle this is by first reading the Summary and then returning it again like so:
var summary = workItem.getValue(WorkItemAttributes.SUMMARY);
return summary;
The problem is that the Summary is an HTML field, not a regular string. If there are any characters in the summary that would be HTML-encoded, these characters come out in the encoded form. So if the summary had the value:
"Five > three"
then the value of my summary variable will be:
"Five > three"
I have to detect when this happens and fix it before I can return the summary value. Currently I have a line of code that does that with the "replace" function uses regular expressions to find all these sorts of characters. That is annoying, but it is doable.
A more serious problem is if the Summary actually uses legitimate formatting like bold, italics, or a hyperlink. If the summary has the value:
Urgent: Do something!
Then the string value I get back is:
<b>Urgent:</b> Do something!
If I do my regex fix on that string and return that value, the summary will look like the second line and the formatting will be lost.
From what I've read around here on the forums, it sounds like putting HTML formatting back into the HTML field is just not supported. I can probably live with that if I could just leave the Summary value unchanged when I don't need to change it (since that's the majority/typical situation).
Is there a way to abort a calculated value JavaScript so that no value is returned? I thought about wrapping the dojo.declare statement in a try/catch block and then using a throw statement inside the function rather than returning a value, but that doesn't seem to work (unless I'm just implementing it wrong). I also note that the dojo.declare constructor seems to always have "null" as its first parameter. I was wondering if that was useful in some fashion.
Does anyone know of a way to do this?
Accepted answer
So I tried to explain this in my write-up, but I guess I wasn't clear? If the Summary contains formatting, it is not possible to return the value unchanged. For example, bold formatting comes out as <b>bold text</b> and if I return that same text back to the Summary, this is interpreted as a CHANGED value. It doesn't apply formatting back to the Summary, it just displays those HTML tags as plain text.
Not only does this result in erroneous HTML tags being inserted into the summary where formatting existed previously, this constitutes a change to the attribute and some projects in our environment have configured the Summary so that it cannot be changed beyond a certain state. These projects actually started getting permission denied errors because the automation was trying to modify the Summary and they had no intention or desire to do that.
The only way to not change the value is for my function to not return a value at all.
I worked on this a little more yesterday and it turns out that my JavaScript was returning the Summary in multiple places in the code, and I missed one of them. If I replace all instances of return statements with "throw" statements, this actually works. So it appears "throw" is a viable technique for leaving the value unchanged.
3 other answers
I've identified a problem with the technique I've outlined in my post above. Although throwing an exception does solve the problem, it also causes errors to be logged. The error can be safely ignored, but the log gets spammed with it.
Is there a safe exception to throw from JavaScript that will not cause a log entry? The error message in the log is:
ERROR com.ibm.team.workitem.common - Error invoking value provider 'value provider's name'
com.ibm.team.repository.common.TeamRespositoryException: Unexpected exception type
An easy solution is to add the following function to your script:
Comments
Jonas Studer
Aug 12 '16, 3:02 a.m.Hello Mister Decker,
As far as I understand. You don't want the encoding in your string.
1: Ways to detect the encoding:
-
document.inputEncoding
,-
document.characterSet
(non IE)-
document.charset
-document.defaultCharset
2: If you know which encoding the summary is using, try these.
-unescape();
-decodeURI(enc);
Jonas Studer
Aug 12 '16, 3:07 a.m."I also note that the dojo.declare constructor seems to always have "null" as its first parameter. I was wondering if that was useful in some fashion."
If you use dojo declare its like creating a class in Java.
Everything inside the declaration is accessible through the given namespace.
The NULL value at the beginning signalizes the javascript-class it has no inheritance.
https://dojotoolkit.org/reference-guide/1.10/dojo/_base/declare.html#dojo-base-declare
Jonas Studer
Aug 12 '16, 3:12 a.m.I dont completely get the logic you are using.
1: Something triggers the "calculate value" action.
2: You DO something with the given data
2.1: DO in this case means "READ"
2.2: You check if the given data meets your expectations
3: The data is evaluated
3.Match -> You gonna change some fields and save it.
3.NoMatch -> You leave the data as they arrived.
Why do you change data if there is "NoMatch"?
Just leave it they it is, so you dont have to the problem.
But, if you NEED to change some data, it would be interesting how you access the data. Via OSLC or via WorkitemProxy?
Ralph Schoon
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER Aug 12 '16, 4:05 a.m.Nate, please let us know what you see. My best guess is that when returning the string without escapes the string is converted internally using XMLString.createFromPlainText() and the values are escaped again.