- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 06-10-2021 08:20 AM
This can be achieved following these simple steps:
1- Convert the textarea of the journal field into a Tinymc rich editor, by calling the same function ServiceNow uses for this purpose.
You will need an onLoad Client Script on the table you have your journal field.
To convert the textarea just execute the following function
setupTinymceField(elementId, config);
Where elementId, in the Incident form, can be one of these: "activity-stream-textarea", "activity-stream-work_notes-textarea", "activity-stream-comments-textarea"
And the standard config from ServiceNow for tinymc editors is:
{
toolbar1: "bold,italic,underline,undo,redo,|,fontselect,fontsizeselect,table,|,forecolor,backcolor,link,unlink,|,image,media,code,|,alignleft,aligncenter,alignright,|,bullist,numlist,fullscreen",
toolbar2: "",
font_formats: "Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Journal=journal;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;",
remove_script_host: true,
language: "en",
relative_urls: true,
convert_urls: false,
remove_trailing_brs: true,
enable_media_sites: "youtube.com,player.vimeo.com,vimeo.com",
extended_valid_elements: ",sn-mention[class|table|sysid]",
custom_elements: "~sn-mention",
attachmentCanVie: true,
attachmentCanPopup: true,
plugins: "advlist anchor autolink charmap code colorpicker directionality emoticons fullscreen hr insertdatetime lists importcss nonbreaking noneditable pagebreak print searchreplace tabfocus table template textcolor textpattern visualblocks visualchars powerpaste snLink listitem_fix align_listitems a11y_fixes readonlynoborder data_uri_sanitize enable_iframe_media",
powerpaste_word_import: "prompt",
powerpaste_html_import: "clean",
automatic_uploads: false,
allow_script_urls: false
}
But of course, you can change it as you wish or read it from the system directly instead of hardcode it here in the Client Script.
2- Move outside of the control the horizontal bar that is used as decoration to help users easily identify the journal field, i.e. the yellow bar that appears in the work notes.
If we don't do anything the bar will appear on top of the control, which is not a big deal, but better if we move it a bit to the left. We can do that in different ways. Personally, I have chosen to add the following lines to the same Client Script, right after the calls to the setupTinymceField function.
var journalDecorators = document.getElementsByClassName("sn-stream-input-decorator");
Array.from(journalDecorators).forEach(function (el) {
el.style.left = "-10px";
});
3- Add an event to the post button to clean the content of the editor once the message is posted.
If we want the control to behave as before, we will need to tell the Post button to clean the content of our Tinymc editor, as it already does with normal journal inputs. For that, in the same Client Script, we need to add an event listener to execute the following line, when we hit the button:
tinymce.get(elementId).setContent("");
This is how I've done it.
window.onload = function () {
document.getElementsByClassName("btn btn-default pull-right activity-submit")[0].addEventListener("click", function () {
Array.from(journalFieldsIDs).forEach(function (el){
tinymce.get(el).setContent("");
})
});
}
Please, notice that we can have several journal fields on our form. This way we are cleaning all of them when pressing the Post button.
This is the last thing we need to do in our Client Script.
4- Use an extra journal field to wrap the content of the original field between [code] tags, so that ServiceNow can render the HTML code instead of print it in the Activity stream.
Go to the dictionary definition of your journal field and just press Insert and stay to create a similar one.
Now create a Business Rule that gets executed before update and insert when the original journal field changes. Here an example:
Then you just add a similar line like this in the script field:
current.u_work_notes ="[code]"+current.work_notes+"[/code]";
Here we are copying the content of the Tinymc editor, wrapped by [code] tags, to the journal field we have just created.
5- Deselect (do not remove) the default journal field from the Filter Activity and add+select your new journal field instead
For that, use the funnel button at the right of the Activity stream. Deselect the journal field and then at the bottom of the list click on "Configure available fields" to add to this list the journal field you have created before. Select it and we are done!
Unfortunately, I wasn't able to make it work yet without this extra field, but there may be a trick for this too. Please let me know if you find it!
- 9,375 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Has anyone implemented this? Eager to know.

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi
So I found through DOM tree that my input has id #activity-stream-comments-textarea.
I created onLoad script how you mentioned, but in console I can see the error that:
"ReferenceError: setupTinymceField is not defined
at onLoad_d4b68c58879674503f597b9acebb359b"
Should this function be called somehow specifically?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
You are totally right Igor, a colleague of mine found out that the Tinymce library wasn't loaded unless the form already had an HTML field.
The solution to this is pretty simple though, you just need to add this at the beginning of your client script:
if ($j.isFunction(this.setupTinymceField)) {
// All is good, so you can directly call your function that transforms your journal field to TinyMCE
...
} else {
var scriptFiles = [
'/scripts/tinymce_default/tinymce.full.js'
];
ScriptLoader.getScripts(scriptFiles, function() {
// Now that we have loaded the missing script, you can call your function that transforms your journal field to TinyMCE
...
});
}
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
You are totally right Igor, a colleague of mine found out that the Tinymce library wasn't loaded unless the form already had an HTML field.
The solution to this is pretty simple though, you just need to add this at the beginning of your client script:
if ($j.isFunction(this.setupTinymceField)) {
// All is good, so you can directly call your function that transforms your journal field to TinyMCE
...
} else {
var scriptFiles = [
'/scripts/tinymce_default/tinymce.full.js'
];
ScriptLoader.getScripts(scriptFiles, function() {
// Now that we have loaded the missing script, you can call your function that transforms your journal field to TinyMCE
...
});
}

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi
Not sure what's going on there, I even added HTML field to the form, and set Order of my onLoad script to 10k, but this didn't help).
However, your comment gave me another idea - try it with setTimeout, and this approach works. Another thing that I don't like timeouts, so if you have something else to try - please let me know.
In general, even with setTimeout it looks good, I like you work, interesting approach and looks pretty and flexible.
P.S.: Wondering will I have to fix all my notifications now to cut off [code] [/code] ?
This is my script now:
function onLoad() {
setTimeout(function(){
var config = {
toolbar1: "bold,italic,underline,undo,redo,|,fontselect,fontsizeselect,table,|,forecolor,backcolor,link,unlink,|,image,media,code,|,alignleft,aligncenter,alignright,|,bullist,numlist,fullscreen",
toolbar2: "",
font_formats: "Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Journal=journal;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;",
remove_script_host: true,
language: "en",
relative_urls: true,
convert_urls: false,
remove_trailing_brs: true,
enable_media_sites: "youtube.com,player.vimeo.com,vimeo.com",
extended_valid_elements: ",sn-mention[class|table|sysid]",
custom_elements: "~sn-mention",
attachmentCanVie: true,
attachmentCanPopup: true,
plugins: "advlist anchor autolink charmap code colorpicker directionality emoticons fullscreen hr insertdatetime lists importcss nonbreaking noneditable pagebreak print searchreplace tabfocus table template textcolor textpattern visualblocks visualchars powerpaste snLink listitem_fix align_listitems a11y_fixes readonlynoborder data_uri_sanitize enable_iframe_media",
powerpaste_word_import: "prompt",
powerpaste_html_import: "clean",
automatic_uploads: false,
allow_script_urls: false
};
var elementId = 'activity-stream-comments-textarea';
if ($j.isFunction(this.setupTinymceField)) {
setupTinymceField(elementId, config);
} else {
var scriptFiles = [
'/scripts/tinymce_default/tinymce.full.js'
];
ScriptLoader.getScripts(scriptFiles, function() {
setupTinymceField(elementId, config);
});
}
window.onload = function () {
document.getElementsByClassName("btn btn-default pull-right activity-submit")[0].addEventListener("click", function () {
tinymce.activeEditor.setContent("");
});
};
},1000);
}
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi Igor, this is how I would recommend building this script.
function onLoad() {
if ($j.isFunction(this.setupTinymceField)) {
// All is good, so you can directly call your function that transforms your journal field to TinyMCE
transformJournalToTinyMCE();
} else {
var scriptFiles = [
'/scripts/tinymce_default/tinymce.full.js'
];
ScriptLoader.getScripts(scriptFiles, function() {
// Now that we have loaded the missing script, you can call your function that transforms your journal field to TinyMCE
transformJournalToTinyMCE();
});
}
function transformJournalToTinyMCE() {
// 1. Initiate variables and config
// 2. Call setupTinymceField function
// 3. Define window.onload function
}
}
Just in case, be sure that your client script is not getting cached and that the browser is loading your latest modified version.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Thank you for sharing your solution! Very interesting!
Wondering if you learned anything about how the work notes fared in notifications after you made this change? Did you need to make any changes there?

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
I had to replace everywhere ${comments} to ${mail_script:comments}, to get them rendered properly. This was my script, I will share it, but I've seen couple of bugs in some emails during couple of days when I used this in prod, then I reverted back fields to original comments because I faced with issue on service portal input form. When I removed from form comment activity my comments input has gone also, so my customers (I used it for CSM cases) were not able to put comments, or if I added field to layout back - they were able to see both entries (with tags and duplicated without). So possible solution for my bug is to modify the original widget, maybe I will give it a chance later someday...
var formattedComments = formatComments(current.comments.getJournalEntry(-1));
template.print(formattedComments);
function formatComments (allComments, type){
var styler = type =='work_note'?"background-color:LightGoldenRodYellow;": '' ;
var sup = type =='work_note'?'Work notes':'Additional comments';
var formattedComments = allComments.replaceAll('[code]','');
formattedComments = formattedComments.replaceAll('[/code]','');
var commentArray = formattedComments.split('\n\n');
var text = '<div>';
commentArray.forEach(function(comment){
if(comment){
var commentValue = comment.split('\n')[1];
var commentTimeAndName = comment.split('(')[0];
text+='<div><span></span><hr></div>';
text+='<div style='+styler+'><span class="tdwrap"><strong>'+commentTimeAndName+'</strong></span><span style="float:right;"><sup> '+sup+'</sup></span></div>';
text+='<div style='+styler+'><span><span style="word-wrap:break-word;display:block;">'+commentValue+'</span></span></div>';
}
});
text+='</div>';
return text;
}
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Indeed, notifications are to be taken into consideration when planning to use HTML in the comments, and together with that, we should consider the mobile web interface, the mobile apps, and the workspaces as well. Unfortunately, there isn't much we can do in these cases, so I would suggest to carefully analyze all that before going forward with this customization.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Did you set this as another client script? Or part of your tinyMCE enabling one?

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
What I lined above it's email script, which can be used in notifications to get proper comments
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Has somebody managed to make this work on Tokyo?
I have the following code as a client script:
function onLoad() {
var scriptFiles = [
'/scripts/tinymce_default/tinymce.full.js'
];
jslog("before");
ScriptLoader.getScripts(scriptFiles, function() {
transformJournalToTinyMCE();
});
function transformJournalToTinyMCE() {
var config = {
toolbar1: "bold,italic,underline,undo,redo,|,fontselect,fontsizeselect,table,|,forecolor,backcolor,link,unlink,|,image,media,code,|,alignleft,aligncenter,alignright,|,bullist,numlist,fullscreen",
toolbar2: "",
font_formats: "Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Journal=journal;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;",
remove_script_host: true,
language: "en",
relative_urls: true,
convert_urls: false,
remove_trailing_brs: true,
enable_media_sites: "youtube.com,player.vimeo.com,vimeo.com",
extended_valid_elements: ",sn-mention[class|table|sysid]",
custom_elements: "~sn-mention",
attachmentCanVie: true,
attachmentCanPopup: true,
plugins: "advlist anchor autolink charmap code colorpicker directionality emoticons fullscreen hr insertdatetime lists importcss nonbreaking noneditable pagebreak print searchreplace tabfocus table template textcolor textpattern visualblocks visualchars powerpaste snLink listitem_fix align_listitems a11y_fixes readonlynoborder data_uri_sanitize enable_iframe_media",
powerpaste_word_import: "prompt",
powerpaste_html_import: "clean",
automatic_uploads: false,
allow_script_urls: false
};
var elementId = 'activity-stream-comments-textarea';
setupTinymceField(elementId, config);
var journalDecorators = document.getElementsByClassName("sn-stream-input-decorator");
Array.from(journalDecorators).forEach(function(el) {
el.style.left = "-10px";
});
}
jslog("after");
}
However, nothing happens to the additional comments field. I tried changing the "elemntId" to be one of the other 2 and the effect is the same.
The console gives no error. A few things:
1. I had to remove the $j, as the console was giving me error "$j is null"
2. I had to remove the "window.onload" part as well, because the console was erroring with "window is null"
Anyway, I don't see the above 2 points being responsible for how the field shou
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @svanto, because of the mentioned console errors, it seems your client script is flagged as isolated.
Just make sure the option Isolate script of your Client script is deactivated. Maybe you need to add it to your form or list layout if it's not visible by default.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hola - has anyone successfully tried this in Yokohama?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hii ,
I have tried the suggested method . But I had to have a HTML type field already present on the form . But I cannot see the toolbar even though it was configured in config
Can anyone pls help me with this